Hi, I’m working on a quadrotor project but seem to be having troubles with receiving serial communication on my Arduino. I’m trying to communicate between my Arduino Pro and my Sparkfun 9DOF razor IMU running the a modified AHRS code. I have my Arduino connected to an XBee on the hardware serial line communicating to my computer so I am using the new soft serial library for a second serial line. I have the TX and RX lines on the IMU hooked to pins 2 and 3 on the Arduino respectively. I also have the IMU board grounded to the Arduino and both boards are running from their own separate power sources. The problem I seem to be having is that I’m only getting the first 2-3 characters of correct data on the serial monitor and the rest is gibberish. I am sure that the IMU is reporting accurate data because I’ve hooked it directly to my computer and it transmits fine. I am also certain that the baud rate is correct on both devices (57600). I have a very simple program running just to test this:
#include <NewSoftSerial.h>
NewSoftSerial mySerial(2, 3);
void setup() {
Serial.begin(57600);
mySerial.begin(57600);
}
void loop(){
if(mySerial.available()){
Serial.write(mySerial.read());
}
}
Any suggestions?
Thanks!
Sure sounds like a slight baud rate mismatch or that the Arduino gets behind (somehow) in sampling the RX line from the IMU. Have you checked for overflow or framing errors ? Is there anyway you could halve the baud rate just to see if that works ?
http://arduiniana.org/libraries/newsoftserial/
EDIT : What Arduino do you have ? The IMU is a 3.3V part. The 3.3 Arduino Pro only runs at 8 Mhz and might not work at 57k baud. The 5V Pro should run fast enough but the 3.3V levels from the IMU might not register as a logic 1 given some noise.
Thanks for the suggestion, I tried cutting down the baud rate on all devices to 19200 except the xbees because they need to be at 57600 baud to reprogram the arduno and IMU (which led me to believe that they can read that fast if that’s the speed they’re programmed at), this just gave me even a bigger mess in the serial monitor. Also I am using a 5v 16 MHz arduino pro although I’m using a 3.7v lipo battery, do you think that will make a difference? I’m pretty sure it can pull the voltage up to its operating voltage to a certain extent.
macman20:
Also I am using a 5v 16 MHz arduino pro although I’m using a 3.7v lipo battery, do you think that will make a difference? I’m pretty sure it can pull the voltage up to its operating voltage to a certain extent.
Yes I think that will make a difference. The 5V Pro needs 5V to run properly. From the product page …
We recommend running the board with a LiPo battery for better portability. You will need to use a 5v step up or DC to DC converter to get 5V from a 3.7V LiPo battery, see the related items below.
After you’ve got the voltage right, you’ll need a level shifter to communicate btw the Pro and the IMU.
http://www.sparkfun.com/products/8745
Thank you very much, I will try that, I wouldn’t have noticed that if you hadn’t pointed it out
Ok, I received my parts today and tested them out. Although they had the same effect on the NewSoftSerial library when I tried hooking the serial lines from the logic level converter to the Arduino’s hardware lines I successfully received the first 3-4 lines of transmission from the IMU consistantly, but after that it stopped transmitting. Although after I found this problem I discovered that holding down the reset button on the Arduino would allow the data to transfer continuously. This was still a problem so I hooked the CTS pin on the IMU to the reset on the Arduino, this now allows it to transmit data constantly. But obviously this is still a problem, now I can’t really do anything with my Arduino while it is running, do you know of what might be causing the problem of the data stopping after 3-4 lines?
Thanks!
Can you post a schematic or wiring diagram ?
This is my wiring schematic for the current configuration (excluding the CTS on the IMU hooked to Arduino Reset pin).
http://i.imgur.com/DrwZo.png
Note: Arduino is also hooked to XBee Explorer Regulated.
Ok, well I just tested everything with the Arduino running a completely blank sketch, my fears were confirmed. The reason I was getting the first 3-4 lines of data was because that was when the Arduino was still establishing its Serial.begin() function, then once that ran it would just block the transmission running through. I discovered this by running the blank sketch, the IMU transmits right through the Arduino with no interference when the blank sketch is running. Any suggestions on how to get the NewSoftSerial library working again?
Thanks!
First thing I see is that you’ve got the Tx HV and LV swapped. The HV pins should always be connected to the 5V Arduino, the LV pins to the IMU. I also see you’re sharing the UART on pins 0 and 1 with the IMU. Are you using the USB connection at the same time ? I thought you were using a “soft” (NSS) serial “port” to communicate w/the IMU ? Is the NSS “port” being used to comm with the XBee ? W/o seeing your code and understanding the NSS library, I can’t say if the Tx/Rx lines are correct (not swapped) for the XBee. Well, that and you don’t show them on the schematic ? And what you have shown seems different from your OP where you said …
I have my Arduino connected to an XBee on the hardware serial line communicating to my computer so I am using the new soft serial library for a second serial line. I have the TX and RX lines on the IMU hooked to pins 2 and 3 on the Arduino respectively.
Can you explain how you’re using the NSS port and XBee ? (I’m assuming this based on the schematic) I read that the NSS SW can be used for multiple instances (ports) but only when done 1 at a time. I wonder how well this SW plays with using the HW based UART on pins 0 and 1. I could envision some interrupt weirdness happening. Can I correctly assume that with your test code (that doesn’t work) there’s no data coming in to the Arduino from the (?) Xbee while you’re receiving data from the IMU ? Can you disconnect this line (Rx coming in from XBee) and pull it high just to be sure ?
BTW has the Arduino reset line been pulled high all this time, not left floating ?
EDIT : Was watching football whilst typing the above. Didn’t see your last post until now. Let me think about it.
macman20:
Ok, well I just tested everything with the Arduino running a completely blank sketch, my fears were confirmed. The reason I was getting the first 3-4 lines of data was because that was when the Arduino was still establishing its Serial.begin() function, then once that ran it would just block the transmission running through. I discovered this by running the blank sketch, the IMU transmits right through the Arduino with no interference when the blank sketch is running. Any suggestions on how to get the NewSoftSerial library working again?
Thanks!
Is your XBee connected to JP5 (com connector), the Rx and Tx pins ? Is the IMU truely connected (via level converter) to the digital 0 and 1 (Rx and Tx) pins as shown on your schematic ? If so the IMU is effectively directly connected (through 1k resistors) to the Xbee and the ATmega328. So I can see the TX out from the IMU making it to both the “Arduino” and the XBee. I’m not sure why it would go bad unless either the code redefines the RX input as some output or … as I see from the schematic … the HV and LV lines are swapped. Of course it will depend on how you’ve got the XBee Tx/Rx lines connected. Personally I think you want what you said in the OP; the XBee connected to the HW UART lines (digital 0,1 same as Rx/Tx on J5) and use the NSS SW to make another serial port on digital 2 and 3 to comm with the IMU.
Sorry for all inconsistencies, this is the setup I’m working with. (The XBee explorer is connected to an XBee)
http://i.imgur.com/GAEsX.png
Edit: Yes, the XBee is connected to the JP5 connector.
Without trying to verify that all the Tx/Rx lines are proper (so easy to get them swapped) I only see 1 odd thing about your wiring. Why do you have the 3.3 V from the XBee going to the Arduino (which I thought was the 16Mhz, 5V part) ? I don’t think this is your problem but it doesn’t look correct to me. Shouldn’t the XBee be taking in 5+ V and creating 3.3V ? I don’t know if the 5V regulator on your Arduino Pro has enough drive to supply the XBee, maybe it does, maybe it doesn’t. So I’d route the 5V raw into the XBee Vin. BTW did you read the comments on the XBee page re: voltages and level shifting ?
So is this the configuration that kinda, partly works for the 1’st few lines ? Can we assume that you have no problems downloading code to the Arduino via the XBee ? If so this would be a pretty good indication that those lines are not swapped. Since you have somehow gotten data directly from the IMU to your PC via some alternative route, we can assume that part is good and you have properly identified which lines are Tx and Rx. Is the IMU setup to automatically output data after it powers up or does the Arduino have to issue some command(s) to start the IMU data output ? So are we to understand that the NSS comm port does the communication with the IMU and further that this works for a short time and then … does what ? Sends gibberish or do you just receive nothing ? It seems odd to me that this works at all with your empty sketch … or was that a different setup ? Obviously to get data from the IMU using the NSS SW you need to have that SW running. I wonder (aloud) if trying to receive and immediately send a character, on a character by character basis, is the “right” thing to do when using NSS ? I’ll guess that NSS senses the interrupt on every bit coming in that changes state. I don’t know how long it takes (s/b short time) or what interrupts are enabled/disabled when you call for a serial write via the UART to the XBee. Could it be that this (serial.write) interferes with the IOC used by the NSS routines ? Going with that thought, it might be interesting to receive the whole message from the IMU, buffer it in the Arduino and then send it, as a burst, to the XBee. This might avoid any potential conflicts over interrupts. How often do you have the IMU sampling and sending data ? You’d have to make sure there’s enough time to fit 2 whole messages plus a bit more inbetween the sample points/data bursts.
To clear up any confusion this is the most current wiring diagram which does not allow for the first 3-4 lines to be transmitted clearly, the reason I found that the lines were being transmitted when I had the tx and rx from the IMU hooked to the Arduino’s hardware UART lines is because the Arduino wasn’t fully booted so the tx and rx were just acting like wired connections, I found this with the blank sketch.
Contrary to my cryptic wiring diagrams (sorry) the XBee is being fed the full 5V from the Arduino.
Also to clarify the correct response from the IMU is something like “!ANG:23.54,34.55,43.67” then a newline at the end with the NSS hookup (the current hookup as depicted in the schematic above) the response I get is “ANÇ1.7¶29.624.´
!AN§±29.23.
ûÿ!AN1.8±29.µ”. I also tried causing a 100ms delay from the IMU, this didn’t help.
Also the IMU just always sends data from power on, doesn’t wait for a command. So currently the XBee (on the hardware line) is only sending to my computer (although I would like to have RC to it in the future) and the NSS is only receiving from the IMU.
Edit: I’m still using the code from the first post on the Arduino, for the IMU I’m using the modified AHRS code (http://groups.google.com/group/sf_9dof_ … a4e6b010f1) that works with the most current 9DOF IMU (http://www.sparkfun.com/products/10736).
macman20:
Also to clarify the correct response from the IMU is something like “!ANG:23.54,34.55,43.67” then a newline at the end with the NSS hookup (the current hookup as depicted in the schematic above) the response I get is “ANÇ1.7¶29.624.´
!AN§±29.23.
ûÿ!AN1.8±29.µ”. I also tried causing a 100ms delay from the IMU, this didn’t help.
Excellent info, especially the above. So things are basically working but the data is getting corrupted. Seems you’re supposed to get 20 characters and I might assume 200 bytes (8N1) from the IMU every ??? msec. At 57600 that should take ~4 msec. So even at a 100 Hz sample rate, you should have time to buffer the message, even if just for debug purposes. You seem to be getting a variable number of characters, sometimes more than 20, sometimes less. While this could be reflections causing problems, my guess is that it’s oddness with interrupts. So I recommend investigating that route first.
BTW see the prior thread on NSS problems, especially note this part by coyote20000 …
viewtopic.php?f=14&t=21742
Here’s what I found so far.
When reading data using nss, you have to force the arduino to wait till all the characters are done being received.
Instead if using “if (nss.available()){}” use “while(nss.available())”. This way nss isn’t released and data isn’t lost. Using “if” will read one byte then drop out. “while” will keep the arduino working on the nss stream till it’s empty. If a byte comes in when nss isn’t monitoring, it is lost…
So again I think you should buffer the incoming data until the burst is complete and only then send it out to the XBee.
Ok, well I tried adding the while(mySerial.available) instead of if, this helped a little, I think I got a few more un-corrupt characters
“ANG:14.36¬18.19
!ANG13.9·18.4µ2.21!ANGº12.3·17.6±
!ANG13.3¸18.”
But there is still a definite problem… Also when I tried a delay in the IMU it still did the same thing just at a slower speed.
How did you “delay” the IMU ? What sample rate are you using and how would a “delay” affect that ? Did you try buffering the whole IMU message, each message, before sending it to the XBee ?
By delay I mean I put a delay(100) in just to make sure the Arduino could catch up. Also, about buffering, I haven’t yet added a buffer but I don’t quite know how to go about that or where to add it, any pointers on that? Ill try and look it up.
Thanks again for all the help!
A delay isn’t going to help and in all likelihood will hurt. As I understand it the IMU will send some 20 characters of data every some (?) msecs. That’s going to happen no matter what you do in the Arduino code. The time between these bursts of data is set by the IMU code and perhaps there’s some way to change that rate but I don’t know it (though you should if you’re going to use the IMU for your copter). My guess is the sample rate is something around 50 to 100 Hz giving you 20 to 10 msec between each burst of data. Perhaps it’s longer but I wouldn’t assume so. Do you know the IMU’s sample rate or have you measured the times between the data bursts ? In any case any delay (especially 100 msec) in reading the data from the IMU is probably not a good idea. You’ll need to read each burst of data in eventually.
Given the comments in the other thread on NSS, I’d read the entire 20 characters in, store them as a single string (perhaps) and then send that string out to the XBee. Wash, rinse, repeat for burst as it comes into the Arduino from the IMU. Given it takes ~4 msec to receive the burst from the IMU, the Arduino should have enough time to do this. Doing other processing, to stabilize your vehicle, would also have to fit in this time. The buffering code snippet in that other thread looked sufficient at 1’st glance (though I modified it to not look for the CR in your IMU data).
#define BUFF_SIZE 40
char buffer[BUFF_SIZE]; //buffer will store the IMU data from each burst as ASCII characters
void loop()
{
int i = 0;
while (mySerial.available())
{
buffer[i++] = mySerial.read(); //read in data storing it in array called buffer
if(i == BUFF_SIZE) break; //Bail! The buffer is about to explode
}
for(int j = 0 ; j < i ; j++)
{
Serial.print(buffer[j]); //send IMU data to serial port-XBee as ASCII chars after all of burst has been rcvd
}
}
I make no claims the above is good but use it as a guide to coming up with some test code to show how to read in data using NSS.
I tried the code you suggested and worked it into my little sketch and this is what I came up with:
NewSoftSerial mySerial(2, 3);
void setup() {
Serial.begin(57600);
mySerial.begin(57600);
}
void loop()
{
int i = 0;
while (mySerial.available())
{
buffer[i++] = mySerial.read(); //read in data storing it in array called buffer
if(i == BUFF_SIZE) break; //Bail! The buffer is about to explode
}
for(int j = 0 ; j < i ; j++)
{
Serial.print(buffer[j]); //send IMU data to serial port-XBee as ASCII chars after all of burst has been rcvd
}
}
The first time I ran it the first 1.9 messages came through fine although I played around with it for a while to no avail and then changed it back to its original setup but never got the same results again. These are the results I’m now getting in “bursts”:
“!ANÇ26.717.641.4
!ANG26.7°17.641.4
!ANG:26.74¬17.65¬41.4²!ANG”
Do you think I should add a 1 or 2 msec delay between chars sent from the IMU?
Thanks.