You haven't posted any of the code you're using to receive the values, but I'm guessing the problem is with your casting and decoding of the dataOut
value.
Consider the following (direct from my copy of Matlab):
dataOut = 1.3;
dataOut_ = char(dataOut);
fprintf('%d\n',dataOut_);
1
This is because your dataOut_
variable is not a string or character array of values! If you were to instead try fprintf('%d\n',dataOut);
(note the lack of trailing underscore), you get:
fprintf('%d\n',dataOut);
1.300000e+00
If you want to convert 1.3
to a character array (what I'm assuming you actually want to do, but again you never posted the receiving code so I don't know really what you're anticipating receiving), then you should use either the long-hand form:
dataOut_ = char(string(dataOut));
or the built-in function that does the same thing:
dataOut_ = num2str(dataOut);
Both of those return the same:
dataOut_ = char(string(dataOut));
fprintf('%d\n',dataOut_);
49
46
51
These are bytes that correspond to Unicode characters. You can translate those bytes back to characters by casting them to ascii/unicode on the receiving end, BUT then you also need to put those characters into a character array and then convert that character array back to a number.
Matlab has a built in function that could do that, but you're (presumably) not using Matlab on the receiving end:
>> dataIn = native2unicode([49,46,51])
dataIn =
1.3
But again, that 1.3
is a character array. You need to cast it to a number, usually with double(dataIn)
.
There is an easier solution.
Multiply the number by 100. Round using the Matlab command round
, pass that value. On the receiving end, divide by 100. Now you have timing control to a hundredth of a second. A uint8 could do up to 2.55 seconds, a uint16 could do up to 655.35 seconds.
Keep in mind that you'll need to send multiple bytes anyways if you're planning on converting a floating point number to a character array, so using a uint16 shouldn't be a problem as far as your data packets go.
dataOut = 1.3;
dataOut_ = round(dataOut*100);
fprintf('%d\n',uint16(dataOut_));
130
:EDIT:
OP posted some more code, but it doesn't look like everything, but I can comment from here:
- I don't see where you multiply by 100 in your transmit code. Is that code current?
- In your Arduino code, you use
Serial.read();
but you don't ever cast the output. This means that each byte of d
is a number from 0-255. If you want to use it as a character array, you (probably) need to cast it to a string/char before you make the comparison check.
- In your Arduino code, you're just checking if
d
is the floating point number 1.3. You haven't done anything (like char(1.3)
or string(1.3)
) to cast 1.3 to a character array so you can do byte-by-byte comparisons.
You have a number of options here, but I'm not sure what you want to do:
- Cast the floating point number to a byte array, send the resulting byte array, and then recast the byte array back to floating point. In Matlab, use
fprintf('%d\n',typecast(1.3,'uint8'))
.
- Cast the floating point number to a character (Unicode) byte array, transmit the byte array, and then convert the byte array back to characters, then convert the characters back to a number. In Matlab, use
fprintf('%d\n',char(string(1.3)))
.
- Multiply from fractional seconds to tenths or hundredths or milliseconds, etc. Round/truncate the number, transmit the number, then convert back to fractional seconds. In Matlab, use
fprintf('%d\n',uint16(round(1000*1.3)))
.
Matlab inherently uses 64 bit (double) numbers for everything, so keep that in mind when you try to reassemble the bytes on the Arduino end. If you want to transmit the byte array for a 32 bit number, use the single()
command, as in fprintf('%d\n',typecast(single(1.3),'uint8'))
. This produces a four byte array, as opposed to the eight byte array produced when you run the same command without the single
command.