Reading Serial Data from Accelerometer

Hi all!

I've been working with Arduino for the past few months on a university project to control a 8 motor UAV - going ok so far, well, I've still got all my fingers!

I have been trying to get data from a different accelerometer/gyro board - it's an Atomic 6DOF IMU.
The data comes out in serial form so I am connecting the voltage and ground as normal to the pins of my Arduino MEGA.

Now, I'm connecting the TX pin on the accelerometer to the RX0 pin on my Arduino.

My code is as follows:
/*

  • This is the code to read the IMU serial data from RX0 in the Arduino MEGA

*/

void setup()
{
Serial.begin(115200); // set up the Serial library at 115200 bps
Serial.println("Beginning Stream"); //prints and line breaks
}

void loop()
{
// read the value
int sensorValue = Serial.read();
Serial.print(sensorValue);
Serial.println();
delay(10);
}

I'm having a LOT of problems with this.
First off, it won't print anything at all on the serial monitor if I keep the line Serial.println(); The only way I can get it to show anything is by keeping the delay so short (the accelerometer has a refresh rate of 50Hz) and by leaving out the blank line between readings.
This is less than ideal since I would like to distinguish between the differen axis readings! Using Serial.println(sensorValue) does not print anything in the serial monitor.
I have to use a high baud rate since the accelerometer is configured for this for Bluetooth and I would like to not mess with this unless needed. My COM port is configured for 115200 through Microsoft Device Manager.

Can someone please help me to read the serial string from the board and then put it into the serial monitor, then go on to the next line for the next reading.

Thanks a bundle!

Aryeh

I'm confused (easily done!)

are you using D0 and D1 to talk to the accelerometer?
or to talk to the serial monitor?

(please tell me not both!!)

int sensorValue = Serial.read();
    Serial.print(sensorValue);
    Serial.println();
  delay(10);
 }

You're not waiting for serial data to become available, reading the data that may or may not be there, then you're printing it, then wasting enough time (10ms) to transmit 115 characters.
What's wrong with "Serial.println (sensorValue);" anyway?

You may want to give this a read:

Thanks for those replies.

I'm getting the data from the accelerometer and trying to pass it to the serial monitor. I don't want to send anything to the accelerometer (yet!).
When I use "Serial.println(sensorValue);" the serial monitor doesn't show anything! Not even the stuff in the void.setup(). I don't know why it doesn't......

With regards to the short delay, if I make it larger than 10ms nothing will show up in the serial monitor. Ideally I want to sample a few times per second (I'm doing measurements in an aerobatic aircraft) at anything up to about 10Hz so would want the delay to be 100 in any event.

Thanks for pointing me towards that resource.

Any more help will be really appreciated

Aryeh

RX0 and TX0 on the Mega (on all the Arduinos really), is tied to the PC through the USB port. You can't use that port to communicate with multiple devices. On the UNO, it's a choice between what you use your one serial port for, but you don't have that limitation with the Mega, since it has four separate serial ports.

Tie your accelerometer into one of the other serial ports. With the Mega, you have the following Serial devices available for usage in your sketches:

Serial
Serial1
Serial2
Serial3

Leave Serial as your port to communicate with the PC with, since it's hardwired for that. The RX/TX pins for the other ports are listed on the Mega's spec page here: http://arduino.cc/en/Main/ArduinoBoardMega2560

So what I should do is to bring in the data over Serial1 and send to Serial like this?

void loop()
{
int sensorValue = Serial1.read();
Serial.print(sensorValue);
Serial.println();
delay(200);
}

This has delayed the readings and the serial monitor is now showing the welcome message from the void setup part.

However, it now prints
"Beginning Stream"
-1
-1
-1
-1
-1
-1
-1
etc....

Any ideas? Is this to do with the accelerometer board baud rate not being the same as the Arduino?

Thanks a lot,
Aryeh

So what I should do is to bring in the data over Serial1 and send to Serial like this?

Wouldn't it have been faster to try that on the Arduino? Post on the forum and wait for an answer, or upload to the Arduino and observe first-hand the results. Which will general be faster? Which will be remembered longer?

But, the answer to the question is yes.

PaulS, yep, I've done it with my hardware and the results are in the post above....
just get lots of -1s :~

Well, you should not read anything from the serial port without checking that there is data to read.

void loop()
{
  if(Serial1.available() > 0)
  {
     int sensorValue = Serial1.read();
     Serial.print(sensorValue);
     Serial.println();
     delay(200);
  }
}

read() returns a -1 when there's no data available to read, so your output indicates that there's no data available to read.

However, it isn't going to be as simple as just checking if data is available with available(). Read my guide on Serial comms, it specifically explains how to read data from an IMU. It isn't nearly as simple as just reading an incoming byte and assigning it to an int.

You also need to read the datasheet for that Atomic IMU. It needs to be configured properly to use it, and by default it is not running (it also has a binary and ASCII mode, and by default is in binary mode as well) Your sketch needs to put it in the appropriate mode and set it to run before you will receive any data from it.

Read my guide on Serial comms

Is there any way that this could be linked to from the Serial reference page? Or added to the playground?

I initially wanted to add that guide to the Playground, but I was unable to create an account on the Playground. The page to create an account for me doesn't provide a form to fill out. I just get:

(:registerform:)

I've tried it using Firefox, Chrome, and I even resorted to IE as a last ditch effort.

Nevermind. I just realized it uses the same account as the forums.

Thanks everyone for their input.
I've set up the Atomic IMU through it's own configurator running a C program.
I've redone the code and now it looks like this:

void setup()
{
Serial.begin(115200); // set up the Serial library at 115200 bps
Serial1.begin(115200);
Serial.println("Beginning Stream"); //prints and line breaks
}

void loop()
{
int data[30];
// Find header
while (1) {
int myHeader = Serial1.read();
if (myHeader == 65) {
Serial.println("I found the header");
for (int i = 0; i<35; i++) {
data = Serial1.read();

  • Serial1.println();*
    _ if (data == 90) {_
    * Serial.print("I found the footer. Message is this long:");*
    * Serial.println(i);*

* for (int j = 0; j<i; j++) {*
* Serial.print(data[j]);*
* Serial.print(",");*
* }*
* Serial.println(); *
* break;*
* }*
* }*
* }*
* }*

* // read the value*
* for (int i = 0; i<7; i++) {*
_ data = Serial1.read(); // Connected to pin 19
* }
Serial.println("I've got a new packet!");
for (int i = 0; i<16; i++) {
Serial.print(data);
Serial.print(",");
}
Serial.println();*_

}
The section before the break ensures that there is data to send - the part after the break was written as a test to check that data was being sent.
Thanks again
Aryeh

if (myHeader == 65) {
      Serial.println("I found the header");
      for (int i = 0; i<35; i++) {
        data = Serial1.read();

How do you know that there is data there to read?
Are you just relying on the delay caused by the println?

Oh, the data stream is always prefaced by an ASCII 'A' character which is 65 and ended by a 'Z' character

Oh, the data stream is always prefaced by an ASCII 'A' character which is 65 and ended by a 'Z' character

So, why not write if (myHeader == 'A') ?
Isn't that easier to read when you don't have an ASCII table to hand?
You're still not checking to see if those 35 characters have arrived yet.

Hi everyone,

Well, I've been going through JHaskell's blog page on serial data and understand what is going on (I think).
I have a code that checks to see when an 'A' is broadcast and then it records into the buffer until a 'Z' is sent which is the end of the packet of data.

I then have to send the data through some sort of parsing to get it in the form I want....

I am having a problem with his suggested code using this format:

//My part
//
void setup(){
Serial.begin(115200); // This is the port to the PC
Serial1.begin(115200); // This is the data coming in from the IMU
Serial.println("Beginning Stream");

char startChar = 'A'; // This is the start of the data packet
char endChar = 'Z'; // This is the end of the data packet
}
//
//This is the part from JHaskell
//
void loop(){ // Aryeh : Added by me
while(Serial.available()>0){
char incomingbyte = Serial1.read(); // Aryeh : Changed to Serial1 since I'm reading the IMU readings
if(incomingbyte==startChar){
dataBufferIndex = 0; //Initialize our dataBufferIndex variable
storeString = true;
}
if(storeString){
//Let's check our index here, and abort if we're outside our buffer size
//We use our define here so our buffer size can be easily modified
if(dataBufferIndex==DATABUFFERSIZE){
//Oops, our index is pointing to an array element outside our buffer.
dataBufferIndex = 0;
break;
}
if(incomingbyte==endChar){
//Our data string is complete. Parse it here
storeString = false;
}
else{
dataBuffer[dataBufferIndex++] = incomingbyte;
dataBuffer[dataBufferIndex] = 0; //null terminate the C string
}
}
}
}

Where do I define buffer and index?
Have I got the correct place to define startChar and endChar? Are they int, char, etc? The program complains that databufferindex is not declared......
Once there is a full data packet and I'm ready to parse it, can I just send it to a text file once the storeString =false has been done?
Thanks again
Aryeh

while(Serial.available()>0){
    char incomingbyte = Serial1.read();

You're checking that there is data available on one interface, then reading data from another unrelated interface.

When posting code, please use the # icon on the editor's toolbar.