Afzal
Afzal

Reputation: 189

Send array of floating point numbers from MATLAB to Arduino

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

Answers (4)

Ibrahim Seleem
Ibrahim Seleem

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

Tashi Wangyal
Tashi Wangyal

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

Patrick Trentin
Patrick Trentin

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:

  • you should use %f to print float
  • as far as I know, with this instruction you only send one value, and that's why when you run JeffreyCash's code you successfully print only one 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

Jeffrey Cash
Jeffrey Cash

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

Related Questions