NaNs from str2double on Arduino hardware

1 view (last 30 days)
I'm running a Simulink model with a Matlab Function Block on an Arduino Mega 2560. The Matlab code includes converting a string to a double.
E.g.:
function x = convert(str)
x = str2double(str);
It works in Normal mode simulation, but when running on the hardware (External mode) I keep getting NaNs returned in x instead of the number. To try to work out what's wrong, I've tried the following simplified code:
x = str2double('32'); % returns NaN
x = str2double('32.0') % returns 32
Can anyone explain this behaviour, and what do I do to get over it? I've tried using real() function and that seems to make no difference.
  2 Comments
Stephen23
Stephen23 on 14 Oct 2019
Start by checking:
  1. that the correct function is being called (e.g. which str2double -all).
  2. the actual input data does not contain any non-numeric characters (convert to double and print in the command window. Show us some examples).
Richard Stephens
Richard Stephens on 14 Oct 2019
The two examples I gave contain only numeric characters!
x = str2double('32'); % returns NaN
x = str2double('32.0') % returns 32
Perhaps I didn't make it clear enough that this is a problem with the code generation for Arduino. It works fine in Normal mode. I only get a problem when running on the external hardware.

Sign in to comment.

Accepted Answer

Debarghya Kundu
Debarghya Kundu on 25 Nov 2020
The reason for the observed behavior is the stdio library used by Arduino.
The code generated by str2double uses a function called sscanf. This function internally calls vfscanf function.
vfscanf is available in three different versions. Out of these three versions, the default version does not implement scanning float variables. This is mentioned in the doc:
"By default, all the conversions described above are available except the floating-point conversions and the width is limited to 255 characters. The float-point conversion will be available in the extended version provided by the library libscanf_flt.a. Also, in this case the width is not limited (exactly, it is limited to 65535 characters). To link a program against the extended version, use the following compiler flags in the link stage: -Wl,-u,vfscanf -lscanf_flt -lm "
Refer the following doc link for more details:
To use compiler flags mentioned in the doc, you can follow the steps mentioned below:
1. Open config set
2. Go to "Code Generation" tab
3. In "Build configuration" drop down, select "Specify"
4. In C++ Liker, append the following: -Wl,-u,vfscanf -lscanf_flt -lm
5. Dont forget to add a space to the existing flags before appending the new flags.
6. Click apply, OK.
7. Run the model in external mode.
Please note that using the extended version of this library will consume a lot of code space.
  1 Comment
Richard Stephens
Richard Stephens on 26 Nov 2020
Thanks for the reply.
I decided to write my own very simple str2dbl and dbl2str routines rather than "consume a lot of code space".

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!