Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 8 months ago.
Serial communication with matlab
Hello guys!
Now I've tried to communicate with Matlab and it has been okay so far, but one problem suddenly happened..
I'm using LPC1768 and I send the data every 1ms to Matlab by using printf.
I think printf is too slow to send all data which I want to get and I don't know which function should I use in order to send all data. ( Now when I put complex code in printf then values are delayed like 5ms or even 10ms.)
Therefore, which function should I use instead of printf?
Thanks!
void interrupt() { i++; SEND_FLAG = 1; } int main() { timer.start(); pc.baud(115200); flipper1.attach(&interrupt,dt); // PWM.period(.00005);//Set PWM frequency. VNH5019 h-bridge limited 20 kHz (.00005 seconds) while (1){ // exit when the file is closed. enc = wheel.getPulses(); NewTheta = pulsesToRadians(wheel.getPulses()); ThetaDesire = (i/500) * 2*pi; dTheta = (NewTheta - OldTheta) / dt ; Torque = (1/(pi/2))*(ThetaDesire - NewTheta) + 0*(0 - dTheta); if (Torque > 1) { Torque = 1; } if (Torque < -1) { Torque = -1; } signal_to_hbridge(Torque); if(SEND_FLAG == 1) { pc.printf("%f,%F,%F,%.f,%f \r\n",i ,pulsesToRadians(enc)/(2*pi), pulsesToRadians(enc), Torque * 100, ThetaDesire); SEND_FLAG = 0; } // OldTheta = NewTheta; } }
1 Answer
9 years, 8 months ago.
The bottleneck isn't printf, it's the RS232 link.
You are running the serial port at 115200 baud. For RS232 each byte of data takes 10 symbols (assuming 1 stop bit). That means in 1ms you can send a total of (115200/10)/1000 bytes = 11.52 bytes.
Typically printf("%f",number) will output around 8 digits. You are outputting 5 numbers so call it 40 bytes of data. That's going to take around 4ms to send.
You can run the serial link at least 4 times faster, possibly 8 assuming the UART on the PC and matlab can cope with it. If you limit the number of significant digits or decimal places for the output to the resolution you need then you may be able to shorten your message a bit.
After that you have to either fall back to transferring the data in binary (4 bytes per float), run two serial ports in parallel (use something like MODSERIAL so printf doesn't block), or decrease your update rate.
I just looked at your code in more detail. You could speed it up a bit very easily.
remove the line enc = wheel.getPulses(); and then in the printf use NewTheta rather than pulsesToRadians(enc). That saves doing the same calculation 3 times and also eliminated potentially using two different values from the two readings of the wheel. And then you are sending the same value twice, once divided by 2 pi and once not. Only send it once and do the maths at the other end, that reduces your data by 20%. You are sending i which is presumably an integer as a float. Send it as an integer. ThetaDesire is calculated from i. If you are sending i then there is no need to send that.
So that's a 40% reduction in the amount of data you need to send. Not enough to get you up to 1kHz on it's own but a big help.
posted by 11 Dec 2015Thank you for answer Andy! You are right. when I run this code and measure the values every 5ms, I can get all values I want.... Maybe I think the only way I should do is to use the UART on the PC... That fact makes me frustrating... Anyway thank you for helping me and your new code is awesome! thank you bro!.
posted by 14 Dec 2015