MATLAB Answers

data format error with serial communication

3 views (last 30 days)
Hello everybody, i have realized a script who send some comands to a serial devide. The device is a Mitsubishi Rv-m1 robot and it communicates with matlab on RS232. Here is the script.
clear all
cam = webcam('Trust Webcam');
s = serial('COM4');
s.StopBits = 2;
s.Parity = 'even';
s.DataBits = 7;
s.BaudRate = 9600;
t2 = timer('TimerFcn', 'stat=false; disp(''Timer'')','StartDelay',2);
t5 = timer('TimerFcn', 'stat=false; disp(''Timer'')','StartDelay',5);
t8 = timer('TimerFcn', 'stat=false; disp(''Timer'')','StartDelay',8);
fprintf(s,'SP 5');
fprintf(s, 'NT');
%%Definizione posizioni
% Posizione webcam
fprintf(s,'PD 1,+32.5,+250.3,+318.4,-93.8,+179.9');
% Origine piano dei cilindri
fprintf(s,'PD 2,-122.4,+365.8,+33.8,-86.8,+179.9');
% Vettore contenente le coordinate dell'origine
origin = [-122.4 365.8 33.8 -86.8 179.9];
%%Posizionamento per scattare la foto
fprintf(s,'MO 1');
%%Snapshot - ridimensionamento - localizzazione posizioni
%%Posizionamento nell'origine
fprintf(s,'MO 2');
%%Movimento dall'origine alla posizione dell'oggetto
% Vettore contenente le coordinate del centro del cilindro
% Ottenuto modificando il vettore origin con le coordinate dei centri.
cylinder = [origin(1)+centrimm(1),origin(2)-centrimm(2),origin(3),origin(4),origin(5)];
% Conversione in formato char con 2 cifre decimali
movechar = sprintf('MP %0.1f,%0.1f,%0.1f,%0.1f,%0.1f',cylinder(1),cylinder(2),cylinder(3),cylinder(4),cylinder(5));
% Conversione in formato adatto per il comando seriale
% Esempio di comando : 'MP +28.1,311.9,40,-88.8,179.9'
movestr = cellstr(movechar);
% Movimento robot
In the first section i have setted all the correct parameters for the communication infact the firsts commands (fprintf(s,'SP 5'); fprintf(s, 'NT'); fprintf(s,'PD 1,+32.5,+250.3,+318.4,-93.8,+179.9');) work correctly. "new_circle_recognition" is a script who makes a snapshot of the webcam (matlab object cam) and returns a vector 1x2 named centrimm with the position in mm of the center of a cylindric object. I want to use the information inside centrimm for send a serial command to serial object "s" with fprintf. The string should be like this: 'MP +28,311,40,-88,179' so i have used sprintf for create a char variable with the number in float format without decimal digits.
If i use char variable "movechar" in fprintf
the device returns an error sound instead using cell variable "movestr"
matlab returns "cmd must be a string".
At this time i don't have at home the robot. I believe the problem is in the wrong data format of the command sent with fprintf. I'm thinking to use something like this
or i can use fwrite instead fprintf. does someone have a suggestion? Thanks a lot guys.


Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 23 Oct 2016
fprintf(s, '%s\n', movestr{:});


Show 1 older comment
Walter Roberson
Walter Roberson on 23 Oct 2016
fprintf(s,'movechar') returns an error because you were literally sending the word movechar rather than the content of the variable movechar
fprintf(s,movestr) was giving you an error because you had taken the character vector you had created and you were using movestr = cellstr(movechar); for no obvious reason, which turned the single string into a cell array of strings, which fprintf() cannot deal with directly.
You used
movechar = sprintf('MP %0.1f,%0.1f,%0.1f,%0.1f,%0.1f',cylinder(1),cylinder(2),cylinder(3),cylinder(4),cylinder(5));
Notice that you do not end the line of text with \r or \n . It so happens that if you are using a serial device and you use
fprintf(s, 'some constant string')
then that is equivalent to
fprintf(s, '%s\n', 'some constant string')
which adds the configured end-of-line delimiter at the end of the string, which is why you might not have noticed the lack of newline before; see
fprintf(obj,'cmd') writes the string cmd to the device connected to the serial port object, obj. The default format is %s\n
My suggested code
fprintf(s, '%s\n', movestr{:});
uses that format once for every string in the cell array of strings in movestr . It is equivalent to
fprintf(s, '%s\n', movestr{1}, movestr{2}, movestr{3}, ... movestr{end});
which in turn would be equivalent to
fprintf(s, '%s\n', movestr{1});
fprintf(s, '%s\n', movestr{2});
fprintf(s, '%s\n', movestr{end});
except for some details about when flushing occurs. The short form for that would be
fprintf(s, movestr{1});
fprintf(s, movestr{2});
fprintf(s, movestr{end});
I do not know why you used
movestr = cellstr(movechar);
so I speculated that you were showing a simplified form of the code where you might, in your real code, want to store multiple strings and send them all at once.
But for the code you show... the easiest repair is to just remove the line
movestr = cellstr(movechar);
and continue to use
fprintf(s, movestr);
squall141 on 23 Oct 2016
I have used cellstr to obtain a value which includes character '. In this way I have 'my generic string' instead my generic string. If I remove
movestr = cellstr(movechar);
I have only movechar which is an 1xn char like this
movechar =
MP 12.5,52.7,256.3,659.4,179.5
Furthermore in your answer you say to use
fprintf(s, '%s\n', movestr{:});
on movestr 1x1 cell obtained with cellstr (that you suggest to remove). Anyway i can't use movestr{2}, movestr{3} etc because it's only 1x1 cell. Only movestr{1} and movestr{:} works obviously.
Walter Roberson
Walter Roberson on 23 Oct 2016
The inclusion of the ' is only for display purposes in cell strings; it is not stored along with the string. If you need to actually transfer ' (which I doubt) then you should
fprintf(s, '''%s''\n', movestr)
where movestr is not a cellstr
movestr{2} would be beyond movestr{end} in the case of a 1 x 1 cellstr. I am illustrating what cell array expansion means.

Sign in to comment.

More Answers (0)

Sign in to answer this question.

Translated by