Problem parsing an IMU device

12 Jul 2012

Hi there everyone,

Im just developing the comunication code for my quadcopter, and I need to parse the out of the imu, that is like that:

!!!AN0:-4,AN1:19,AN2:2,AN3:-2,AN4:29,AN5:100,RLL:-0.08,PCH:0.38,YAW:0.04,*

And I though in that code:

#include "mbed.h"
Serial imu(p9, p10);
int an0, an1, an2, an3, an4, an5, rll, pch, yaw = 0;


Serial pc(USBTX, USBRX);

int main() {
    imu.baud(38400);
    pc.printf("Result of YAW:");
    while(true) {
        
        imu.scanf("!!!AN0:.*,AN1:.*,AN2:.*,AN3:.*,AN4:.*,AN5:.*,RLL:.*,PCH:.*,YAW:.*,***", &an0, &an1, &an2, &an3, &an4, &an5, &rll, &pch, &yaw);
       
        pc.putc(yaw);
        wait(200);
    }
}

And I only receive the "Result of the YAW" in the hyperterminal In my PC. Any idea about how to solve this? After hours I can't the error to fix at the moment :S

Thank for your attention ;)

14 Jul 2012

The format specifiers don't look right to me, shouldn't it be %d for the integers AN0-5. I think roll,pitch,yaw might have to be read as floating point.

15 Jul 2012

 #include "mbed.h"
Serial imu(p9, p10);
int an0, an1, an2, an3, an4, an5 = 0;
float rll, pch, yaw = 0;


Serial pc(USBTX, USBRX);

int main() {
    imu.baud(38400);
    pc.printf("Hola");
    while(true) {
        if(imu.readable()) {    
            imu.scanf("!!!AN0:%d,AN1:%d,AN2:%d,AN3:%d,AN4:%d,AN5:%d,RLL:%f,PCH:%f,YAW:%f,***", &an0, &an1, &an2, &an3, &an4, &an5, &rll, &pch, &yaw);
        }
            pc.printf("Yaw: %f", &yaw);
            wait(200);
    }
}

That was the right way? I changed the int type of rll pch and yaw by an float. Are the regexp correct? I changed too the type of the data collected, what you think?

Thanks for your time.

16 Jul 2012

Well that looks more like the way scanf was described when I tried to look it up. As far as I'm aware the template for scanf doesn't use "regular expression" syntax, and as a result it is only usefull where the data format is well known in advance (e.g. this case).

I would hope that the version with the %d and %f specifiers might work, otherwise you might have to resort to pulling it in character-by-character and parsing it yourself, or maybe someone has made a regex library and you can use that instead?

Assuming the "*" character isn't special and is matched as-is you would only want one star at the end to match the trailing star of the readout string.

Incidentally it might be a good idea to make a sample file of data and send it via usbtx, just in case your program is working perfectly but the communications are getting garbled for other reasons, for example some form of buffer overflow.

18 Jul 2012

How I can pull it character-by-character? Modifying the output code of the imu?

18 Jul 2012

You can read the chars one by one using the imu.getc() method. Note that you have to take care that the chars are read fast enough to avoid losing characters because the transmitter doesnt wait. The pc.printf() and the wait(200) will cause delays and result in problems when the transmitter is sending at high update rates.

The scanf should work also but is sensitive to any errors or unexpected characters in the format string. The format has to be an exact match with the received data or scanf() will fail and abort. Your example suggests that it should look like this:

imu.scanf("!!!AN0:%d,AN1:%d,AN2:%d,AN3:%d,AN4:%d,AN5:%d,RLL:%f,PCH:%f,YAW:%f,*", &an0, &an1, &an2, &an3, &an4, &an5, &rll, &pch, &yaw);

you may have to add a newline (\n) and/or carriage return (\r) at the end.

note that the printf is wrong. It should be

pc.printf("Yaw: %f", yaw);

instead of

pc.printf("Yaw: %f", &yaw);