Filter löschen
Filter löschen

Arduino UNO and MATLAB GUI Serial Communication Problem

5 Ansichten (letzte 30 Tage)
Rachel Dunwoody
Rachel Dunwoody am 8 Apr. 2019
Kommentiert: Abhishek Singh am 16 Apr. 2019
I am using an Arduino UNO to control a motor through a MATLAB GUI. I am trying to read back data from the Arduino but MATLAB is saying it is receiving empty cell arrays. If I use the Arduino serial output I can see it is outputting the data in the expected manner.
The error received is: Warning: A timeout occurred before the Terminator was reached. 'serial' unable to read any data.
I have a small amount of 'handshaking' between Matlab and Arduino at the start of the script - just sending a character to and from to ensure Serial communication is set up and setting a few sampling parameters from MATLAB. Could it be a buffer issue?
I have tried using Serial.flush() in Arduino Code, flushinput() in Matlab script, setting the timeout period to be longer, trying different terminators.... would really appreciate other ideas?
Thanks in advance!
Here is the relevent MATLAB code for setting up serial communication:
%%%%%%%%%%%%%%%% Handshaking to set up serial with Arduino Mega %%%%%%%%%%%%%%%%%%%
instrreset; %disconnect and delete all instrument objects
handles.d = serial(handles.comport); %set up serial communication
set(handles.d, 'BaudRate', 115200);
set(handles.d, 'InputBufferSize', 100);
set(handles.d,'Terminator','LF');
fopen(handles.d);
% Check Arduino is alive
a='b';
while (a~='a')
a=fread(handles.d,1,'uchar');
end
if (a=='a')
disp('Serial Read');
end
fprintf(handles.d,'%c','a');
mbox=msgbox('Serial communication setup.'); uiwait(mbox); %Click box to acknowledge serial comms is up and running
%{
'b' - bus voltage
'r' - reset encoder to 0
'c' - calibration
's' - set position
'v' - set velocity
%}
%%% Check odrive motor controller set up by requesting bus voltage
fprintf(handles.d,'%c','b'); %requesting voltage
BusVolt = 0;
while (BusVolt == 0)
data_bus = scanstr(handles.d,'\n','%f')%reading in data as split string
if (18.5 < data_bus <20) %Should read about 19.5 - 19.8V if Odrive set up
BusVolt = data_bus;
disp(BusVolt);
end
end
%{
Calibrate motor and wait for confirmation from Arduino that
calibratation finished
%}
fprintf(handles.d,'%c','c'); %requesting calibration
h = 'n'
while (h ~= 'y')
h = fread(handles.d,1,'uchar');
end
if (h=='y')
disp('Calibration Finished!');
end
guidata(hObject,handles); %update all handles
Then this is the code I use to set parameters and read data from Arduino:
VTmax = handles.lengthV % Total time for data collection (s)
VTs = handles.samplefreqV % Sampling time (s)
%Calculating encoder counts to move for input speed
vel_counts = 0
vel_deg = handles.vel
vel_counts = vel_deg * 11.1111
valuesV = [vel_counts,VTmax,VTs]
%Get arduino to update sample time and frequency with next two pieces of data sent to it
fprintf(handles.d,'%c','j');
if (vel_counts >= 1200)
mbox=msgbox('Velocity < 100 deg/s'); uiwait(mbox); %Click box
end
if (vel_counts <= 1200)
fprintf(handles.d,'%f\n',valuesV);
end
disp('Data Sent')
% Arduino has received data
rec='b';
while (rec~='t')
rec=fread(handles.d,1,'uchar');
end
if (rec=='t')
disp('Data Received');
end
%Send move at specified velocity command
fprintf(handles.d,'%c','v');
serialobj = handles.d
%fread(serialobj, serialobj.BytesAvailable)
i = 0;
tic
while (toc < VTmax)
i = i + 1
%if size(data_strV) == [2 1]
%fread(serialobj)%, serialobj.BytesAvailable)
data_strv = scanstr(handles.d,'LF')%reading in data as split string [enc counts, degrees moved]
%Read time stamp
% If reading faster than sampling rate, force sampling time.
% If reading slower than sampling rate, nothing can be done. Consider
% decreasing the set sampling time Ts
t(i) = toc;
if i > 1
T = toc - t(i-1);
while T < (1/VTs)
T = toc - t(i-1);
end
end
t(i) = toc;
end
And finally this is the code in Arduino used to print out the data - it works using the Arduino serial prompt so I think the issue is on the MATLAB end in reading in the data.
vel_set = 50;
if (c == 'v') {%//set speed and print out position in counts and degrees
odrive.SetVelocity(axis0, vel_set); %//command motor to move at desired velocity
%//Time stamp start of this iteration of loop
StartRun = micros();
CurrentMicros = micros();
while (CurrentMicros - StartRun < len*mic){ %//check that sample duration not exceeded
%//Time stamp start of this iteration of loop
CurrentMicros = micros();
if (CurrentMicros - OldMicros > 1/(double)freq*mic){ %//check sample freq
encoder2Pos = encoder2.read(); %read data from encoder
degPos = encoder2Pos * 0.09; %convert encoder count to degrees
Serial.print(encoder2Pos);
Serial.print(',');
Serial.println(degPos);
OldMicros = CurrentMicros;
}
}
odrive.SetVelocity(axis0,0); %Set motor speed back to 0
}
  1 Kommentar
Abhishek Singh
Abhishek Singh am 16 Apr. 2019
Help me with these informations to better assist you:
1). Which version of matlab you're using.
2). Share the Arduino code that you are using so I could debug your problem easily.

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Kategorien

Mehr zu MATLAB Support Package for Arduino Hardware finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by