Shop OBEX P1 Docs P2 Docs Learn Events
Dinsmore R1655 - Calling Dr. Tracey Allen — Parallax Forums

Dinsmore R1655 - Calling Dr. Tracey Allen

JonathanJonathan Posts: 1,023
edited 2005-03-19 18:08 in BASIC Stamp
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

Comments

  • Tracy AllenTracy Allen Posts: 6,658
    edited 2005-03-19 07:36
    Hi Jonathan,


    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.

    Amax  CON   2540    ' highest counts from ADC
    Amin  CON   1556     ' lowest counts from ADC
    Aspan  CON    Amax-Amin    ' approximately 984
    Ahalf   CON Amin + (Aspan/2)   ' approximately  2048 counts
    Ascale   CON  17050   ' calculate 256/(Aspan)*65536
    
    Bmax  CON   2540     ' it could be the same as A
    BBmin  CON   1556
    Bspan  CON    Bmax-Bmin
    Bhalf   CON Bmin + (Bspan/2)
    Bscale   CON  17050   ' calculate 256/(Bspan)*65536
    
    asin VAR word
    bcos VAR word
    theta VAR word
    
    
    main:
    DO
      gosub getA   ' returns result asin
      asin = (asin ** Ascale) - (Ahalf ** Ascale)  ' rescale, offset gives -127<= asin <= +127
      gosub getB   ' returns result bcos
      bcos = (bcos ** Bscale) - (Bhalf ** ABscale)  ' rescale, offset  gives -127<= bcos <= +127
      theta = asin  ATN bcos  */ 360    ' find angle and convert brads to degrees
      DEBUG  ? theta
      PAUSE 500
    LOOP
    





    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
  • JonathanJonathan Posts: 1,023
    edited 2005-03-19 15:59
    Tracey, All,

    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
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2005-03-19 17:06
    Oh, right, the CON does not allow parens and it executes strictly left to right. So it should be

    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.

    Amax  CON   2540    ' highest counts from ADC
    Amin  CON   1556     ' lowest counts from ADC
    Aspan  CON    Amax-Amin    ' approximately 984
    Ahalf   CON Aspan/2+ Amin    ' approximately  2048 counts
    Ascale   CON  17050   ' calculate 256/(Aspan)*65536
    
    Bmax  CON   2540     ' it could be the same as A
    Bmin  CON   1556
    Bspan  CON    Bmax-Bmin
    Bhalf   CON Bspan/2 + Bmin
    Bscale   CON  17050   ' calculate 256/(Bspan)*65536
    
    asin VAR word
    bcos VAR word
    theta VAR word
    
    
    main:
    DO
      GOSUB getA   ' returns result asin
      DEBUG CR,DEC asin
      asin = (asin ** Ascale) - (Ahalf ** Ascale)  ' rescale, offset gives -127<= asin <= +127
      GOSUB getB   ' returns result bcos
      DEBUG TAB,DEC bcos
      bcos = (bcos ** Bscale) - (Bhalf ** ABscale)  ' rescale, offset  gives -127<= bcos <= +127
      theta = asin  ATN bcos  */ 360    ' find angle and convert brads to degrees
      DEBUG  TAB, DEC asin, TAB, DEC bcos, TAB, DEC theta
      PAUSE 300
    LOOP
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • JonathanJonathan Posts: 1,023
    edited 2005-03-19 18:08
    Tracey,

    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
Sign In or Register to comment.