Shop OBEX P1 Docs P2 Docs Learn Events
How do I receive data from IMU — Parallax Forums

How do I receive data from IMU

Tony CunninghamTony Cunningham Posts: 43
edited 2010-09-02 20:59 in Propeller 1
I need help figuring out how to read the incoming data from the CHR-6dm AHRS. I have the pdf doc here for anyone to look at. I've got my code reading the IMU, but the result is not what it is supposed to be. I'll put my code here so you can see what I'm getting. I know I'm not coding this right to be able to read it properly.

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2010-08-06 20:54
    My reading of the spec says the data is prefixed with some bytes snp... discribed on page 32, you need to look for that followed by packet type b7 and then the packet length before you get the sensor data.
  • Tony CunninghamTony Cunningham Posts: 43
    edited 2010-08-07 09:37
    Thanks Tim,

    I just don't know how to go about doing that. Did you see my code? I went about it the only way I know how so far. Any suggests on how to "look" for the data packet?

    Tony
  • TimmooreTimmoore Posts: 1,031
    edited 2010-08-07 10:16
    Take a look at this, it still needs work but you can see what you need to do. The packet format is "s","n","p",$b7,N,data
    so it waits for a s, then n then p then $b7, then checks N is >= 2 then gets the data. The first 2 bytes are which channels are active so you need to get that and use it when reading the data. Its looks like the data is binary so you need to Num.dec for all the data. It doesn't check the checksum but to do that you need to read into a buffer, check the checksum and then display but this should get you going.
  • Rick BrooksRick Brooks Posts: 67
    edited 2010-08-07 13:05
    Tim and Tony,

    I also have a CHR-6dm that I'd like to interface to a Propeller. I haven't done much, but take notes and think about it.
    For the code Tim posted, each measurement is actually two words long. So I think that you'd have to do something like:
    yaw := ser.rx
    yaw := (yaw << 8) + ser.rx
    Then to correct for negative values, check the 15th bit like:
    if yaw & |< 15
    and to make a 32 bit signed do a:
    yaw |= NMASK
    where NMASK is FF FF 00 00
    Then you have a signed long for yaw.
    To convert to degrees, just multiply by .0109863 (or do an integer divide by 91).
    I am quickly running out of resources. I do have a spare port on Tim's pcFullDuplexSerial4FC that I hope can be used for the compass input.

    Rick Brooks
  • TimmooreTimmoore Posts: 1,031
    edited 2010-08-07 13:57
    Rick, Yes you are correct each sensor is 2 bytes, to sign extend you can do
    yaw := ser.rx
    yaw := (yaw << 8) + ser.rx
    yaw~~
    
    the ~~ sign extends for 16bit data

    You should be able to use a port on the 4 port serial, I haven't used the chr6m but I have used it with the sf9 dof AHRS at 115200
  • Tony CunninghamTony Cunningham Posts: 43
    edited 2010-08-07 14:26
    Thank you, Tim

    I want to understand how to do this better so I have a couple of questions.

    What does this do "if ser.rx => 2"?

    What is this doing "if active & $8000"?

    Also, the docs talk about scaling the output. I tried multiplying the yaw input, but got this huge number that doesn't match what it's supposed to be. You have any ideas?

    If I were to transmit to the IMU, how would I do that?
  • Tony CunninghamTony Cunningham Posts: 43
    edited 2010-08-07 15:09
    Rick,

    Thank you for you input also. The more the better! I hope you get to using your IMU soon cuz I'd like to see how you do it.
    I put you and Tim's suggestion about the 2 byte data, now I'm just getting a -1 with no movement. I added pst for debug so it would be easier to see the results, because I know Tim uses it. He was the one who steered me to the pst debug.
  • TimmooreTimmoore Posts: 1,031
    edited 2010-08-07 15:27
    If you look in the datasheet page 32, it says the transmitted packets from chr6 contain
    's','n','p' so the code needs to check for those characters arriving in that order.
    Then the next byte is PT or packet type, looking at the list you need SENSOR_DATA which is 0xB7 or $b7 in spin, so the 4th rx should be $b7
    the next type is N, on page 35 for sensor data it says N = 2 + 2*# active channels so N is greater than or equal to 2.
    The next 2 bytes list the active channels - see page 36, so you read those 2 bytes put them together as a single variable then bits in that variable say which active channels are being sent.
    if active & $8000 is testing one of the bits - in this case the yaw bit, if its not 0 then the yaw channel is being sent so you can read 2 bytes, put them together, sign extend it and its the yaw value.

    The multiplication they are talking about is if you want it in the right units, on page 8 they tell you the units and scale value for each channel. I wouldn't worry about that until you are reading from the chr6 correctly.
  • kuronekokuroneko Posts: 3,623
    edited 2010-08-07 16:58
    Timmoore wrote: »
    yaw := ser.rx
    yaw := (yaw << 8) + ser.rx
    yaw~~
    
    the ~~ sign extends for 16bit data

    Sign-extension requires it to be written/used like this
    ~~yaw
    
  • Rick BrooksRick Brooks Posts: 67
    edited 2010-08-07 18:00
    Tim,
    Thanks for the hint on Sign Extended 15. I never noticed it before.

    Tony,
    I've already reconfigured my CHR-6dm into silent mode and to only send yaw, pitch, and roll data. That way I'll send a 7 word packet and receive a 15 word packet. That is what I'm doing now with a HMC6352 and Spin I2C interface.
    The HMC6352 is producing reasonable results. So the CHR-6dm isn't a high priority project for me. That means that someone else will probably get the code written before I get to it.

    Rick Brooks
  • Tony CunninghamTony Cunningham Posts: 43
    edited 2010-08-07 19:13
    kuroneko,
    Thanks for the correction, that helped. I'm getting some better numbers.

    Rick, I appreciate your input. If it wasn't for you and Tim and kuroneko I wouldn't have gotten anything at all.

    I would still like to know how I would send data packets to the CHR-6dm.
    Rick, you said you put yours in silent mode, how did you do that? Did you do it with spin?
  • Rick BrooksRick Brooks Posts: 67
    edited 2010-08-07 20:40
    Tony,
    You can change modes using either the AHRS Interface PC Software that is available from CH Robotics, or a serial program on your PC. Since Hyperterminal isn't on Windows 7, I've been using RealTerm. It has a hex feature that makes it easier.
    The hex command for silent mode is: 73 6E 70 81 00 01 D2
    The hex command for yaw, pitch, roll only is: 73 6E 70 80 02 E0 00 02 B3
    To write the settings to flash, send: 73 6E 70 A0 00 01 F1

    To get data, send: 73 6E 70 01 00 01 52

    A typical output would look like: 73 6E 70 B7 08 E0 00 C2 9A 01 E9 26 FC 06 58
    Yaw is C2 9A which converts to -172 degrees
    Pitch is 01 E9 which converts to 5 degrees
    Roll is 26 FC which converts to 109 degrees

    Rick Brooks
  • Rick BrooksRick Brooks Posts: 67
    edited 2010-09-02 18:18
    Tony,

    Try out the attached code. I believe that I used the proper correction factors for each of the readings.

    It uses the "listen" mode, so you may want to modify it to use the "broadcast" mode.

    Setting the CHR-6dm to output only yaw, pitch, and roll as fast as possible in listen mode, one complete reading takes 2.2 to 3.8 msec. It seems that the CHR-6dm takes from 0.9 to 2.5 msec to start sending data after the request. That seems like a long time to me.

    Let me know if it works for you.

    Rick Brooks
  • John AbshierJohn Abshier Posts: 1,116
    edited 2010-09-02 20:59
    Here is a Spin program. It assumes that all data elements are being sent. I had the Devil to pay to get the PC program to work. Next project is to get Spin code written for calibration, not including hard and soft iron calibration (I don't see how to do that on the Prop.). Usage is MIT license. I forgot to put it in the code.

    John Abshier
Sign In or Register to comment.