Go Down

Topic: Serial communication Matlab-Arduino (Read 988 times) previous topic - next topic

m_dal

this is my code:
Code: [Select]

String stringa= ""; //create a string to store what comes from serial
char c; //create a variable char to store each character from serial
int B [298][6]; //matrix that must be filled with data read from serial
int count=0; //counter that increased if a ';' is found
int conta4=0; //counter to store the length of the string
int conta5=0; //counter that increases if a value is added to B
int conta2=0; //counter that increases if a numeric value is found on the string
int conta3=0; //counter that increases if a value is added to B
            //(it is set to 0 if a row of B has been entirely filled)
int num; //variable that stores the value of x(char array) into integer
bool s=false; //to repeat the loop only once
char q=';';
char w=' ';
char y=']';
char x[9];//variable char to store values until ';' ' ' or ']' will be found
#include <AccelStepper.h>
#include <MultiStepper.h>

// Define some steppers and the pins the will use (first pin for the number of wires,
                                                 // second one for the number of steps,
                                                 // and third one for direction)
AccelStepper stepper1(1,9,8);  
AccelStepper stepper2(1,2,3);
AccelStepper stepper3(1,10,11);
AccelStepper stepper4(1,22,23);
AccelStepper stepper5(1,24,25);
AccelStepper stepper6(1,26,27);

MultiStepper steppers;

void setup() {
 Serial.begin(4800);

stepper1.setMaxSpeed(500.0);
Serial.print("stepper1 in posizione:");
Serial.println(stepper1.currentPosition());
   
   
stepper2.setMaxSpeed(500.0);
Serial.print("stepper2 in posizione:");
Serial.println(stepper2.currentPosition());


stepper3.setMaxSpeed(500.0);
Serial.print("stepper3 in posizione:");
Serial.println(stepper3.currentPosition());


stepper4.setMaxSpeed(500.0);
Serial.print("stepper4 in posizione:");
Serial.println(stepper3.currentPosition());


stepper5.setMaxSpeed(500.0);
Serial.print("stepper5 in posizione:");
Serial.println(stepper3.currentPosition());



stepper6.setMaxSpeed(500.0);
Serial.print("stepper6 in posizione:");
Serial.println(stepper3.currentPosition());



steppers.addStepper(stepper1);
steppers.addStepper(stepper2);
steppers.addStepper(stepper3);
steppers.addStepper(stepper4);
steppers.addStepper(stepper5);
steppers.addStepper(stepper6);

delay(3000);

 
}
void loop() {
  if (Serial.available() > 0) { //read from serial

   c = Serial.read(); // read Char
   stringa = stringa + c; // add Char to string
   conta4=conta4+1; //increase counter to store the length of the string
   }
   if(s==false){
if(stringa.charAt(conta4-1)==y){//enter in if only is the string has been acquired
for ( int i=0;i<conta4-1;i++)//go through the i-char of the string
{
   if(stringa.charAt(i)==q) //if ';' is found
   {
       count=count+1; //increase count (go to the following row of the matrix)

   }
   
   if (stringa.charAt(i)!= q && stringa.charAt(i)!= w) //(a number has been found)
   {
     x[conta2]=stringa.charAt(i); //add number to x
     conta2=conta2+1; //increase the counter if a number or a sign has been found
   }
if(stringa.charAt(i)==w || stringa.charAt(i+1)==q|| stringa.charAt(i+1)==y){ //the number
                                                                           //to be stored in the matix
                                                                           //has been read
num= atoi(x); //convert the char array x into a number
if (conta3==6){ //the row of B has been completed
       conta3=0;
}
   for (int i=0; i<conta2;i++){
   x[i]=' ';//set all the values of char array x to ' ' once x has been converted to integer
   }
   B[count][conta3 % 6]=num; //add num to B
   s=true; //exit from loop once the for cycle is over
   conta2=0; //set to 0 the index of x
  conta3=conta3+1; //increase counter because a number has been added to the matrix B
  conta5=conta5+1;//increase counter because a number has been added to the matrix B
     
   
     }
   }
   if (conta5==1788){ //once B has been completed store each row in a 1-D array and move the robot
long positions [6];
for (int i=0;i<298;i++){
 for (int j=0;j<6;j++){
positions [j]=B[i][j];
}
steppers.moveTo(positions);
steppers.runSpeedToPosition();
}
}
}

     }
   }


The code is working properly: I have used Hyperterminal to send my txt file containing the matrix converted into string and then I have verified if the matrix has been received printing with Serial.println() all the values of the matrix containing the number of steps for each position. My other question is: I can write on serial with Matlab using a simple function but how can I verify if I received all my values if I can't print on the serial because it's occupied? I know Arduino DUE has three serials but how can i use them?

UKHeliBob

Quote
The problem is to synchronize the time in which a row is sent on serial and the movement of the robot itself
Time has little or nothing to do with it.  Have the Arduino signal Matlab that it is ready to receive a new row of data when it can deal with it.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

m_dal

This could be matlab code:
Code: [Select]

s = serial('COM1');
fopen(s);
for i=1:length(matrix)
x=matrix(i,:); %single row of the matrix
fprintf(s,'%s',x) %write single row of the matrix as a string of char
end
fclose(s)


I could also add '<' and '>' as string starting and terminator, as you suggested.

In this way I write a single row of the matrix on the serial through Matlab, then in the Arduino Code the string must be converted into a vector to move the stepper motors  with the functions I reported on my Sketch. THERE IS A PROBLEM: how can I know that while matlab is writing on serial a movement has been completed? for example matlab could send one row, the robot starts to move and matlab send another row while the roboti is still completing the movement, perhaps matlab sends another row and in this way I jump a position.

UKHeliBob

As I have already suggested, have the Arduino signal Matlab that it is ready to receive a new row of data when it can deal with it.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

m_dal

I don't understand well, can you explain how can i do this?

UKHeliBob

Matlab sends one row of data
Arduino receives one row of data
The robot executes the commands in the data
The Arduino sends a serial message to Matlab to ask for more data
Repeat until all rows have been received and acted upon
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

m_dal

Here is a simple code I wrote to send through matlab a 3 x 3 matrix row by row:

Matlab code
Code: [Select]

A=[123 13 20; 343 49588 11; 4387 -11 989];
s = serial('COM3');
fopen(s);
c='y';
count=1;

if c=='y' %if yes received send a new row
x=A(count,:); %single row of the matrix
fprintf(s,x); %write single row of the matrix as a string of char
count=count+1;
datas=fread(s,'int32') %arduino sends to matlab the received data
c ='n'; %c variable is set to 'n' until 3 seconds are passed
c=fread(s,'char'); %c is set newly to y(sent by Arduino) to re-enter into if
end


Arduino code
Code: [Select]

int matlabData[3]={0,0,0}; //row of three elements

void setup(){

  Serial.begin(9600);
}

void loop()
{
  if(Serial.available()>0) // store the MATLAB data into the array
  {
    for (int i=0; i<3; i++)
    {
      matlabData[i]=Serial.read();// read data
    }
  }
    delay(1000);
      for (int i=0; i<3;i++)
      {
      Serial.print(matlabData[i]); //send data back to matlab, and store into the matlab variable
      }
      delay(3000); //wait three seconds (simulation of robot movement)
      Serial.print('y'); //yes means the movement has been completed and send the value to matlab
     
    }

UKHeliBob

Code: [Select]

  if(Serial.available()>0) // store the MATLAB data into the array
  {
    for (int i=0; i<3; i++)
    {
      matlabData[i]=Serial.read();// read data
    }
  }


Summary : make sure that at least one byte of data is available.  Read three bytes even if only one is available

Query : what happened to the other 3 rows ?

Comment : Serial.read() reads a byte up to 255 in value but some of the values in Matlab are greater than 255 or negative.  Will that work ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

m_dal

So have I to convert the numeric value into a char and then reconvert it into integer using atoi() function?

PaulS

Quote
So have I to convert the numeric value into a char
No. You have to convert the value to a string (a NULL terminated ARRAY of chars).
The art of getting good answers lies in asking good questions.

Go Up