Search code examples
arraysmatlabarduinoserial-port

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?


Solution

  • 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');
      }
    }