IMU 6DOF + GPS TTL communucation problems

i want to use my Duemilanove to recieve IMU 6DOF TTL data along with GPS data at the same time. I'm trying to use the SoftwareSerial Library with no luck. for now, to simplify the problem, i'm just trying to receive data from either unit by itself. here is the code:

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = 4;
byte tx = 6;
byte SWval;

void setup() {
  Serial.begin(9600);
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
}

void loop()
{
    SWval = SWread();
    Serial.print(SWread());
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

reading the gps data just gives me infinite strings of bytes and the IMU doesn't communicate at all because it's waiting for my input which i'm unable to give. the IMU is supposed to start up with a menu where you select different options and send g to tell the unit to start sending data. of course, i don't get to see the menu because the code does not communicate with it correctly so i get nothing.

why not try the newSoftSerial library: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233298805

ok i tried it and i still basically have the same problem. i can get data from the gps, but it's not gps strings like it should be. just single random ascii characters or bytes. i get nothing from the IMU (because it's waiting on me but i can't see it's menu.) here's the code:

#include <NewSoftSerial.h>

NewSoftSerial gps(3, 2);
NewSoftSerial imu(7, 5);

void setup()
{
  imu.begin(9600);
  gps.begin(9600);
  Serial.begin(9600);
}

void loop()
{
  // Every 10 seconds switch from 
  // one serial GPS device to the other
  if ((millis() / 10000) % 2 == 0)
  {
    if (gps.available())
    {
      Serial.print("GPS: ");
      Serial.print(gps.read(), BYTE);
    }
  }
  
  else
  {
    if (imu.available())
    {
      Serial.print("IMU: ");
      Serial.print(imu.read(), BYTE);
    }
  }
}

in fact, i've tried every gps example code i could find with the same result. either nothing or illegible characters. i've got the 32 Channel San Jose Navigation GPS 5Hz Receiver with Antenna from sparkfun. aslo called the FV-M8. should work like all the others if connected properly.

Does the GPS send TTL-level data in true or inverted form? Most (if not all) RS-232 converter chips are inverting, so most TTL serial ports produce inverted data. Could this be a source of confusion in your setup?

i looked through the manual and specs several times and didn't see any indication of either. it just says it uses TTL. where would i find code to test either scenario?

FINALLY got something. i changed the gps baud rate to 38400bps, out of pure randomness, and now i get legible GPS strings. the manual clearly states the default is 4800bps. i still need to get data from the IMU. to do that i need to see the menu that it sends on startup but i get nothing.

#include <NewSoftSerial.h>

NewSoftSerial gps(2, 3);
NewSoftSerial imu(7, 5);

void setup()
{
  imu.begin(9600);
  gps.begin(38400);
  Serial.begin(9600);
}

void loop()
{
  // Every 10 seconds switch from
  // one serial GPS device to the other
  if ((millis() / 10000) % 2 == 0)
  {
    if (gps.available())
    {
      Serial.print(gps.read(), BYTE);
    }
  }

  else
  {
    if (imu.available())
    {
      Serial.print("IMU: ");
      Serial.print(imu.read(), BYTE);
    }
  }
}

Glad to hear that it's working! Sounds like my concern about inverted TTL signal was bogus.

If you temporarily comment out the GPS code, can you receive data from this IMU device? My guess is that you missed whatever data it sent because for the first 10 seconds your program wasn't listening to the IMU.

Mikal

i tried that too.

#include <NewSoftSerial.h>

NewSoftSerial gps(2, 3);
NewSoftSerial imu(5, 7);

void setup()
{
  imu.begin(38400);
  gps.begin(38400);
  Serial.begin(9600);
}

void loop()
{
  // Every 10 seconds switch from
  // one serial GPS device to the other
  /*if ((millis() / 10000) % 2 == 0)
  {
    if (gps.available())
    {
      Serial.print(gps.read(), BYTE);
    }
  }

  else
  {
    if (imu.available())
    {      
      Serial.print(imu.read(), BYTE);
    }
  }*/
  if (imu.available())
    {      
      Serial.print(imu.read(), BYTE);
    }
}

i receive a short burst of data (which is supposed to be the root menu) every time i hit the reset button on the imu but its always just a handful of illegible ascii characters. i've tried every baud rate from 9600-115200. i just get different ascii characters depending on the baud rate i pick. 57600 is the default according to the manual.

David, do you know what the menu is supposed to look like? When you try 57600 do you get anything close to the correct number of bytes or anything at all recognizable?

Just for diagnostic purposes, could you please remove the gps.begin() line?

Mikal

ok. using this code i just get "2242240" every time i hit reset on the IMU. or, if i change it to "Serial.print(imu.read(), BYTE);" i get "àà" plus a box character.
the manual says; "When the 6-DOF v2 powers up, the first thing you'll see is the configuration menu. You are presented with 3 options for configuration: Sensor range, output type and the active channel list. Just hit “1”, “2” or “3” to enter the submenu of your choice, or hit “g” to start the unit sampling."
how do you send “g”? i tried sending it as a string like you see commented out in the code. when i did that i would get much longer strings of random ascii characters but only sometimes. it definately wasn't a continuous stream of data.

#include <NewSoftSerial.h>

NewSoftSerial gps(2, 3);
NewSoftSerial imu(5, 7);

void setup()
{
  imu.begin(57600);
  //gps.begin(38400);
  Serial.begin(57600);
  //delay(1000);
  //imu.print("<ctrl>g");
}

void loop()
{
  // Every 10 seconds switch from
  // one serial GPS device to the other
  /*if ((millis() / 10000) % 2 == 0)
  {
    if (gps.available())
    {
      Serial.print(gps.read(), BYTE);
    }
  }

  else
  {
    if (imu.available())
    {      
      Serial.print(imu.read(), BYTE);
    }
  }*/
  if (imu.available())
    {      
      Serial.print(imu.read());
    }
}

The data you're getting does indeed remind me of sampling at the wrong baud rate, although I know that's not much help.

"g" is probably just the byte 007, which you can send to your device (assuming the baud rate is fixed!) with

imu.print(7, BYTE);

Mikal

EDIT: Hey, according to the Sparkfun datasheet (http://www.sparkfun.com/datasheets/Sensors/DataSheet-6DOF-v4-Rev1.pdf), the default baud rate is 115200. See section 4.1. That means you can't use it with NewSoftSerial. What I would do in this case is connect the IMU to the hardware serial and then add an LCD screen or some other serial monitor(connected with NewSoftSerial) for debugging and menu processing.

apparently if you send anything to the imu it sends back this response. ?
??êe
2É@?S
®kÅr²P·Kíi·WH#
ý¶sZ
©ÕnºMC!Ð?j?¦¥7Î+AR°W¶
¢-?K&I?%?C??

kJñpKÊ¡)ÅÅÙ5AK?
ëÅáAAjj4Õí
+A6J¶áÕ
)
ÅÅ5AKA
A?ÙL
? and then waits. ctrl g is appearently HEX 7 or DEC 7 but it doesn't matter, i still get the same result.

hey! sending 007 BYTE worked. now it's streaming data. illegible data but still that's something.

See my EDIT above.

right. i did more testing and sending an 007 byte works in telling it to start streaming data. i also found that it only works at 57600bps so now i know i'm at the correct baud rate and i am receiving a steady stream of data. the problem is still that it's illegible ascii characters. what else can be done?

Hmm... in my NSS testing, RX at 57.6K is 99.9% accurate (although not 100%). I guess it's possible that slight differences in your Arduino clock cause this, but it's hard to see how it would be this bad. I have heard several reports of people successfully using NSS at 57.6K. Is anyone else having trouble at that speed?

Mikal

i got it to work but i don't know why it works this way and not the other. here's the code.

void setup()
{
  Serial.begin(57600);
}

void loop()
{
  if(Serial.available())
  {
  Serial.print(Serial.read(), BYTE);}
}

now wtf is up with that? is there something wrong with the NewSoftSerial library? i don't get why this works and the previous code doesn't.

here's some more weirdness. to set the scene, i've got the IMU TX -> Arduino RX and the IMU RX going to nothing. it's sticking in the air. if i touch the end of the wire with my finger it sends the menu screen. if i have it plugged in to the TX of the ardiono like it's supposed to be i get that ascii crap again.