Using values from 9DOF Razor in Arduino Mega

I hope someone can help, I am a bit of a novice with this stuff.

We are currently in the middle of a project and are using the Sparkfun Razor 9DOF IMU to calculate angles of rotation. The plan is for these angles in the X, Y, Z directions to be used to fire motors, sort of an attitude correction system.

We have used the code availible from the link on the sparkfun website that from what I see is commonly used, this is programmed on the Razor, at this stage we are now reading this angle data through the serial monitor on the arduino in the form given by that code of:

ANG! 20.00, 30.00, 10.00 (where 20, 30, 10 etc are example angles)

My question, which may make me sound very simplistic I am aware, is how we get the arduino board to recognise these angles so that we can apply conditions that will start or stop the motors, e.g if the angle in the x axis (in this example 20.00) is greater than 10 degrees turn on pin 1 and 2 etc. Is there a way for the arduino to recognise these values independently, knowing that one will be for pitch, one for roll and one for yaw.

Any help would be greatly appreciated.

Chris

I think you could connect the Mega and the Razor through their serial connections (RX<->TX, TX<->RX) and then on the Arduino you have to read the data coming from the Razor, parsing them into yaw, pitch, roll.

Thanks for the reply.

Yeh I have got that far, I created just a simple read program that is displaying the serial data in the form shown previously. My problem is that I am a complete novice to this, how do I go about getting the arduino to recognize the data as three seperate things that I can then use.

Chris

You should code on the Arduino using Serial.read() (check documentation http://www.arduino.cc/en/Serial/Read and the example there).

Supposing you are receiving a line like:

ANG! 20.00, 30.00, 10.00

Then I would do something like:

void loop() {

	// send data only when you receive data:
	if (Serial.available() > 0) {
		// skip "ANG! "
		Serial.read(); Serial.read(); Serial.read(); Serial.read(); Serial.read();
                // read the first decimal number
                int val = Serial.read() - '0';
                val = val * 10 + (Serial.read() - '0');
                // in val you have now the read value for the integer part

                // skip the dot
                Serial.read();
                
                int val2 = Serial.read() - '0';
                val2 = val2 * 10 + (Serial.read() - '0');

                float finalval = (float) val + ((float) val2 / 100.0);
		
                // say what you got:
		Serial.print("I received: ");
		Serial.println(finalval);
                
                // TODO: repeat the above for the remaining 2 angles.
	}
}

Not tested but should give you an idea.

Thats excellent, thanks. I'll go forward with that and see how I get on.

Good, keep us posted. Note that the above is not copy and paste ready code.. you should adapt it.

In the first serial.read() for the first integer. Why has the value been multiplied by 10

void loop() {

    // send data only when you receive data:
    if (Serial.available() > 0) {
        // skip "ANG! "
        Serial.read(); Serial.read(); Serial.read(); Serial.read(); Serial.read();
                // read the first decimal number
                int val = Serial.read() - '0';
                val = val * 10 + (Serial.read() - '0');
                // in val you have now the read value for the integer part
val = val * 10 + (Serial.read() - '0');

"15" -> ('1' - '0') * 10 + '5' - '0' "125" -> ('1' - '0') * 100 + ('2' - '0') * 10 + '5' - '0'

Right, makes sense, you have to work in tens hundreds etc within arduino. I guess this is why you have divided by 100 when adding the float values

When doing this for the other angles also, do I just include

Serial,read(); Serial.read();

to eliminate the comma and space that seperates each value?

Only if you are certain that there are two characters in the serial buffer when you call Read".

Yes there are it is exactly in the form I showed you at the start. When using Serial. read() does this read each digit in the line of data consecutively?

Another question I had was about your use of - '0' after the number.

Is this only the case in the example I have shown where the numbers are whole values e.g 20.00 instead of 18.54, or is this just used as a 0 always?

Yes there are it is exactly in the form I showed you at the start

That's not what I asked you.

At the point when you call "Serial.read" twice, are you sure that there are two characters already received that you want to ditch?

If there is only one, the first read will return the character, and the second will return -1.

You should always make sure (using the "available" method) that there are sufficient characters in the buffer before you call "read".

Another question I had was about your use of - '0' after the number

Are you confusing me with someone else? Normally "- '0'" is used to convert an ASCII numeric character like '2' to its decimal value 2.

Is it not a similar case to earlier in the code when there has been 5 Serial.read function being used to omit !ANG

if (Serial.available() > 0) {
        // skip "ANG! "
        Serial.read(); Serial.read(); Serial.read(); Serial.read(); Serial.read();

So, you call "Serial.available" and say it returns 1. What happens then?

The input is always going to be in the form shown at the start of the post, but I understand what you mean. The input is coming from an accelerometer assembly that has its own IMU and is processing this data and sending it in that form.

However I understand what you are saying in that say for my purpose the angle goes above 100 degrees, there is now another character to deal with, similarly with negative values, as there can be a negative sign in front of the angle.

Do you know of any other way to get around this, sorry if it may seem simplistic as I say I am a novice to the system

You can either call Serial.available before you read every character, and check that the return value is non-zero, or you can call it once to see if there are enough characters present to process the whole message. Or you can call "read" repeatedly and dump any -1 values that it returns. http://arduino.cc/en/Serial/Read http://arduino.cc/en/Serial/Available

To be fair, he did say:

Not tested but should give you an idea.

if (Serial.available() > 0) {

Yeah, this can fail miserably.. it should check for the whole data line length.. remember to insert also the \r and \n which you can't see but they are transmitted.

I have made a change to the code on the Razor IMU that will now add 360 to each of the values of the angles. This means that it will never be less or more than three digits and will never be negative so don't have to worry about them. That's what I am going forward with at the moment.

What does the \r and \n do what do they represent

What does the \r and \n do what do they represent

Carriage return and newline codes.

0x0d and 0x0a