Parallax Compass Module and Propellor
Mike Green
Posts: 23,101
Does anyone know whether the Parallax compass module (Hitachi HM55B) will work with the Propellor? There's a 5 to 3.3V regulator on the module for the analog circuitry, but the digital interface runs off 5V. The spec sheet implies that the logic high output of the Propellor is too low for the Parallax compass module. I suppose I could solder a jumper across the regulator so the whole thing runs off 3.3V from the Propellor Demo Board, but I'd just a soon not modify the unit if I can avoid it.
Comments
·
I jumped off into something else before I got it to work, but I hope to return to the compass soon.· I found a MC14504B chip that works as a level shifter for 3.3V to 5V.· This may solve the problem of voltage differences.
·
If you get yours working let me know.· I started writing code for the HM55B but stopped when I ran into the trig calculations because I was not familiar enough with Spin and·assembly yet.· I am feeling more confident now and will probably look back into this.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter
tdswieter.com
One little spark is all it takes for an idea to explode
I'm a little surprised that the HM55B won't accept the 3.3 V input signals. If that's the case, I might try pulling up the HM55B's DIN and CLK lines to 5 V with resistors, and writing a modified synchronous serial object that sets the I/O pins to inputs for sending high signals, and of course, low signals will still be OUTA[noparse][[/noparse]pin] := 0 and DIRA[noparse][[/noparse]pin] := 1.
Post Edited (Andy Lindsay (Parallax)) : 6/16/2006 4:43:35 AM GMT
The only change would be to add a 10 k resistor between the HM55B's Dout pin and the Propeller microcontroller's P6 I/O pin to minimize the current passing through the protection diode.· Apparently when the current passing through a protection diode is on the same·order as the Propeller chip's·current consumption, it can effect the Propeller's power rails.· So, larger series resistors are better whenever you are using circuits that send signals above or below the 0 to 3.3 V range.
Attached is some test code (schematic included) to try with the Propeller and HM55B module with the modified 4-wire interface.· It's just a quick little program with most of the necessary ingredients for an object.· I still need to test the 3-wire interface before·writing it, but ran·out of time today.· I figured you'd probably prefer something that works sooner over something that's spiff later.
I did find an interesting application note on Philip's website for a "Bidirectional level shifter for I2C-bus and other systems" #AN97055 that uses a MOS-FET for each line (SDA,SCL) and pull-ups to 3.3V and 5V on the appropriate side of the MOS-FET. I'm sure it would work just fine for SPI as well if I should need it.
Has anyone else tried this yet? My Prop locks up when I run ATan2(x,-y)...
(I noticed that a new Float32lib was posted today, but only the Sin/Cos functions were modified)
Thanks!
Mark
I have an HM55B also, and I was thinking that instead of using ATan2(x,-y), try x * ATan(-y) as shown in the HM55B docs.
I am thinking along the lines of:
VAR
LONG angle, rads
OBJ
fp : "Float32Full"
.
.
.
fp.start
.
.
.
rads := x * fp.ATan(-y)
angle := fp.Degrees(rads)
I am at work, so can not test this. Will test when I get home later.
Charlie
In your "Test HM55B.spin" code, should the NMASK be $FFFFF800 vice $FFFFFC00 ??
Charlie
The results should be the same either way, but $FFFFF800 would make the code a little more self explanatory.
Bit-10 is the sign bit for the HM55B's field measurements. Since the program ORs the axis measurement with NMASK when bit-10 is 1, $FFFFF800 will change all the leading 0s to 1s (bits 32..11) to make it a 32-bit signed value. Since bit-10 == 1 is the condition that has to be met to OR the measurement with $FFFFFC00, bits 32..11 still get changed to 1s, and bit-10 is left 1 since 1 OR 1 = 1.
Andy
Post Edited (Andy Lindsay (Parallax)) : 6/23/2006 6:42:48 PM GMT
I found a couple of issues with my code. The first was that I wasnt 'starting' the Float32Full. Once I did that ATan2 'kind-of' worked with the following code. I say kind-of, because it only works between 0-90 degrees. Any negitive values into the ATan2 function return a -6.81e+38..
lcd.str(string("R="))
rads:= fp.ATan2(-y,x)
lcd.str(FtoS.FloatToString(rads))
lcd.str(string("' D="))
angle := fp.FMUL(rads,57.0)
lcd.str(FtoS.FloatToString(angle))
I did revise my code to include Andy's code above. Do you think there is something in the negitive-mask that doesnt seem to be working right? (I cant say I uderstand the |< and the |= syntax well enough to determine if it's right or not..)
Thanks!
Mark
Does the ATan2 method require floating point numbers or integers?· TestHm55b.spin is working with integers.· Here is an example that calls the FFloat method to convert -y and·x to floating point before they are passed to ATan2:
···· rads:= fp.ATan2(FFloat(-y),FFloat(x))
Here's a second example that should accomplish the same thing:
···· y := FFloat(-y)
···· x := FFloat(x)
···· rads:= fp.ATan2(y,x)
Andy
Post Edited (Andy Lindsay (Parallax)) : 6/25/2006 11:58:06 PM GMT
Also, both |= and |< are explained in Chapter 4 of the Propeller manual <http://www.parallax.com/propeller/downloads.asp>. Look up "Bitwise Decode" and "Bitwise OR".
What this code is doing is creating the number %000...0010000000000 with |< 10, which creates a number with a 1 in a specified bit, and the rest are 0s. If this number AND y is not 0, it means that y has a 1 in bit-10 also, so it's a negative value. If it is negative, it needs to be sign-extended from 11-bits to 32-bits, which is what y |= NMASK does. It's the same as y := y | NMASK. The result of y OR %111...1100000000000 is that bits 31..11 are changed to 1, while bits 10..0 are left unchanged.
if y & |<10
·· y |= NMASK
You were right! ATan2 needed floats...
rads:= fp.ATan2(fp.FFloat(-y),fp.FFloat(x))
I'm using the new Float32Full that was posted last week (V1.1)..
I found the Bitwise Decode |< in the docs (chap 4), but I'm still not sure why you needed an AND '&' before the Bitwise decode. Unless it's some type of validation that the number 'is a number' AND |<... (I see that the code wont compile without the & before the |<) I just didn't see any references to the combination of terms...
Thanks again for your help!
Mark
The |< 10 operator just creates the value %000...0010000000000. The y variable holds some other 11-bit twos complement (signed) value. If it's negative, its bit-10 will be 1. For example -4 is this in 11-bit twos complement binary is: %11111111100. If it's positive, bit-10 will be 0. For example, here's +3: %00000000011.
One way to figure out if the y variable's bit-10 is 1 (negative) or 0 (positive) is to AND it with %000...0010000000000. Since 1 AND 1 = 1, and the rest of the possible combinations for AND are 0, the result of this AND operation has to be non-0 if y is negative and 0 if y is positive:
%000...0010000000000
%000...0011111111100 AND
%000...0010000000000
> NOT zero, so negative
When we try it with a positive number, the result is 0, so the number is positive.
%000...0010000000000
%000...0000000000011 AND
%000...0000000000000
> zero, so positive
The IF block considers 0 to be FALSE. So, when %000...0010000000000 & %000...0000000000000 = 0, it skips the |= sign extending part. On the other hand, %000...0010000000000 & %000...11111111100 = %000...0010000000000, which is not zero. According to the Propeller Manual:
"A Boolean result of False is actually the numerical value 0 and True is -1, but Boolean comparisons treat zero (0) as False and any non-zero value (≠0) as True."
So, whenever the IF statement's condition evaluates to zero, it skips the sign extend. On the other hand, whenever the condition evaluates to non-zero (%000...0010000000000), the sign extend code is executed. So, the AND operation is just a way of making the condition evaluate to 0 if y.bit10 is 0 or to 1 if y.bit10 is 1.
Post Edited (Andy Lindsay (Parallax)) : 6/26/2006 5:56:33 AM GMT