Society of Robots - Robot Forum
Software => Software => Topic started by: dellagd on March 14, 2010, 10:19:14 AM
-
http://www.radioshack.com/product/index.jsp?productId=2909788#tabsetBasic (http://www.radioshack.com/product/index.jsp?productId=2909788#tabsetBasic)
its a accelerometer from radioshack and I dont know how to write custom code for sensors
could someone explain to me how to code for this sensor with the Axon? (also which pins go where on the axon)
-
Do you download and read the User's guide?
The outputs are explained and there is even sample code for the BASIC stamp. Use this code to learn what you need to do and then rewrite it for the Axon.
The Accel's outputs are digital so they can be connected to any digital input on the Axon. The acceleration is the ratio of the high to period of the output pulse as shown in figure 1 of user's guide. The code needs to time the the pulse period and the high pulse length then calculate the G if needed.
-
um, could you show me how to do what you just said? That was kinda my question
-
while( pin is high)
{
//increment counter
}
//do math as shown in users guide
You will need to know how many cycles are 10ms, I forgot how to calculate it but it is somewhere in the source code of the Axon and the $50 robot.
-
I'm sorry but I still dont really get what you mean. I dont see anything about "cycles" in the axon source code
-
It's probably in the $50 source code (you should really do it :P ), where it calculates how many processor commands take up a certain amount of time.
-
well since the ATmega640 is configured to go faster than the ATmega8 then why would it help to look in the $50 robot code?
PS I still dont get your little code bit up there anyway.
-
I'm sorry but I still dont really get what you mean. I dont see anything about "cycles" in the axon source code
A 'cycle' is the length of time one instruction (assembler) takes to execute, also called an instruction cycle.
This time is dependent on the clock frequency set by the processor's XTAL (crystal).
Now look again at Figure 2 in the accelerometer's user's guide and the equation under the figure.
A(g) = ((T1 / T2) - 0.5) / 12.5%
The period time and the high pulse time are a ratio in the equation so the absolute times (in seconds) are not required (the units of time cancel). Just count the length of each and divide the time (count) of the high pulse by the time (count) of the period.
-
I dont want to seem noobish, but could someone give me some actual code? I think it wold seem much clearer if I acually saw the code since you guys seem to know how to do this.
-
here is kind of pseudocode:
int t1 = 0;
int t2 = 0;
while(bit_is_set(PIND,4)) //while pin is high....
t1++; //count how long it is high
while(!(bit_is_set(PIND,4))) //while pin is low...
t2++; //count how long it is low
int acceleration = ((t1/t2) - .5)/.125; //find acceleration
-
ok thx a bunch razor!
-
ok new question what is the difference from g-force, x tilt, and x input??
DEBUG CRSRXY, 0, 3
DEBUG "X Input... ",
DEC (xRaw / 1000), ".", DEC3 xRaw, " ms",
CLREOL, CR,
"G Force... ", (xmG.BIT15 * 13 + " "),
DEC (ABS xmG / 1000), ".", DEC3 (ABS xmG), " g",
CLREOL, CR,
"X Tilt.... ", (xTilt.BIT15 * 13 + " "),
DEC ABS xTilt, DegSym, CLREOL
DEBUG CRSRXY, 0, 7
-
here is kind of pseudocode:
int t1 = 0;
int t2 = 0;
while(bit_is_set(PIND,4)) //while pin is high....
t1++; //count how long it is high
while(!(bit_is_set(PIND,4))) //while pin is low...
t2++; //count how long it is low
int acceleration = ((t1/t2) - .5)/.125; //find acceleration
t2 is counting how long the input is low but the equation in the user's guide is the length of the high pulse divided by the total length of the high plus the low (length of the period). So change the last line of code to:
int acceleration = ((t1/(t1+t2)) - .5)/.125; //find acceleration
Now there is a second problem with this code. acceleration is an int and the math to calculate the acceleration requires floating point math. t1/(t1+t2) is always less than 1 (it'll be a faction). Also 0.5 & 0.125 are less than 1. One could using floating point values but this takes up a lot more code space and execution time.
The easy way out of this is to multiple t1 by 100 and use the equation:
t1 = t1 *100;
int acceleration = ((t1/t2) - 50)*8; // find acceleration * 100
The acceleration value is now greater than zero and is also 100 times the true 'G' value but is easy to deal with.
I see you are examining the BASIC code in the User's guide, good.
The code you posted is the output to a UART to display the data in a terminal program on a PC.
'x input' is x raw, the actual measured time of the high pulse. See the "Read_G_Force:" subroutine.
'g force' is the actual g calculated from the pulse width. See the "Read_G_Force:" subroutine.
'x tilt' is the calculated tilt of the x-axis. See the "Read_Tilt:" subroutine.
Do notice the equation used in the "Read_G_Force:" subroutine. xRaw is 1000 times larger so that 500 is subtracted from it. The result is 1/1000 g per 1 value (exp: if xmG calc's to be 1000 this is 1g, if xmG calc's be be 50 then g = 0.05).
-
ok, I think I get this
xmG = ((xRaw / 10) - 500) * 8
(quote from the code)
but what about this wierd line
xRaw = xRaw */ Scale
(also from the code)
what the heck does "*/" mean?
-
From the PBASIC manual:
One way to deal with fractional numbers is to use the ‘ */ ’ operator. It has the effect of
multiplying a value by a whole number and a fraction. This operator places the whole
number portion in the upper byte, multiplies the fractional part by 256 and places the
result in the lower byte.
For example, if multiplying value with 1.8, using the ‘ */ ’ would mean 0.8 * 256 = 204.8 =
205 and therefore:
Upper byte : 01
Lower byte : CD
-
so you use it if multiplying with floats basically?
-
so you use it if multiplying with floats basically?
Yep, it does a very basic fixed point math (similar to a float).
Note that this operator is only available in PBASIC.
-
here is kind of pseudocode:
int t1 = 0;
int t2 = 0;
while(bit_is_set(PIND,4)) //while pin is high....
t1++; //count how long it is high
while(!(bit_is_set(PIND,4))) //while pin is low...
t2++; //count how long it is low
int acceleration = ((t1/t2) - .5)/.125; //find acceleration
in the part:
while(bit_is_set(PIND,4))
what is "bit_is_set"? I know you said it was psudocode, but how would I check to see if the pin is HIGH on the axon II?
-
bit is set is the actual code used to check if the pin is high (there are a variety of ways to do this, i just prefer bit is set)
in my example, i am checking D4. If you want C3, do (PINC,3). etc etc
-
well when I use that code I get an error.
what header file is the "bit_is_set" function located in?
here are the errors:
../experimental2.c: In function 'read_accelerometer':
../experimental2.c:20: error: 'PIND' undeclared (first use in this function)
../experimental2.c:20: error: (Each undeclared identifier is reported only once
../experimental2.c:20: error: for each function it appears in.)
make: *** [experimental2.o] Error 1
Build failed with 3 errors and 0 warnings...
-
Assuming you have AVR GCC installed, include this:
<avr/sfr_defs.h>
Or if that does not work, you can just define it yourself (but may have redefine issues later on if it starts working)
#define bit_is_set ( sfr,
bit ) (_SFR_BYTE(sfr) & _BV(bit))
-
I think that I know the problem
could this be it?
There is nothing listed here!
-
Looks like you didn't set a device (mega168, mega640, etc etc)
-
well, these are my settings...
-
ok, I got it to appear, same problem... Is there another method for checking if the pin is HIGH?
do I have to declare what PIND is or something?
-
well, heres a screenshot of the configuration options, the I\O view, and the bit of code where bit_is_set is called. Anything you see wrong?
-
Check the makefile and see if the mega640 is selected.
-
this is towards the top of the makefile :
## General Flags
PROJECT = experimental2
MCU = atmega640
TARGET = experimental2.elf
CC = avr-gcc.exe
-
ok I've switched to WebbotLib method, but all it does is give me haywire messages
code:
void read_accelerometer () {
while(pin_is_high(F5)) //while pin is high....
t1++; //count how long it is high
while(pin_is_low(F5) ) //while pin is low...
t2++; //count how long it is low
acceleration = ((t1/(t1+t2)) - 500)* 8;
} //find acceleration
yes, I did initallize F5 as an input
is it possible that my accelerometer is faulty?
-
Is acceleration an unsigned long?
-
should it be? because its not
-
Change t1, t2, and acceleration to be unsigned longs.
-
nope, same problem. I'll just return it and get an accelerometer that is analog, like all accelerometers should be. Anyways this sensor was designed and built for the Parralax Boe-Bot and made by the the people who made the Boe-Bot.