Writing large ammount of data over serial is very slow

12 views (last 30 days)
Emma
Emma on 7 Dec 2017
Commented: Emma on 7 Dec 2017
Hi!
I'm trying to send around 960 000+ uint8 samples to an arduino due using serial ports (not using the toolbox for arduino since there is many arduinos connected at the same time). This takes about 40s with a baudrate of 250 000, having to send this 64 times it would take a little more than 40 minutes.
The samples are sent in chunks since the memory in the arduino cannot handle larger data, preferrably it would be in chunks of 64000. The data is sent and then we wait for the arduino to send a char saying that it has read that what was sent. Waiting for ack does not take much time at all (around 0.007s per run) but sending the data with frwite takes about 8s for 200000 samples.
I have tried to change the size of data to be sent, not having the fwrite in the for loop but writing them after eachother. Also taking out the central fwrite call in the fwrite function.
Does anyone have any idea on how to solve this?
THe code is as follows:
%%------ Send Samples ------ %
block_size = 200000;
number_of_blocks = 5;
[x , fs] = audioread('48kHzSampleSong.wav');
% Only mono
x = x(:,1);
res = 8; % bits per sample
delta = 0.02; % quantization step size
[xhat, yhat] = UniformQuantizer(x,2^res,delta);
% Modify for PWM (y in the interval [0,2^res -1])
y_hat = yhat+2^(res-1);
% Convert to bytes for sending
y_8bit = uint8(y_hat);
[com] = serialsetup('COM8',250000);
disp('>> Communication initialized');
% Choose matlab mode
fprintf(com,'%c','m');
% Send command to Arduino
fprintf(com,'%c','s');
for t=1:number_of_blocks
idx1 = (t-1)*block_size+1;
idx2 = idx1+block_size-1;
tic;
fwrite(com,y_8bit(idx1:idx2), 'uint8');
disp1 = toc;
%fwrite(com,'test', 'uint8', 'async');
tic;
wait4Ack(com,'s');
disp2 = toc;
disp(strcat('ack ',num2str(t), ' fwrite: ', num2str(disp1), ' w4a: ', num2str(disp2)));
end
And setup serial:
% ---- Serial Setup -----
function [s] = serialsetup(comPort,baudRate)
%creates serial connection on comPort and sets standard values for the setup
if(nargin < 2)
baudRate = 250000;
end
s = serial(comPort);
set(s, 'DataBits', 8);
set(s, 'StopBits', 1);
set(s, 'BaudRate', baudRate);
set(s, 'Parity', 'none');
set(s, 'Timeout', 20);
%change output/input buffer to be able to send e.g. 1000 bytes a time to slaves.
%Default is 512 byte.
s.OutputBufferSize = 200000;
s.InputBufferSize = 1024;

Answers (1)

Christoph F.
Christoph F. on 7 Dec 2017
A baud rate of 250000/s means a transfer rate of roughly 21000 bytes/s. This means sending 960000 bytes will take about 46 seconds and sending 200000 bytes will take about 9.5s.
> Does anyone have any idea on how to solve this?
Either use a transfer method with a higher bandwidth, or find some way to reduce the amount of raw data that has to be transferred, e.g. by using some form of compression.
  1 Comment
Emma
Emma on 7 Dec 2017
Thanks for your answer! I will look at possible ways to reduce the raw data!

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!