The documentation of serial/fprintf shows four possible modes in the representative forms, and in each case the data to be sent is shown as a string. However, the format parameter can include any of many different non-character item specifiers, and one of the examples is
fprintf(s,['ch:%d scale:%d'],[1 20e-3],'sync');
which demonstrates a case where the data to be sent is not a string.
Despite this, a user is reporting to me that in R2013a that they were told
Error using serial/fprintf (line 84)
The third input argument must be a string.
Error in Untitled (line 10)
fprintf(s, '*%d', data(:)) ;
where data is uint8 (obtained via imread)
Unfortunately I cannot test this on my own system as I do not have a serial port. Could someone confirm that non-string data can be used in serial fprintf, and could they test whether uint8 is the problem?
(Assume for the moment that the serial buffer is large enough to hold the entire output; do not test with large arrays as the default output buffer is only 512 bytes.)

 Akzeptierte Antwort

Nalini Vishnoi
Nalini Vishnoi am 6 Mai 2015

1 Stimme

Hi Walter,
I can reproduce the behavior on a system with a serial port. The documentation (mostly the syntax section) of serial/fprintf indicates that the data to be sent to the device needs to be a string. However in the example you mentioned the format parameter includes different non-character item specifiers (specifically %d - which is signed decimal notation). When I opened that function, I noticed that serial/fprintf function accepts only 'string' and 'double' data types. Hence the error while trying to pass an array which is of type 'uint8'. If you have not tried already, you can try these workarounds:
1. Cast the uint8 value as double:
>> fprintf(s, '*%d', double(data(:))) ;
2. Use sprintf to build the 'cmd' string which is then passed as an argument to serial/fprintf function:
>> str = sprintf('%u\n',data);
>> fprintf(s, str);
3 Use fwrite function which writes binary data (could be uint8) to the device.
>> fwrite(s, data, 'uint8');
I work with MathWorks and would communicate the ambiguity in the documentation of the function and the possibility of allowing other data types (such as 'uint8') as accepted arguments, to the respective development teams.
-Nalini

7 Kommentare

Walter Roberson
Walter Roberson am 6 Mai 2015
Thank you. I would appreciate if you could mention those to the developers.
With respect to the sprintf() approach, I did get concerned about the maximum string length it could generate, but it appears that only has the normal variable size restriction (i.e., "until you run out of memory" in practice, at least if you are not using a 32 bit release.)
The output buffer size for the serial port is the part that is more likely to create a problem with the sprintf() approach, as the operation is defined as raising an error if the buffer fills up, rather than as "chunking" the output.
The student who wrote to me was intending to read the data on an embedded system, and was intending to send it all as one line with no line breaks. That would implicitly lead to the requirement on the destination system of reading byte by byte to pull off the variable-length text-represented numbers; reasonable-length newline-delimited lines would be more likely to be processable more efficiently. Or, much better yet, if they switched to length-prefixed binary.
Anyhow. Can I have my nap now? ;-)
shamsudheen p
shamsudheen p am 2 Jul. 2015
Bearbeitet: shamsudheen p am 2 Jul. 2015
Hi sir,
I have the same issue while i was trying to send image to the serial port.
The programme code in which i am on is
A = imread('download.png');
if true
s=serial('COM4');
s.InputBufferSize = 5000;
s.BaudRate = 9600;
fopen(s);
data = permute(A, [2, 1, 3]);
fwrite(s, data, 'uint8');
end
fclose(s);
delete(s);
clear s;
and it produces the error
"Error using serial/fwrite (line 199) Unsuccessful write: An error occurred during writing."
I have tried with fprintf(s, '*%d', double(data(:))) ;
and it shows the error as
"Error using serial/fprintf (line 144)
Unexpected Error: The number of bytes written must be less than or equal to OutputBufferSize-BytesToOutput".
Please help me to solve this
Walter Roberson
Walter Roberson am 2 Jul. 2015
In the second case, your serial output buffer has filled up. You can configure the output buffer size.
In the first case, the error is not specific enough for me to understand it. You could try changing the buffer size; the documentation does indicate that each fwrite() must not write more than the buffer size.
shamsudheen p
shamsudheen p am 3 Jul. 2015
Bearbeitet: shamsudheen p am 3 Jul. 2015
I have modified the output buffer size as
s.OutputBufferSize= 15000;
still the problem remains. What is the maximum value that I can have for the output buffer?
Walter Roberson
Walter Roberson am 3 Jul. 2015
As far as I know, the maximum value that you can have for the output buffer in 32 bit MATLAB would be about 1 Gigabyte; for 64 bit MATLAB, the largest output buffer would be 2^48 - 1 bytes, which is quite a number of terabytes.
shamsudheen p
shamsudheen p am 3 Jul. 2015
Bearbeitet: shamsudheen p am 3 Jul. 2015
I have modified the programme code as below
A = imread('download.png');
if true
s=serial('COM46');
s.InputBufferSize = 5000;
s.OutputBufferSize= 2^30;
s.Terminator= 'CR';
s.BaudRate = 9600;
fopen(s);
data = permute(A, [2, 1, 3]);
fprintf(s, '*%d', double(data(:))) ;
end
fclose(s);
delete(s);
clear s;
a time out error is araised as
Error using serial/fprintf (line 144) Unexpected Error: A timeout occurred during the write operation.
Error in tr (line 9) fprintf(s, '*%d', double(data(:))) ;
Walter Roberson
Walter Roberson am 3 Jul. 2015
Bearbeitet: Walter Roberson am 3 Jul. 2015
The default is 10 seconds, which would be enough to transfer 9600 text bytes at 9600 baud. You send a minimum of 2 text bytes per input element, and can send up to 4 text bytes per input element, so your transfer rate is between 240 and 480 elements per 10 seconds. That is, of course, discouraging; you should consider higher baud rates.
(However if you are sending completely over USB with no actual serial port interface, then the 9600 baud is more or less decoration -- but still a large enough file could take more than 10 seconds.)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by