fscanf() is producing inconsistent results

5 views (last 30 days)
Amed
Amed on 7 Apr 2014
Edited: Amed on 7 Apr 2014
Hello, I am at a real tough spot. My senior design challenge is a data acquisition system and I am using matlab as to collect data from Arduino. The code is mostly done, but I am having very poor results using fscanf() to collect a string of data.
My Arduino is sending the following string of 2 floating values through the serial communication port.
832.5767 22.5783
My code I am using is the following:
if true
while n < 10000
timer = toc;
if timer >= round(timer*10)/10 && clone ~= round(timer*10)/10;
clone = round(timer*10)/10;
Time(n) = round(timer*10)/10; % writes data in time matrix.
% Begin data acquisition.
input = fscanf(s)
input = cell2mat(textscan(input, '%f %f'))
n = n + 1;
end
pause(0.00001) % Pause is essential to break loop.
end
end
Everything works beautifully until about a minute and then fscanf() starts producing inconsistent reads. Changing the baud rate has no effect. Its like clockwork where errors begin to occur at the 1400ish iteration.
Please help me, my grade is dependent on the success of this project.

Accepted Answer

Amed
Amed on 7 Apr 2014
Edited: Amed on 7 Apr 2014
Thanks for your help, I actually fix the issue thankfully by limiting the number of times Arduino performs Serial.println(). You were right on the inefficiency of my previous code but I had the same problem on a faster code. It is at the expense of some latency but I was able to solve the issue where MATLAB sends a request to the Arduino where it then returns a string.
The new code is based from this model I created to sample at intervals.
if true
SF = 10; % Samples per second
n = 1;
Time = 0;
Clock = tic;
while n < 10
if toc(Clock) >= Time + 1/SF
Time = toc(Clock)
n = n + 1;
end
end
end
Before I had it to where Arduino was sending continuous data, but I suspect the MATLAB engine has a bug with the fscanf() under the conditions deployed with GUIDE. Arduino may be to fast for MATLAB in the manner I previously used.
if true
while n < 10000
if (handles.timer + toc) >= timer + 1/10
timer = timer + round(toc*10)/10;
% Begin data acquisition.
fprintf(s, 'A'); % here is where the request was sent.
input = fscanf(s, '%f %f'); % here is where MATLAB receives data.
Time(n) = timer;
RPM(n) = input(1,1);
% End data acquisition.
n = n + 1;
end
pause(0.000001) % needed to break loop via button.
tic
end
end

More Answers (1)

Jan
Jan on 7 Apr 2014
Your loop wastes a lot of time. Why do you start about 1000 pause commands instead of waiting for 10 seconds? What about pause(10) to wait once only?
A timer callback would be even nicer.
This looks easier than the indirection over textscan and cell2mat:
input = fscanf(s, '%f %f')
Your problem seems to be, that the external device does not send the data fast enough. It looks like "832.5767 22" has been sent while your program reads and in the next iteration you get the string ".5783" only. Better think of another method to detect the availability of data. Which line break did you specify in the fopen command to open the serial connection?
Look for "BytesAvailable" and further hints on http://www.mathworks.com/help/matlab/ref/serial.fscanf.html .

Categories

Find more on Data Acquisition Toolbox Supported Hardware in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!