Go Down

Topic: MATLAB communication timeout (Read 682 times) previous topic - next topic

wrxth

Sep 25, 2013, 01:30 am Last Edit: Sep 25, 2013, 01:41 am by wrxth Reason: 1
I'm trying to connect my Arduino mega 2560 with MATLAB.
The idea for the codes is: MATLAB sends a character ('A' first, and then 'B') to arduino,  based on the character MATLAB sent, arduino sends the data back accordingly. Arduino sends the data read from analog pin A0 when it receives 'A' and the data from pin A1 when receives 'B'. Then MATLAB plot the calculated function in 3D. I put them into a loop, so the code will keep sending A and B, and keep receiving data from arduino.
But when I launched the MATLAB script, an warning saying "Warning: A timeout occurred before the Terminator was reached." showed up. This warning only showed up for once at the beginning, and then the script worked fine. That means the MATLAB script sent the first 'A' to arduino and was stuck at reading the data sent by Arduino. After showing the timeout warning, MATLAB aborted reading from arduino and sent 'B'. Then the rest of the loop behaved as expected. To be visualized, the script behaves like this: (MATLAB: send 'A') -> (Arduino: send A0) -> (MATLAB: send 'B') -> (Arduino: send A1) -> (MATLAB: send 'A') -> (Arduino:send A0) -> (MATLAB: send 'B') -> (Arduino: send A1).....so MATLAB stuck at the red part and then aborted (skipped?) it.

How to fix this problem?

The code for Arduino:
Code: [Select]

float distanceA = 0;
float distanceB = 0;
char selc = 'N';

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

void loop(){
 selc = Serial.read();  //Read the character sent from MATLAB
 
 switch(selc){
   case 'A':               //If MATLAB sent 'A'
   distanceA = analogRead(A0);  //Get the reading from A0
   Serial.println(distanceA);    //Send the data back to MATLAB
   delay(5);
   break;
 
   case 'B':              //If MATLAB sent 'B'
   distanceB = analogRead(A1);  //Get the reading from A1
   Serial.println(distanceB);
   delay(5);
   break;
 }
}


Code for MATLAB:
Code: [Select]

%clear the COM port
clear
delete(instrfindall);

%setup for 3D plotting
u=[-20:1:20];
v=[-20:1:20];
[U,V]=meshgrid(u,v);
sigma = 6;

%connect to serial port and set baud rate
s1 = serial('COM3','BaudRate', 115200);

% open connection and send identification
set(s1, 'terminator', 'LF');
fopen(s1);
fprintf(s1, '*IDN');

for index = (1:100)   %loop from 1 to 100
       
       %send character 'A' to Arduino
       fprintf(s1,'%c','A');
       
       %read the data analogRead(A0) sent by Arduino
       AVal(index) = str2double(fgets(s1));   // will get stuck at here for the first time
       
       %Calcuations    
       H1=AVal(index)*exp(-((U+10).^2+(V+10).^2)./2/sigma^2);
       
       %send character 'B' to Arduino
       fprintf(s1,'%c','B');
       
       %read the data analogRead(A1) sent by Arduino
       BVal(index) = str2double(fgets(s1));
       
       %Calculations
       H2=BVal(index)*exp(-((U+10).^2+(V-10).^2)./2/sigma^2);
       
       surf(u,v,H1);  %Plot the first graph
       axis([-20 20 -20 20 0 200]);
       hold on;
       surf(u,v,H2);  %Plot the second graph
       hold off;
       drawnow;
end

[color=green]%close the port and delete it[/color]
fclose(s1);
delete(s1)
clear('s1')
delete(instrfindall)

PaulS

Code: [Select]
  selc = Serial.read();  //Read the character sent from MATLAB
Regardless of whether there is anything to read, or not. Bad idea.

Code: [Select]
    delay(5);
Why? You are sending data only in response to input. So quit farting around, and see if there is more data.

Code: [Select]
fopen(s1);
This resets the Arduino.

Code: [Select]
fprintf(s1, '*IDN');
Without waiting for the Arduino to get ready, jam some data out. Then. block waiting for a response. Hmmm, why does that feel like a bad idea?

Go Up