Any better idea for sending floats over serial connection?

Hi there,

Do you have any idea to make data transmission faster?

I’m trying to send some float data from F446RE Nucleo to my PC via USB connection.
On the PC end, I’m running real-time data acquisition. That being said, I want this data transmission to be fast.

I’m using C union. But I cannot get rid of printfs.

This is my code, and it works. But I’m glad to hear better ideas.

typedef union _data {
    float f;
    char  s[4];
} myData;

myData  dat1;
myData  dat2;
myData  dat3;
myData  dat4;
...

void main() {
	...

	while(1) {
        //"putting motor position into data package."
        dat1.f = motors[0].state.position; 
        dat2.f = motors[0].control.p_des;
        dat3.f = motors[1].state.position;
        dat4.f = motors[1].control.p_des;
        
       //"break down data, then send to PC"
        pc.printf("%c%c%c%c", dat1.s[0], dat1.s[1], dat1.s[2], dat1.s[3]);
        pc.printf("%c%c%c%c", dat2.s[0], dat2.s[1], dat2.s[2], dat2.s[3]);
        pc.printf("%c%c%c%c", dat3.s[0], dat3.s[1], dat3.s[2], dat3.s[3]);
        pc.printf("%c%c%c%c", dat4.s[0], dat4.s[1], dat4.s[2], dat4.s[3]);
			
    newprint = 0;
	}
}

Thanks, in advance :slight_smile:

In terms of total data transmitted I can’t think of any easy way to reduce the size. If anything you’re transmitting too little since I don’t see any headers or other markers that would allow the PC and mbed to sync up if they are started in the wrong sequence or the connection is temporarily broken.

You say you can’t get rid of the printfs. Why not? What’s wrong with:

void sendData(myData value) {
  for (int i=0;i<4;i++)
    pc.putc(value.s[i]);
  }

or without the unions

void sendFloat(float value) {
  for (int i=0;i<4;i++)
    pc.putc(  *(((char*)&value)+i) );
}

void main() {
   ...
   while (1) {
     sendFloat(motors[0].state.position);
     sendFloat(motors[0].control.p_des);
     ...
   }
}

But that’s not going to speed up the transmission, it’s just a cleaner way to do it. printf is a lot slower than putc but the serial data rate is so much lower that it won’t make any difference in how fast the data comes out.

To actually speed the data up you either need to increase the baud rate (if you’re using USB then 921600 baud should work without any issues) or reduce the data you’re sending.
If you know the range of possible values for your data and the required resolution then you may be able to use a 16 or 24 bit scaled integer value rather than a floating point value and so reduce the amount of data you need to send that way…

1 Like

Thanks for the through explanations. I couldn’t use putc just because I was using wrong syntax.

Now as my baud rate is maxed out, I would try reducing the size of data being transfered.

Btw, if you know a good DAQ running on Windows, please let me know. My python based code won’t speed up more than 40 Hz. Data reading and plotting are designed to run on different thread, but can’t figure out which one is the bottleneck.

Python can be painfully slow at times. Personally I’d fall back to a c# application for high speed data acquisition on windows. I’ve had a multi threaded python app that was mostly using numpy (so compiled c code under the hood) that I converted to a single threaded c# application, the new version ran over 50x faster without even trying to optimize it.

But if you don’t know c# that may not be an option,

1 Like