Converting sensor text output to a number

Hey guys,

I recently got the Razor 9DOF freedom sensor running with the AHRS firmware.
The guide I followed is here (https://dev.qu.tu-berlin.de/projects/sf-razor-9dof-ahrs/wiki/Tutorial)


As is shown in the image above the output is a text string containing angles for roll pitch and yaw.

I am reading these into my UNO but I need a method to extract the angles and convert them to numbers.

I have previously done this using the substring and toInt commands.
However, here the length of the string changes dynamically depending on the value of the angle so substring wont work for me. If the angle goes from 10 to 100 for example then incorrect values will be read in through substring.

I'm hoping someone here can show me another method whereby I can convert each of the roll pitch and yaw value to numbers and store them.
Thanks

You can use the strtok() function to split your string into sections and perform magic on each section...

Converting a text representation of a float into a float would normally be done with atof().

Easy enough :wink: No need to buffer anything (or worse; buffering into String ) Assuming you know how to handle the serial port, in your loop do:
() If initialise flag is true, zero your 3 number variables Y, P and R. Note that we need to do "Y". Rest all countrs /flags.
() Read the next byte until you get past the #YPR (basically anything that is a letter or '=' is discarded)
() When you get a valid digit, put it into the appropiate Y P or R variable, first multiplying previous content by 10. Basically this converts ASCII to int, one char at a time, as they arrive. .
() If you see a decimal point start counting in a seperate variable. Everytime you add a digit in above step, count one if we started counting. If you see a "-" just note this in another boolean variable
() When you see a "," or "\n" the number is done. Move on the next in the Y P R pointer. When done all 3, you're done!

Draw backs - the code will not fail if the number is badly formatted (like two decimal poins) but return some (unpredictable) result. I have used above algorithm in my "nnnC" function published as a post (Search for "nnnC"), yours just needs to do 3 numbers.

Hello, I think it will be easier to do it by using sscanf, after reading a whole line from Serial (when you reach an EOL character) :slight_smile:

Like in this example: C++ code - 9 lines - codepad

guix:
Hello, I think it will be easier to do it by using sscanf, after reading a whole line from Serial (when you reach an EOL character) :slight_smile:

Like in this example: C++ code - 9 lines - codepad

Arduino sscanf() has float support?!

Ff sprintf() doesn't, I doubt sscanf() does, does it?

I forgot about this... so install floating point support, or use something like this C++ code - 9 lines - codepad :slight_smile:

guix:
I forgot about this... so install floating point support, or use something like this C++ code - 9 lines - codepad :slight_smile:

You do know you can (and should) put code in the forum here? Use the code tags. Then we can see the code without having to go to another website.

Sure, just show me how to compile and run code with the code tags, because I like writing working examples with immediate output :slight_smile:

guix:
Sure, just show me how to compile and run code with the code tags, because I like writing working examples with immediate output :slight_smile:

I open a terminal (ctrl-alt-t on my machine), use vi to edit my perennial "t.c" file that I use as a scratchpad, then compile it with "cc -o t t.c" and test it with "./t"

Or, if I happen to have the Arduino IDE open, then I just throw my ideas into that and press "verify" if I don't need to worry about the output of it and just want to confirm the syntax before looking a fool by posting (as I have before) badly formatted code.

Thanks for the replies everyone, lots of good ideas
However, unfortunately I have been unable to try them because I am having trouble reading in and storing the serial data from the 9DOF.

I have used the sketch below, which works for reading in commands I send over Xbee (via HW serial) but not in this case

#include <SoftwareSerial.h>

SoftwareSerial razor(2, 3);  //RX, TX

char buffer[64];
int index = 0;

String command;
char n;

void setup()  {
  Serial.begin(57600);
  Serial.println("9dofoutput");
  
  razor.begin(57600);
}

  void readSerial() {
    if(razor.available() > 0) {
      char n = razor.read();
      if(n == '#') {
        handleCommand(String(buffer));
        index = 0;
        for(int i=0; i<64;i++)
        {
        buffer[i]='\0';
        }
      } else {
        buffer[index++] = n;
      }
    }
  }

    void loop() {
    
    readSerial();

      }
  void handleCommand(String command) {    
        Serial.print("Angles: ");
        Serial.println(command);
  }

This is the output I am getting

Looking at the AHRS code that is on the sensor board, I have seen how it creates the output.

  else if (output_format == OUTPUT__FORMAT_TEXT)
  {
    Serial.print("#YPR=");
    Serial.print(TO_DEG(yaw)); Serial.print(",");
    Serial.print(TO_DEG(pitch)); Serial.print(",");
    Serial.print(TO_DEG(roll)); Serial.print("x"); Serial.println();
  }
}

It seems the error is occurring due to the format in which data is sent out by the board,i.e. a mix of Strings and the actual angles which are floats
Any ideas on how I could read this in correctly to my board, or just the floats as that's really what I\m after, I'm hitting a wall

Much appreciated,
Thanks

        handleCommand(String(buffer));

Making the handleCommand() function take the proper argument type (hint: it is NOT String) would be a start.

Putting each { on a new line, and using Tools + Auto Format (along

with reasonable amounts of white space)

would make your code more readable.

Checking that you don't overflow buffer would be a good idea, too.