Matlab -> Arduino -> Matlab

Dear all,

I'm new to Arduino and since working years on Matlab I would like to merge some projects on Arduino.
I'm facing right now a problem in the serial communication between the two.
(I don't use simulink, and I don't want to)

What I would like is to transfer is a vector (10x1) to Arduino through serial.

Here below an example with a vector of 3x1.

%% TESTS
clear all
clc

arduino=serial('/dev/cu.usbmodem1421','BaudRate',9600);
fopen(arduino);

x=[10;-1;0];
pause(1)

for i =1:max(size(x))
fprintf(arduino, '%f ', x(i));
end

y = fscanf(arduino, '%f')

fclose(arduino); % end communication with arduino

And on Arduino:

double matlabData[3];
int i=0;

void setup()
{
Serial.begin(9600);
}

void loop()
{

while(Serial.available()>0) // if there is data to read
{
matlabData*=Serial.parseInt();; // read data*

  • }*
  • Serial.print(matlabData[0]);*
  • Serial.print("\t");*
  • Serial.print(matlabData[1]);*
  • Serial.print("\t");*
  • Serial.print(matlabData[2]);*
  • Serial.print("\t");*
  • Serial.println("");*

}[/quote]
It's doesn't work at all.
What am I doing wrong guys?
Can you help a dumb guy?
Cheers

It's doesn't work at all.

It does work. It just doesn't do what you expect. So, lets adjust those expectations.

First, why are you using parseInt() when sending floating point values? Why are you storing the result integer values in a double array?

Second, since you failed to post your code correctly, it looks like you are trying to assign the integer value to the array, not to the ith element of the array. Are you actually storing the data correctly?

Third, opening the serial connection resets the Arduino. How much time are you allowing for the Arduino to reset? Can it reset, open the serial port, collect all the serial data, process it, and send data back in the time before you close the serial port again?

Fourth, does the program produce correct output if the data is sent from the Serial Monitor application?

Dear Paul S,

It does work. It just doesn't do what you expect. So, lets adjust those expectations.

exactly. This because I really don't know very well Arduino. :slight_smile:

why are you using parseInt() when sending floating point values? Why are you storing the result integer values in a double array?

because in principle I will send a vector from Matlab like this
x= [1.534e-14, 1e-5, 3.234]
And I thought that starting already with floating serial communication would save me time.
I've found on a tutorial this parseInt function and I thought it could work.

Second, since you failed to post your code correctly, it looks like you are trying to assign the integer value to the array, not to the ith element of the array. Are you actually storing the data correctly?

In Matlab yes. In arduino, I've no idea what I'm doing.

opening the serial connection resets the Arduino. How much time are you allowing for the Arduino to reset? Can it reset, open the serial port, collect all the serial data, process it, and send data back in the time before you close the serial port again?

mh.. I really don't know how much time I'm allocating for this.

Any help would be helpful.

Thank you very much

I've found on a tutorial this parseInt function and I thought it could work.

To parse floats? Then, I suppose you'll use parseFloat() when you need to parse a bunch of ints in some other project...

In arduino, I've no idea what I'm doing.

Wel, posting code properly isn't rocket science.
Click the code icon (the far left one on the top row) and paste the code.
At least then we could seem the same thing you see with no italics.

I really don't know how much time I'm allocating for this.

Well, what part of your matlab code waits for something to happen?

 pause(1)

All other parts are done as quickly as possible.

Now, is that one week, one hour, one minute, one second, or one millisecond?

This is the Arduino code

double matlabData[3];
int i=0;


void setup() 
{
  Serial.begin(9600);
}
 
void loop() 
{

 while(Serial.available()>0) // if there is data to read
   {
    matlabData[i]=Serial.parseInt();; // read data

    }
  Serial.print(matlabData[0]);
  Serial.print("\t");
  Serial.print(matlabData[1]);
  Serial.print("\t");
  Serial.print(matlabData[2]);
  Serial.print("\t");
  Serial.println("");


}

And this is the Matlab code.

%% TESTS
clear all
clc


 arduino=serial('/dev/cu.usbmodem1421','BaudRate',9600);
 fopen(arduino); 
 
 x=[10;-1;0];
 pause(1)


for i =1:max(size(x))
fprintf(arduino, '%f ', x(i));
%fwrite(arduino,x(1),'uint8');
end

 y = fscanf(arduino, '%f')

 
 fclose(arduino); % end communication with arduino

I didn't implement other things.
I have the pause(1) that means 1 sec. Matlab waits 1 sec.

Matlab waits 1 sec.

First, try making that 5.

Then, open the Serial Monitor, instead of matlab, and send "10;-1;0". What do you get back?

still 0.00 0.00 0.00

Calligula:
still 0.00 0.00 0.00

When using matlab? Or when using the Serial Monitor application?

Oh, and don't you think that incrementing i in the while loop would be a good idea?

Try sending 1.0, 2.0, 3.0, and see what happens.

Done through serial monitor and add the i++; in the while loop

Still 0.00 0.00 0.00

I have the feeling that the serial.parse function is not what I'm looking for

I have the feeling that the serial.parse function is not what I'm looking for

Post your latest Arduino code, since the culprit does not appear to be the matlab code.

Latest Arduino code
(I just changed the array into float, added the parseFloat())

again, whatever I send it's 0.

float matlabData[3];
int i=0;


void setup() 
{
  Serial.begin(9600);
}
 
void loop() 
{

 while(Serial.available()>0) // if there is data to read
   {
    matlabData[i]=Serial.parseFloat();; // read data
i++; 
    }
  Serial.print(matlabData[0]);
  Serial.print("\t");
  Serial.print(matlabData[1]);
  Serial.print("\t");
  Serial.print(matlabData[2]);
  Serial.print("\t");
  Serial.println("");


}

I "partially" solved the problem with this Arduino code:

#define SIZE_DATA   3
 
float matlabData[SIZE_DATA] = {0};  //Not a bad idea to initialize it
 
void setup()
{
  Serial.begin(9600);
  Serial.setTimeout(1000);  //set waiting time in ms (default: 1000ms) -> so, if you send something from Matlab, it will wait for 1000ms to be sure that nothing else will come…
}
 
void loop()
{
 
  if (Serial.available() > 0) // if, not while (possibly an issue, to be confirmed
  {
    for (int i = 0; i < SIZE_DATA; i++) //Before you were not initializing your counter… So there was an overflow !
      matlabData[i] = Serial.parseFloat();
 
    Serial.read();  //clean serial buffer (read all remaining characters like “\r”)
 
    //Print only if received data:
    Serial.print(matlabData[0]);
    Serial.print("\t");
    Serial.print(matlabData[1]);
    Serial.print("\t");
    Serial.print(matlabData[2]);
    Serial.print("\n");
  }
}

I successfully send the inputs to arduino through serial monitor but now matlab cannot read or send. so I need now a Matlab routine to send correctly a vector to serial.

    Serial.read();  //clean serial buffer (read all remaining characters like "\r")

In your comment, you misspelled one.

float matlabData[SIZE_DATA] = {0};  //Not a bad idea to initialize it
  1. Global variables are initialized by default.
  2. Initializing one element of a n element array is NOT a good idea.

I successfully send the inputs to arduino through serial monitor

Show us exactly what you are sending, including the line ending setting of the serial monitor app.

I finally had a result.
But still I want to improve it.

So in Arduino I have this:

#define SIZE_DATA   3
 
float matlabData[SIZE_DATA] ;  //Not a bad idea to initialize it
 
void setup()
{
  Serial.begin(9600);
  Serial.setTimeout(10);  //set waiting time in ms (default: 1000ms) -> so, if you send something from Matlab, it will wait for 1000ms to be sure that nothing else will come…
}
 
void loop()
{
 
  if (Serial.available() > 0) // if, not while (possibly an issue, to be confirmed
  {
    for (int i = 0; i < SIZE_DATA; i++) //Before you were not initializing your counter… So there was an overflow !
      matlabData[i] = Serial.parseFloat();
 
    Serial.read();  //clean serial buffer (read all remaining characters like “\r”)
 //Serial.flush();
    //Print only if received data:
    Serial.print(matlabData[0]);
    Serial.print("\t");
    Serial.print(matlabData[1]);
    Serial.print("\t");
    Serial.print(matlabData[2]);
    Serial.print("\n");
  }
}

in Matlab this:

clear all
clc

arduino=serial('/dev/cu.usbmodem1421','BaudRate',9600);
fopen(arduino);
y = fscanf(arduino, '%f');

x=[1;2;3];    
for i = 1:3  memory
    fprintf(arduino, '%f ', x(i));
end
y = fscanf(arduino, '%f')


x=[1.45;2.56;3.67];    
for i = 1:3  
    fprintf(arduino, '%f ', x(i));
end
y = fscanf(arduino, '%f')

fclose(arduino); % end communication with arduino

As you can see I have 3 scanf... and 2 printf....why?
well..
Here the result on matlab:

Warning: Unsuccessful read: A timeout occurred before the Terminator was reached.. 

y =

     1
     2
     3


y =

    1.4500
    2.5600
    3.6700

If you cut the first fscanf and leave the others, still the first (with y=1,2,3) answer with the warning and then correctly scan the (y=1.45,2.56,3.67).

It seems that matlab start scanning before arduino sends the reply. am I wrong?

You have not fixed all of the issues I have pointed out. Why do you expect continued help?

How long does it take the Arduino to reset after you open the serial port? Are you waiting that long?