Multi Threads operation SERIAL PORT in Parallel

14 views (last 30 days)
valio
valio on 26 May 2020
Commented: valio on 29 May 2020
Hi guys,
I hope you're all safe and healthy during this period.
I have something to ask you. I need to open two serialport objects in order to communicate with 2 Arduinos. One of that has to send me Data every 10 ms (100Hz) and the other one each 100us (10KHz). These data reiceved have to be synchronize. I wouldn't like to use 2 PCs and I'd like to know if there's some way to read data in this way.
So basically 2 obj and 2 Arduino to read at the same moment. I need to do post analysis and they need to be sync.
Thanks a lot, your help will be really appreciated.

Answers (2)

Walter Roberson
Walter Roberson on 27 May 2020
That cannot be done with asynchronous serial ports such as RS232 and USB. In order to synchronize reception of data, you need to use synchronous data ports such as Bisynch https://en.wikipedia.org/wiki/Binary_Synchronous_Communications
But supposing you had synchronous data ports, and supposing you had a hardware trigger such as Genlock and suppose it was sourced "exactly" half-way between the two arduino so that they could be fired at "exactly" the same time to send the signal out over the synchronous data connection.
Supposing you had those things: you will still have the problem that the receiving processes are going to react a different speeds. That is true even if you have used your operating system to pin each process to a different processor that has its own interrupt subsystem so that they can react at the same speed (and you have no hope if you have not taken that step.)
Really synchronizing events between processes is difficult to do on a general purpose operating system. If you really need to synchronize then you should not be using standard MATLAB to run the tasks -- you should be using a real-time operating system, perhaps programmed using Simulink Real-Time. Which runs on dedicated hardware.
A lot of the time, it turns out that you do not need to get two sources at the same time: that instead, you need to get from them within a particular non-zero time window of each other. Depending on the time window sometimes it is not especially difficult to do.
And a lot of the time, it turns out that what you need is not really that you get the sources at the same time, but rather that you timestamp when you got the samples, that by knowing when things were happening, you can make appropriate predictions.
If you have a situation where the inputs from the arduinos are being used to calculate thrust for multiple rocket motor and so it is vital that the relative timings of the actions be known, then (A) MATLAB is not certified for that kind of work! and (B) you need real-time computing, not a general purpose system like MATLAB.

valio
valio on 27 May 2020
Hi,
thanks for your response. I'll try to explain better my application.
Basically I'll have two Arduinos: one that sends IMU data each 10 ms, then 100 Hz; and the other one that sends EMG Data at 10 KHz (or maybe 1KHz should be fine enough).
I'll use MATLAB with Serial communication protocol, so sending 54 bytes each iteration for IMU (3 IMUs per 9 axis mesaurements, but Serial.write() function of Arduino needs to send data on 8-bit packet, so the Data from IMU, which are 27 int_16t bytes need to be split into 2 registers High and Low and later reconstruct in MATLAB). From the other Arduino I'll send 4 bytes each iteration (2 EMG channel, again 2 H and L registers).
The reason why I'm gonna use MATLAB is to save directly Data in matrix to do post - processing. I don't need to do real-time operations, but still I need to have sycn data. Basically, I need to know when that sample has arrived and when the other one has been arrived. Then, for me it's important the time-stamp of each operation in order to compare IMU and EMG data.
So the most rough part, the one for which I'm asking support here, is to save data in big matrix in order to have the same time stamp (with different sampling rate).
For now here a pseudocode of what I need to reach:
count_imu = 1;
count_emg = 1;
time = 10;
fc_imu = 100;
fc_emg = 10000; % or 1000;
EMG = serialport(...);
IMU = serialport(...);
dataIMU = zeros(54,fc_imu*time);
dataEMG = zeros(4,fc_emg*time);
while (t<time)
dataIMU = read(IMU,54,'uint8');
dataEMG = read(EMG,4,'unit8');
end
So in the while loop I need to reiceve sycn Data in oder to store them in a pre-allocated matrix. Once I'll get it, I'll do post-processing operation.
The problem is: How can I do to say to MATLAB: "Please, can you read these 2 lines of code inside the while loop at the same moment?".
If it's unfeasible, please let me know if anyone has other suggestions.
Thanks.
  3 Comments
Walter Roberson
Walter Roberson on 27 May 2020
Edited: Walter Roberson on 27 May 2020
The connection between Arduino and MATLAB is not by standard serial port: it is by serial over USB.
The limit for USB is 1000 transactions per second. This is the basic polling rate built in to USB.
Normally the USB serial drivers buffer data until a timeout or the packet is full, designed for efficient use of the USB bus bandwidth and NOT designed for real time use. USB 3 adds some possibilities for interruptions that were not present before, but that requires a USB 3 port being run at USB 3 rates, which arduino is not designed for.
1000 Hz is thus the maximum rate. The actual rate that can be achieved is noted variously as roughly 4 Hz (if you use read analog) or 40 Hz (if you just have the arduino send bytes) with some hints that a few people reach closer to 75 to 100 Hz.
There is an Arduino clone, I think it is Redboard, that can archive higher rates. The way that most official Arduino communicate with USB internally is not so good.
I recently received my arduino but have not had a chance to test it yet, so I am relying on what I have read... but what I have read suggests that 10kHz is Definitely Not Going To Happen with arduino. I have not read as much about Raspberry Pi; I do not have figures at the moment about rates actually achieved.
Oddly enough, if you were using a device with a true serial port then 4 bytes at 10 kHz would be comparatively easy. However that would still require 400000 baud and if you want to avoid buffering then it is probably better to switch to Ethernet. Ethernet can handle 10 kHz without difficulty (but timestamps as they come in can be a problem.)
valio
valio on 29 May 2020
Are you talking about Arduino as object? or SerialPort as object?
In the first case I agree with you that is impossible to reach such a sampling rate, due to delays on communication. But, with SerialPort obj I think the rate depens over the BaudRate like you mentioned. I can't use Ethernet, which is much better, since that I'm smartworking and can't access to Lab's facilities.
Anyway the problem is How to read 2 serial port at the same time. I can downgrade the sampling rate of EMG up to 1KHz, and I think in that case Arduino and USB port should support 115200 as BaudRate without many problems.
For the consistent of the code along time, for timestamp, I'll rely on TCNT registers on Arduino, which are the timer counter and I'll ask to Arduino to convert and send data each time the counter reachs a pre-defined value. I did some trials and I noticed that using 1KHz as sampling rate, along time, for a very long recording (like 10 min, I need just 1 and half) I lost at maximum one sample on 1000. That for my application means less than 1/1000 of error, which is still acceptable.
But, again, how can I do to handle 2 SerialPort at the same time in order to get same value at the same time stamp?
Thank a lot for your help.

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!