Shop OBEX P1 Docs P2 Docs Learn Events
Parallax Compass Module and Propellor — Parallax Forums

Parallax Compass Module and Propellor

Mike GreenMike Green Posts: 23,101
edited 2006-06-26 05:53 in Propeller 1
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

  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2006-06-16 02:08
    One of the first experiments I tried was to hook up the HM55B to the Propeller.· The Propeller does not output a high enough level to cross the high input threshold of the HM55B.· There was another thread where a couple people posted ideas on how to over come this when I asked for help.
    ·
    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
  • Mike GreenMike Green Posts: 23,101
    edited 2006-06-16 03:13
    I would still like to hear from the Parallax people about the possibility of bypassing the 5V to 3.3V regulator and just running the whole thing at 3.3V. That seems much simpler than using level shifters since the HM55B is already designed to work just fine at 3.3V.
  • edited 2006-06-16 04:40
    Alright then, here is an initial (but not final) word from Parallax. The HM55B's 3.3 V regulator would have to be removed, and a jumper placed across the·regulator's voltage·input and output pads for a prototype to work properly in a 3.3 V system. We don't like recommending cutting and jumping, so we'll try some other things first and get back to you.

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2006-06-16 04:53
    Thanks for the suggestion. That sounds very doable (driving active low only). I know the PING sensor seems to work at Propellor logic levels. Would there be a reliability advantage for the PING data line to also have a 5V pullup?
  • edited 2006-06-16 05:00
    I don't think the Ping))) will ever need a pullup. I'm not looking at the schematic just now, but I'm pretty sure that the Propeller I/O pin gets connected to an SX chip I/O pin on the Ping))) rangefinder. If it currently works, the SX chip I/O pin must either be set to CMOS (2.5 V threshold) or TTL (1.4 V threshold). So it should always work just fine. The Hitachi chip is somewhat of a black box in comparison. I'll take a closer look tomorrow and let you know what I find out.
  • edited 2006-06-17 03:01
    There doesn't appear to be any problem using a Propeller microcontroller to communicate with an Hitachi HM55B Digital Compass Module, at least not with the 4-wire interface published in the compass module's documentation.·

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2006-06-17 03:46
    Thanks for your help. I have a Ping and an HM55B on order and will probably get to test them late next week. I'm still concerned about the Propellor's output high level being high enough for the HM55B when its digital interface is run at 5V (according to Hitachi's spec sheet). If I need higher levels, I'll just use a MOS-FET (like a 2N7000) as a simple open-drain inverter with a pull-up to 5V.

    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.
  • Cliff L. BiffleCliff L. Biffle Posts: 206
    edited 2006-06-17 06:44
    Mike, could you post that URL? I'm a software guy, and the whole 3.3v-5v communication issue has been troubling me. (In my case, it's between an Acroname Brainstem and an embedded ARM system. Currently they both use MAX232s, wired directly together...less than ideal.)
  • edited 2006-06-19 18:33
    Mike Green said...
    I'm still concerned about the Propellor's output high level being high enough for the HM55B when its digital interface is run at 5V (according to Hitachi's spec sheet). If I need higher levels, I'll just use a MOS-FET (like a 2N7000) as a simple open-drain inverter with a pull-up to 5V.
    The Hitachi HM55B chip has CMOS inputs.· Since its digital power rails are 0 and 5 V,·its logic threshold is right around 2.5 V.··So, a 3.3 V high signal isn't going to be misinterpreted as a low, at least not on the bench.··The caveats to this are power supply and signal noise.· Since there's less headroom between the logic threshold and the incoming high signal, you'll want to make sure to use a good regulator and avoid long signal lines.··In noisy environments, isolation and signal drivers may be necessary in addition to keeping the sensor away from various sources of magnetic interference.·
  • MarksuMarksu Posts: 5
    edited 2006-06-22 17:49
    It looks like Andy's code attached above works great (4-wire interface with 100K resister). Now I'm trying to use the Float32 library's ATan2() function to mimic the ATN BS2 function that converts the x/y values from Andy's program to degrees.

    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
  • Charlie JohnsonCharlie Johnson Posts: 147
    edited 2006-06-22 19:07
    Marksu,

    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
  • Charlie JohnsonCharlie Johnson Posts: 147
    edited 2006-06-23 18:06
    Andy,

    In your "Test HM55B.spin" code, should the NMASK be $FFFFF800 vice $FFFFFC00 ??

    Charlie
  • edited 2006-06-23 18:38
    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
  • MarksuMarksu Posts: 5
    edited 2006-06-25 23:20
    Thanks dy9coke!

    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
  • edited 2006-06-25 23:50
    Marksu,

    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
  • edited 2006-06-26 00:23
    BTW, where is the ATan2 method you are using?

    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
  • MarksuMarksu Posts: 5
    edited 2006-06-26 04:14
    Thanks Andy!

    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
  • edited 2006-06-26 05:53
    Good; glad it worked. I somehow missed the Float32Full object, so I was kind of going out on a limb there.

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