5 years, 9 months ago.

Write int32_t data vector to serial

Hi to everyone. The problem is: I have an IKSa02 expansion board from which I get, through a Nucleo L152RE, accelerometers and gyro data. I would to send those data through a serial port (RS 232) to a PC in order to make acquisition with a program written in VisualBasic (this program gets the data from the serial port and creates a file .bin that I will process later). Now, the data acquired with the L152RE are int32_t, while with the command putc() I can write on the serial a char. My first question is: how can I write an int32_t data into a serial port? I have made a code if anyone wanted to look at it. The structure of the code is: 1) I put all the data from sensors into a vector called "data_vect", which first element is a fixed data called "a"; 2) I send each element of data_vect through the command putc(). I want to know if this approach is correct. I will be grateful for each answer. Thank you.

#include "mbed.h"
#include "XNucleoIKS01A2.h"


static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;

Serial device(PA_2, PA_3, 115200);

Timer t; 

int main(){
    
    device.format(8,SerialBase::None,1); 

    accelerometer->enable();
    acc_gyro->enable_g();
    
    int32_t acc_data[3];
    int32_t gyro_data[3];
    int32_t t_sample; 
    int32_t data_vect[8];
    int32_t a = 123456789; 
    int i; 
    char *bytePtr;
    int x; 
    
    
    while(1) {
        accelerometer->get_x_axes(acc_data);
        acc_gyro->get_g_axes(gyro_data);
        t_sample = t.read_us();
        
        for(i=0; i<8; i++){
            if(i==0){
                data_vect[i] = a;            //Dato tipo "start bit" 
                }
            
            if(1<=i<=3){
                      data_vect[i] = acc_data[i-3];
                }
            if(4<=i<=6){
                      data_vect[i] = gyro_data[i-4];
                }    
            if(i==7){
                      data_vect[i] = t_sample;    
                }
         } 
        
        for(i=0;i<8;i++){
            bytePtr = (char *)&data_vect[i]; 
            for(x=0;x<sizeof(data_vect[i]);x++){
                device.putc(*(bytePtr++));
                }
            }
            
            
    }//end while
}//end main

Hello Nikolaos,

After taking a closer look at your code I think there is an issue with array index.

Rather than

// ...
        if(1<=i<=3){
            data_vect[i] = acc_data[i-3];  // when i == 1 or 2 then [i - 3] becomes negative
        } 
// ...

try

// ...
        if(1<=i<=3){
            data_vect[i] = acc_data[i-1]; 
        } 
// ...
posted by Zoltan Hudak 19 Jul 2018

It seems that there is more to fix. Also the expressions below won't work correctly.

/..

if(1<=i<=3) {

/..

if(4<=i<=8) {

/..

So I would suggest to rewrite the for loop as follows:

//...

        for (i = 0; i < 8; i++)
        {
            if (i == 0)
            {
                data_vect[i] = a;   //Dato tipo "start bit"
                continue;
            }

            if ((1 <= i) && (i <= 3))
            {
                data_vect[i] = acc_data[i - 1];
                continue;
            }

            if ((4 <= i) && (i <= 6))
            {
                data_vect[i] = gyro_data[i - 4];
                continue;
            }

            if (i == 7)
            {
                data_vect[i] = t_sample;
            }
        }

        uint8_t bytes[sizeof(int32_t)];

        for (i = 0; i < 8; i++)
        {
            *(int32_t*)bytes = data_vect[i];

            for (uint8_t j = 0; j < sizeof(int32_t); j++)
                device.putc(bytes[j]);
        }

//...
posted by Zoltan Hudak 19 Jul 2018

Thank you very much! Now it's working properly! I have no words for your help. I am so grateful! May you have a good day.

Best regards, Nikolaos

posted by Nikolaos Dedes 20 Jul 2018

2 Answers

5 years, 9 months ago.

Hello Nikolaos,

I think that your approach to convert the int32_t data items to bytes (uint8_t, unsigned char or char), transmit those bytes over serial link and then convert the received bytes back to int32_t is correct.

  • You should also take into account the endianness. Maybe you have to shuffle the order of bytes (either on the transmitter or receiver side) before converting them back to uint32_t to get correct values.

Accepted Answer

Thank you for the reply, but it doesn't work. I don't know why, but the data sent on the Serial port are wrong: it's not and endiannes problem. I imagine is a problem of putc() but I don't know what the problem is. What about the "write" command? I cannot understand how to use it; do you have any experience?

posted by Nikolaos Dedes 19 Jul 2018
5 years, 9 months ago.

Generally the code looks ok. I would have used a switch/case statement block instead of all the "if(1<=i<=3)" constructs.

But something looks fishy to me

device.putc(*(bytePtr++));

Normally I would write that

device.putc(*bytePtr++);

So that there is no chance that the compiler will increment before the indirect lookup. Your compiler may generate identical results but I suspect it's pre-incrementing....

Bill

Thank you for the reply, but as I mentioned to the Zoltan's answer, it seems that the serial port send wrong data and i don't know why: i've tryed also with your trick but the result is the same. It's like something was wrong with the serial port RS232. For example: if i send

device.putc('a'); 

on the USB port (STM-link) it looks ok and the terminal shows me the character 'a'. But if I select the RS232 port on the terminal, it does not appear the character 'a', but strange characters.

posted by Nikolaos Dedes 19 Jul 2018