Atomic IMU 6DOF not WORKING!!

Well this(Figure below) is my setup. I am guessing if my connections are correct, the power led must glow, which is not happening.

http://i821.photobucket.com/albums/zz13 … 0728_1.jpg

My connections

  1. gnd of imu to gnd of arduino.

  2. Vcc of imu to 5v of arduino.

  3. Rx of imu to Tx of arduino.

  4. Tx of imu to Rx of arduino.

And obviously, Arduino to comp and IMU switched on…

Alright, now what!

-RaHL

Just to get people up to speed … a problem was found in this thread.

viewtopic.php?f=14&t=29182

The last post there was …

rahlk:
Well, firstly a servo just worked on that very 5v output pin on the mega, i guess there are no problems over there.

Secondly, i tried resoldering the pins too, infact i’ve now soldered it up and down both ways. And finally, the led does glow when i connect it through that two pin alternative power supply on the IMU. So, do you think the IMU may be defective?

me:
OK, sounds like something open in the path from JP4 to the switch. So power it up via that other connector (JP1?). I assume you still have no communication, IMU to Arduino. So there’s 2 likely possibilities. First the Tx/Rx lines are somehow swapped. That’s easy to check, just swap the lines and see what happens. I believe all UARTs are protected so Tx-Tx won’t hurt anything, it just won’t work.

If that doesn’t work then it’s time to look at your coding and port setup on the Arduino. You will probably be better served by posting your code in the Arduino forum here vs this one/

So I think there’s a definite HW issue (the OP should contact SF about a replacement) but it sounded like the OP has another problem on top of that. My suggestion was that he bypass the open to power his 6DOF, try the above and then post his results and sketch here to get comments on his coding.

Thanks Guys(esp Mee_and_Mac), i got it working with my prev connections. Bad soldering :oops:

I managed to connect the atomic IMU 6DOF to the mega and used the code(given below) to read the data. I am getting a set of distinct numbers that actually make no sense at all…

int imuData[9];
void setup() {
  Serial.begin(115200);
  Serial.println("#");
  Serial.println("-");
}
void loop() {
  for(int i=0; i<9; i++) {
    imuData[i]=Serial.read();
    Serial.print(imuData[i]);
    Serial.print("__");
}
Serial.println("");
delay(900);
}

-RaHL

Can you post the raw data and what you were doing to the IMU as that data was taken ? What portions of the data looked bad, the accel or the gyro outputs … or both ? Are you able to check that your serial link, Arduino-6DOF, is good ? That is your not getting framing errors or overun or parity errors or ???

Hey, here’s what you asked for, my above posted code generates this-

http://i821.photobucket.com/albums/zz13 … Output.jpg

Cheers!

How does the Arduino serial read function handle overruns and framing errors ? My first guess is that the data may be coming from the IMU faster than the Arduino can read it. I know the IMU has to spit out 3 accels and 3 gyros, what are the other 3 words supposed to be ?

EDIT : I did a quick look at the datasheet and comments and I found the output frame is supposed to be an ASCII “A”, sample count (since turn on I guess), 3 accels, 3 gyros and an ASCII “Z”. I’d assume that the default condition is auto-run but I have no idea of the default sampling rate. Perhaps you could ask SF what this is. Hopefully it’s slow enough to allow your loop to read in and complete the “print” out the data frame before the next frame. So my first inclination is to flush the buffer from the IMU and then check to see if data is “available”. When it is, do a character by character read (2 bytes) until the software detects an ASCII “A”. Then enter your loop reading 9 (8 more for the 1’st pass) byte pairs and “print” those out. I’m not sure if your loop needs to check to see if there’s a byte “available” each time before reading, I don’t know enough about Arduino sketch-speak to say. Ideally you should end up with an ordered output that we humans can more easily understand. Alternately if your software never “sees” an ASCII “A” (or data never becomes “available”) then it should time out (every few seconds seems reasonable) and “print” some error statement. I’d still enquire as to how an Arduino detects the aforementioned common serial errors and see if you can’t arrange some error printout for those as well.

I note that “count” comes appears to come across in binary format (0-32767 in 16 bits), so you may want to convert that to ASCII someplace after it’s read in and before it’s “printed” out. This will mean your output frame is longer than the input frame (assuming all output is all ASCII encoded) and thus needs more time to be transmitted. My SWAG at timing indicates so long as the IMU sampling rate is <100 Hz, you should be free from input overruns for a properly configured serial port (IMU<->Arduino), but the exact number will depend on how tightly the code can be done.

BTW the IMU datasheet mentions the status LED should blink 5x upon power up and then cycle every 64 samples thereafter. Is it doing this ? If not what is it doing ?

Hello again. The status LED does blink, and once a “#” is passed it begins to blink almost once a second. I am puzzeled because the whole thing is supposedly in a byte mode or something by default, maybe thats why int imuVal statement doesn’t work, so if i were to use a hyperterminal and change it an ASCII mode and then try the code it may work, right?

Oh, and the arduino uses a 16MHz clock so ummm, i guess its faster than the imu… And about my project, its a drone thingy which must have an IMU to stabilize it 'n all, do you think i must be using the arduIMU v2 instead?

rahlk:
Hello again. The status LED does blink, and once a “#” is passed it begins to blink almost once a second.

OK, I see you have autorun disabled. No problem, that might even be a good thing. So most of what I suggested above remains the same but I'd flush the Arduino serial1 buffer before I had the Arduino send the "#" to the IMU. Hopefully this means you could forget having to do the search and sort by "A" (though that doesn't hurt). I also now realize you're in binary output mode so viewing the data in Hyperterminal is going to make it appear to be wierd data. You need to convert each 2 byte word sent into ASCII to make it human intelligible. The only exceptions each burst are the "A" and "Z" characters, they're already in ASCII. You can do this conversion in the Arduino, though that means a longer output burst of data (each of the 2 bytes of count, accel and gyro data will become more bytes when encoded as ASCII characters). Or you can have the Arduino transmit the data as received and you can use another program to transform it into ASCII so you can read it.

Right now I’m having a hard time understanding just how that data is formatted. It seems simple enough from the datasheet on the IMU but the number of bytes and values and words sent don’t jive with what’s said in that datasheet. Maybe I just need to wake up some more.

rahlk:
I am puzzeled because the whole thing is supposedly in a byte mode or something by default, maybe thats why int imuVal statement doesn’t work, so if i were to use a hyperterminal and change it an ASCII mode and then try the code it may work, right?

Let me think about this. As said above I'm having a hard time interpreting what the datasheet means in this regard.

EDIT: OK, I’ve had time to wake up and the output format per the IMU datasheet now makes sense to me. My guess is your data may be good, we’re just not looking (interpreting) it properly. Let me look at what options Hyperterminal has to interpret and display input data and get back to you on this. Having the IMU send it’s data to the Arduino in ASCII mode would simplify our ability to use something like Hyperterminal to view the data but that might not be the best thing for your final application, using the IMU as an IMU for your drone.

rahlk:
Oh, and the arduino uses a 16MHz clock so ummm, i guess its faster than the imu… And about my project, its a drone thingy which must have an IMU to stabilize it 'n all, do you think i must be using the arduIMU v2 instead?

I was worried about how often the data bursts were being sampled and sent to the Arduino. I don’t think that’s a problem now. The datasheet says it should be on for 64 samples and off for 64 samples. Given your 1 blink/sec that means the sample rate is either 100 Hz or 150 Hz. I don’t think that’s going to be a problem.

I don’t know what to say re: the arduIMU v2.

OK, I believe I see a few problems. Let me start with explaining what you probably already know. In binary output mode the data comes in “bursts” at the sampling frequency. Each burst consists of :

  • a leading ASCII “A”, one byte, value = 65d, 41h, 0100 0001b (that’s decimal, hex and binary representations)

  • 2 bytes of unsigned integer for the count, value = from 0 to 32767d (7F,FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the X accel, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the Y accel, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the Z accel, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the pitch gyro, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the yaw gyro, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • 2 bytes of unsigned integer for the roll gyro, value = from 0 to 1023d (03, FF h in MSB then LSB order)

  • a trailing ASCII “Z”, one byte, value = 90d, 5Ah, 0101 1010b

… for a total of 16 bytes per burst.

First problem is that you do this …

int imuData[9];
void setup() {
  Serial.begin(115200);
  Serial.println("#");
  Serial.println("-");
}
void loop() {
  for(int i=0; i<9; i++) {
    imuData[i]=Serial.read();
    Serial.print(imuData[i]);
    Serial.print("__");
}

… which treats each incoming byte as a signed 2 byte integer. I think (because I don’t speak Arduino sketch language) you need to declare imuData() as an unsigned integer and then you need to combine the bytes just read in before storing them in imuData(). This gets the binary data, which was split into bytes to be transmitted to the Arduino, back into it’s proper form. Obviously the single byte characters “A” and “Z” don’t get this treatment.

Problem #2 : that should be serial1.read

Problem #3 : you need to setup the serial port (0) to/from the PC at the Arduino end

? Problem #4 ? : why are you sending a space to the IMU after starting it ? Is that required ? I don’t think so. I read that it would stop the IMU (so I got rid of it below).

So what to do ? Read the IMU data in as bytes because that’s all you can do (I think), store them that way. Combine them (where required) and store them as imuData() because later in “life” you’ll want those 2 byte values to run your autopilot. Then just for debug purposes, print everything out as ASCII characters via the serial port to the PC where you can look at them and marvel at their goodness.

Take the following as a hint, a starting point as to what to do, not as proper code to do everything.

byte rawData[16];       // this will store the bytes as received from the IMU
unsigned int imuData[6]; // this will store only the imu data needed for the autopilot (accels and gyro) 
unsigned int count[1];   // this will store the "recombined" value for count
unsigned int temp[1];   // create a temporary 16 bit variable for use in converting bytes to ints
void setup()
{
  Serial.begin(115200); // setup the serial port to the PC to be 115k baud
  Serial1.begin(115200); // setup the serial port to the IMU to be 115k baud
  Serial1.flush();         // empty the serial port input buffer of any garbage due to power up
  Serial1.print("41");    // set the IMU to 50 Hz sample rate just until this all gets working
  delay(10);             // wait for a 10 msec just in case
  Serial1.print("#");    // command the IMU to start sending data, I changed it to a simple print, no CR needed
}
void loop()
{
  for(int i=0; i<16; i++)
  {
    if (Serial1.available())   // make sure data is available from serial port, seems everyone does this
    {  
      rawData[i]=Serial1.read(); // read the raw data from the IMU, byte by byte
    }   
  }
  // convert the raw data into 2 byte unsigned integers
  for(int i=0; i<6; i++)
  {
    // high byte of imuData is MSB = 1'st of 2 bytes received from IMU, index into rawData to skip "A" and count
    temp = rawData(2*i+3);                  // copy 1'st byte into unsigned int
    temp = temp*256;                        // do it this way to get around Arduino byte to int problem 
    imuData(i) = temp + rawData(2*i+4);    // 2 bytes of binary are now 1 word of binary
  { 
  temp = rawData(1);
  temp = temp*256; 
  count[1] = temp + rawData(2); // convert count as well, store separately from imuData 
  // Now send data out over serial0 port to PC, delete this later when everything is working as it takes a lot of CPU cycles
  Serial.print(rawData(0),BYTE);      // print leading "A" knowing it's already ASCII
  Serial.print(",");                  // print a comma, will make it easy to import into plotting program (as CSV file)
  Serial.print(count);                // print count of samples
  Serial.print(",");
  for(int i=0; i<6; i++)
  {
    Serial.print(imuData[i]);          // print IMU data
    Serial.print(",");
  }
  Serial.println(rawData(15),BYTE); // print trailing "Z" followed by carriage return
}

Now sending all this data out over the serial port as ASCII characters takes some time. If I have 4 (the max it could be) characters (bytes) per accel & gyro parameter plus 5 (max) for ‘count’ plus the commas and an “A” and a “Z” and a CR at the end … that will take < 4 msec and if you’re running sampling at 150 Hz*, it should leave you with ~ 2.66 msec to do the reading and converting. Reading in the data from the IMU will take ~ 1.66 msec so you have 1 msec to do all the converting I’ve coded above. I think that’s enough time but if you can do it more efficiently (and I’m sure it can be done !) then do it.

*Just to keep problems to a minimum while we’re debugging this, I changed the sampling rate to something slower (sending an ASCII 41d to the IMU before starting it sets the sample rate to 50 Hz). Feel free to keep or remove it. When everything is working properly, you may want to set it back to 100+ Hz (and remove the print commands).

I did not add in any debug statements for timeouts on the IMU-Arduino serial port, nor check for overruns or framing errors (I don’t know how). Nor did I verify the 1’st byte received from the IMU was indeed an ASCII “A”. You might want to consider doing these if the data still comes out weird.