Reputation: 189
I want to send an array of three floating point numbers to Arduino from MATLAB. I'm trying to check if these values have been received by Arduino by sending these values back from the Arduino to MATLAB. It seems that Arduino only reads the first element in the array correctly.
My array, 'parameters' is:
measurement_interval = 5.0;
ec_ref_thickness = 2.0;
e_ref_thickness = 3.0;
parameters = [measurement_interval ec_ref_thickness e_ref_thickness];
I established communication with Arduino as:
arduino = serial('COM4');
set(arduino,'DataBits',8);
set(arduino,'StopBits',1);
set(arduino,'BaudRate',9600);
set(arduino,'Parity','none');
fopen(arduino);
I send it to Arduino using:
fprintf(arduino, '%f', parameters);
fprintf(arduino, '\n');
And in Arduino I have:
float parameters[3]
void setup()
{
Serial.begin(9600);
while (Serial.available() == 0)
{
}
if (Serial.available() > 0)
{
for (int i=0; i < 3 ; i++)
{
parameters[i] = Serial.parseFloat();
}
Serial.flush();
}
I send back from the Arduino over the serial port as:
void loop()
{
Serial.print(parameters[0])
Serial.print(" ");
Serial.print(parameters[1]);
Serial.print(" ");
Serial.print(parameters[2]);
}
And read in MATLAB as:
output = fscanf(arduino);
'output' should be [5.0 2.0 1.0]. However, what I get is [5.00 0.00 0.00]
So only the first element '5.0' is returned correctly. How can I adapt this to read all the numbers in the array?
Upvotes: 2
Views: 1973
Reputation: 7
I tested your code after adding small modifications, and it works well.
MATLAB code:
measurement_interval = 5.0;
ec_ref_thickness = 2.0;
e_ref_thickness = 3.0;
parameters = [measurement_interval ec_ref_thickness e_ref_thickness];
arduino = serial('COM3');
set(arduino,'DataBits',8);
set(arduino,'StopBits',1);
set(arduino,'BaudRate',9600);
set(arduino,'Parity','none');
fopen(arduino);
pause(2)
fprintf(arduino, '%f %f %f', parameters);
line = fgets(arduino);
values = strsplit(line, ",");
Final_values = str2double(values)
Arduino code:
float parameters[3];
void setup(){
Serial.begin(9600);
}
void loop(){
while(!Serial || Serial.available() <= 0);
for (int i = 0; i < 3; i++) {
parameters[i] = Serial.parseFloat();
}
Serial.print(parameters[0]);
Serial.print(",");
Serial.print(parameters[1]);
Serial.print(",");
Serial.print(parameters[2]);
}
Upvotes: 0
Reputation: 11
First of try to put some delay after fopenf(arduino) in matlab for about 3 sec i.e.
fopen(arduino);
pause(3);
secondly, send the array of parameters one at a time i.e.
for i = 1:4
fprintf(arduino, '%5.3f\n', parameters (i));
pause(0.5);
end
This should work fine and finally in the arduino side, your setup looks fine but the loop where you trying to send array back to matlab try doing
void loop()
{ for (int i = 0; i < 3; i++){
Serial.println(parameters[0]); //sends data back in every new line
delay (20);
}
and yeah try to create an array of zeros in matlab side to store the received value from arduino i.e.
receiveData = zeros (1, 4);
for i = 1:4
output = fscanf(arduino, '%f');
receiveData =output;
end
this should work fine for you Cheers
Upvotes: 1
Reputation: 7342
The answer by @JeffreyCash is very good and I think that it takes 100% care of the code on the Arduino side. However, since you still have problems, I'd like to post this to cover the Matlab side..
I read in your question that you send values from Matlab with
fprintf(arduino, '%d', parameters);
However:
%f
to print float
float
.Perhaps you should write
fprintf(arduino, '%f\n', parameters(1));
fprintf(arduino, '%f\n', parameters(2));
fprintf(arduino, '%f\n', parameters(3));
or
fprintf(arduino, '%f\n%f\n%f\n', parameters(1),
parameters(2), parameters(3));
Upvotes: 1
Reputation: 1073
First off, if you're trying to pass the parameters as floats, you should probably use a '%f'
as the format specifier in your MATLAB code.
Next, you are going to want to wait for Serial data to become available before trying to parse the floats.
float parameters[3];
void setup(){
Serial.begin(9600);
while(!Serial || Serial.available() <= 0);
for (int i=0; i<3; i++){
parameters[i] = Serial.parseFloat();
}
}
void loop(){
for(size_t i=0; i<3; ++i){
Serial.print(parameters[i]);
Serial.print(i<2 ? '\t' : '\n');
}
}
If for some reason that still doesn't work, you could try checking if your serial data is getting to the arduino properly:
void setup(){
Serial.begin(9600);
while(!Serial || Serial.available() <= 0);
while(Serial.available() > 0){
Serial.print(Serial.read());
}
}
void loop(){}
If for some bizarre reason that still doesn't work, you could always try to parse the data into floats another way. Here is one quick example:
float parameters[3];
void setup(){
Serial.begin(9600);
while(!Serial);
while(Serial.available() <= 0);
for(int i=0; i<3; ++i){
String param_string = "";
int c;
while( (c = Serial.read()) >= 0 ){
if((char)c == '\n') break;
param_string += (char)c;
}
parameters[i] = param_string.toFloat();
}
}
void loop(){
for(size_t i=0; i<3; ++i){
Serial.print(parameters[i]);
Serial.print(i<2 ? '\t' : '\n');
}
}
Upvotes: 3