Dinsmore R1655 - Calling Dr. Tracey Allen
Jonathan
Posts: 1,023
Hi All,
It's like in the old TV show Bewitched. Whenever the going got too tough or crazy, Samantha would call in Dr. Bombay. Of course, here in Stamp land, we call Dr. Tracey Allen!
Once again and as always, math is kicking my butt. I have been playing around with a Dinsmore R1655 compass sensor. I am using an LTC1298 and a BS2p24. I found some code on the web for PICBASIC, and converted it over to good 'ol PBASIC. While I have it fundamentally working, there is a math issue too tricky for me to solve. Meaning that adding more than 2+2 is required :-( . Here is the code:
'{$STAMP BS2p}
'{$PBASIC 2.5}
' ** Declared Pins Used for LTC1298**
CLK PIN 9 ' Clock
DIO_n PIN 10 ' Data
CS PIN 8 ' Chip Select
Result VAR Word ' Reading from the A/D
B_Curve VAR Word ' The B curve reading from the A/D
A_Curve VAR Word ' The A curve reading from the A/D
CompDisp VAR Word ' Our final value to display
RawCompass VAR Word ' Factored A/D results
Compass VAR Word ' Variable to reduce the calculations
CrossZero VAR Word ' We are Crossing 360 degrees
ZeroCross VAR Word ' We have Crossed 360 degrees
UpLimit VAR Word ' Upper crossover point
LowLimit VAR Word ' Lower crossover point
Scale VAR Word ' Spread times 10 divided by 4
config VAR Nib
section VAR Byte
whichChan VAR config.BIT2
UpLimit = 2440'2361 ' A starting value before auto calibration
LowLimit = 1690'1721 ' A starting value before auto calibration
Scale = 30 ' 35 ' A starting value before auto calibration
HIGH CS ' A/D Chip select inactive
' ***** MAIN PROGRAM *****
Mainloop:
PAUSE 1000
DEBUG CLS, "A: ", DEC a_curve, TAB, "B: ", DEC b_curve,TAB,"DIR =", DEC compDisp/10,".",DEC compdisp//10 , " Sec.: ", section
RawCompass = 0 ' Reset our values
Compass = 0 ' Reset our values
CompDisp = 0 ' Reset our values
GOSUB getB ' Get the B_Curve value
PAUSE 10
GOSUB getA ' Get the A_Curve Value
'IF A_Curve = B_Curve THEN GOSUB Calibrate
IF A_Curve >= UpLimit THEN GOTO SectionB 'Reading is in the second section
IF B_Curve >= UpLimit THEN GOTO SectionA 'Reading is in the first section
IF A_Curve <= LowLimit THEN GOTO SectionC 'Reading is in the third section
IF B_Curve <= LowLimit THEN GOTO SectionD 'Reading is in the fourth section
SectionA: ' 0-90 degree reading
· section = "A"
· RawCompass = (UpLimit - A_Curve) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = Compass ' The Compass display is the value of compass
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionB: ' 270-360 degreee reading
· section = "B"
· RawCompass = (B_Curve - LowLimit) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CrossZero = Compass + 2700
· IF CrossZero >= 3600 THEN SectionBA ' We have really crossed Zero Degrees
· CompDisp = Compass +2700
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionBA:
· section = "E"
· ZeroCross = CrossZero - 2700 '3600 was the original·number here
· CompDisp = zerocross
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionC: ' 90-180 degree reading
· section = "C"
· RawCompass = 0
· RawCompass = (UpLimit - B_Curve) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = Compass + 900
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionD: ' 180-270 degreee reading
· section = "D"
· RawCompass = (A_Curve - LowLimit) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = (Compass +1800)'-270
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
' ** Subroutine to get B_Curve value (channel 0)
getB:
whichChan = 1
GOSUB get_adc
B_Curve = result ' Our reading for the B lead
RETURN
' Subroutine to get A_Curve value (channel 1)
getA:
whichChan = 0
GOSUB get_adc
A_Curve = result ' Our reading for the A lead
RETURN
' ** Subroutine to read A/D converter
Get_adc:
config = config | %1011 ' Set all bits except whicChan.
LOW CS ' Activate the ADC.
SHIFTOUT DIO_n,CLK,LSBFIRST,[noparse][[/noparse]config\4] ' Send config bits.
SHIFTIN DIO_n,CLK,MSBPOST,[noparse][[/noparse]result\12] ' Get data bits.
HIGH CS ' Deactivate the ADC.
RETURN ' Return to program.
The problem is thus: The sensor·gives the same reading if in the same position, every time, very accurately. However, when crossing between some sections of the position calculating code (sections A,B,C,D, and E) the reading jumps by about 10 degrees. Other sections cross properly. The problem sections are crossing from B to E, and E to D.
More information and the original source code can be found here:
http://www.robsonco.com/R1655%20Programming.htm
Instead of using the default upper and lower crossing limits, I measured the actual readings and used the information from the above PDF's to calculate the scale variable. I have tried with the defaults and it acts the same. I hope someone can shed some light on this! I am hoping to add this sensor to the Hydrogen Fuel Cell Robot in time to use it this school year.
Thanks All!
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
It's like in the old TV show Bewitched. Whenever the going got too tough or crazy, Samantha would call in Dr. Bombay. Of course, here in Stamp land, we call Dr. Tracey Allen!
Once again and as always, math is kicking my butt. I have been playing around with a Dinsmore R1655 compass sensor. I am using an LTC1298 and a BS2p24. I found some code on the web for PICBASIC, and converted it over to good 'ol PBASIC. While I have it fundamentally working, there is a math issue too tricky for me to solve. Meaning that adding more than 2+2 is required :-( . Here is the code:
'{$STAMP BS2p}
'{$PBASIC 2.5}
' ** Declared Pins Used for LTC1298**
CLK PIN 9 ' Clock
DIO_n PIN 10 ' Data
CS PIN 8 ' Chip Select
Result VAR Word ' Reading from the A/D
B_Curve VAR Word ' The B curve reading from the A/D
A_Curve VAR Word ' The A curve reading from the A/D
CompDisp VAR Word ' Our final value to display
RawCompass VAR Word ' Factored A/D results
Compass VAR Word ' Variable to reduce the calculations
CrossZero VAR Word ' We are Crossing 360 degrees
ZeroCross VAR Word ' We have Crossed 360 degrees
UpLimit VAR Word ' Upper crossover point
LowLimit VAR Word ' Lower crossover point
Scale VAR Word ' Spread times 10 divided by 4
config VAR Nib
section VAR Byte
whichChan VAR config.BIT2
UpLimit = 2440'2361 ' A starting value before auto calibration
LowLimit = 1690'1721 ' A starting value before auto calibration
Scale = 30 ' 35 ' A starting value before auto calibration
HIGH CS ' A/D Chip select inactive
' ***** MAIN PROGRAM *****
Mainloop:
PAUSE 1000
DEBUG CLS, "A: ", DEC a_curve, TAB, "B: ", DEC b_curve,TAB,"DIR =", DEC compDisp/10,".",DEC compdisp//10 , " Sec.: ", section
RawCompass = 0 ' Reset our values
Compass = 0 ' Reset our values
CompDisp = 0 ' Reset our values
GOSUB getB ' Get the B_Curve value
PAUSE 10
GOSUB getA ' Get the A_Curve Value
'IF A_Curve = B_Curve THEN GOSUB Calibrate
IF A_Curve >= UpLimit THEN GOTO SectionB 'Reading is in the second section
IF B_Curve >= UpLimit THEN GOTO SectionA 'Reading is in the first section
IF A_Curve <= LowLimit THEN GOTO SectionC 'Reading is in the third section
IF B_Curve <= LowLimit THEN GOTO SectionD 'Reading is in the fourth section
SectionA: ' 0-90 degree reading
· section = "A"
· RawCompass = (UpLimit - A_Curve) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = Compass ' The Compass display is the value of compass
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionB: ' 270-360 degreee reading
· section = "B"
· RawCompass = (B_Curve - LowLimit) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CrossZero = Compass + 2700
· IF CrossZero >= 3600 THEN SectionBA ' We have really crossed Zero Degrees
· CompDisp = Compass +2700
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionBA:
· section = "E"
· ZeroCross = CrossZero - 2700 '3600 was the original·number here
· CompDisp = zerocross
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionC: ' 90-180 degree reading
· section = "C"
· RawCompass = 0
· RawCompass = (UpLimit - B_Curve) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = Compass + 900
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
SectionD: ' 180-270 degreee reading
· section = "D"
· RawCompass = (A_Curve - LowLimit) * Scale
· Compass = ((RawCompass/10) * 4) /10
· CompDisp = (Compass +1800)'-270
· PAUSE 100
GOTO Mainloop ' Do it indefinitely
' ** Subroutine to get B_Curve value (channel 0)
getB:
whichChan = 1
GOSUB get_adc
B_Curve = result ' Our reading for the B lead
RETURN
' Subroutine to get A_Curve value (channel 1)
getA:
whichChan = 0
GOSUB get_adc
A_Curve = result ' Our reading for the A lead
RETURN
' ** Subroutine to read A/D converter
Get_adc:
config = config | %1011 ' Set all bits except whicChan.
LOW CS ' Activate the ADC.
SHIFTOUT DIO_n,CLK,LSBFIRST,[noparse][[/noparse]config\4] ' Send config bits.
SHIFTIN DIO_n,CLK,MSBPOST,[noparse][[/noparse]result\12] ' Get data bits.
HIGH CS ' Deactivate the ADC.
RETURN ' Return to program.
The problem is thus: The sensor·gives the same reading if in the same position, every time, very accurately. However, when crossing between some sections of the position calculating code (sections A,B,C,D, and E) the reading jumps by about 10 degrees. Other sections cross properly. The problem sections are crossing from B to E, and E to D.
More information and the original source code can be found here:
http://www.robsonco.com/R1655%20Programming.htm
Instead of using the default upper and lower crossing limits, I measured the actual readings and used the information from the above PDF's to calculate the scale variable. I have tried with the defaults and it acts the same. I hope someone can shed some light on this! I am hoping to add this sensor to the Hydrogen Fuel Cell Robot in time to use it this school year.
Thanks All!
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
Comments
My reaction is, Yikes! That's really messy!
It might be simplified greatly using the Stamp's built-in ATN operator (ATN stands for arctangent, inverse tangent).
What the Dinsmore 1655 gives you is basically two signals (curves) A and B:
Asin = sine theta
and
Bcos = cosine theta
respectively, where theta is the angle you want.
Given those two values, the angle is
theta = arctangent (Asin/Bcos)
That is where the Stamp ATN operator come in.
First though, the raw readings Asin and Bcos from the compass have to be offset and scaled into the range -127 to +127 so that they can fit into the Stampese way of doing trigonometry. You have to find the maximum and minimum readings that occur as you rotate the compass. This could be automated, but let's say for starters that you just measure Amax, Amin, Bmax and Bmin, and enter them as constants in the program.
That's it. The resolution is not so good, only ~1 or 2 degrees. Dr. Bombay, Samantha, what do you think?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Thanks for the help! It's still not working correctly. As before, I get consistant readings. However, there are still "borders" where problems arise. For examples, the readings go from 127 to 230 and from 296 to 606.
On another note, the PBASIC toxenizer didn't like:
Bhalf·· CON Bmin + (Bspan/2)
So I changed it to:
Bhalf VAR Word
Bhalf = Bmin + (bspan/2)
Which the toxenizer was OK with.
As always, many, many thanks! This is a cool little compass sensor, and I'm excited to see what we can do once its working.
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
Bhalf·· CON Bspan/2 + Bmin
What values did you use for the Amin, Amax, Bmin and Bmax for your individual sensor? The other constants are calculated from those. Add more debugs to the program. The final value of asin and bcos should vary from 127 to -127 over a full circle.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
asin and bcos do indeed surpass 127. I measured the A/Bmax and A/Bmin:
amax: 2628
amin: 1547
bmax: 2587
bmin: 1523
Up until now, I had been using the crossing points of the readings, not the max and min readings. Reading the data sheets, I thought that was where one was supposed to start. In case it helps, the crossing points (where both adc channels were the same) were 2440 and 1690.
Thanks so much for taking time out of your life to work on my problems!
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.madlabs.info - Home of the Hydrogen Fuel Cell Robot
Post Edited (Jonathan) : 3/19/2005 6:18:21 PM GMT