matlab arduino serial

I am trying to send a number from matlab to an ATmega168 on an arduino duemilanove. I have spent the last three days working on this, but I am no longer making any progress. Despite reading these forums, (and there seems to be quite a bit on this topic) I can not find where I am going wrong.

here is my matlab code:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% this program will send a number to an ATmega168 over serial and then
%%% receive a message indicating that the number was recieved correctly
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear all;
close all;

s = serial('COM3', 'BaudRate', 9600);
fopen(s);

pause(.01);

B = 1023;

fwrite(s, B,'uint8','sync');

pause(.01);

%i = 0;
%if i<6
%    fscanf(s)
%    pause(.01);
%    i = i+1;
%end

fscanf(s)
pause(.01);
fscanf(s)
pause(.01);
fscanf(s)
pause(.01);

display('done');

fclose(s);
delete(s);

You can see where I tried making an if statement in matlab to scan the serial port a specified number of times but this did not work. It seems that there should be a better way to do this.

here is my arduino code:

// this program receives a number from matlab and then sends the number back to matlab

// variable declerations

  int incomingByte = 0;               // variable for incoming serial data
  unsigned long num=0;             // variables for num (values should range from 0 to 1023)
  int i =0;                        // variable used for counting
  
  void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

  Serial.print("DEBUG: setup done\r\n");  
}

void loop()
{
  Serial.print("DEBUG: waiting on number\r\n");
  
  if (Serial.available() > 0)                         // check to see if there is data in the bus
  {
  // read the incoming byte:
    Serial.print("DEBUG: received number\r\n");

    for(i=0; i<4; i++)                               // read four bytes in sequence from serial port and
    {                                           // put them together into one unsinged long variable which is four bytes.

      while(Serial.available()==0)                   // Wait until the next byte becomes available
      {
      }

      incomingByte = Serial.read();                   // Get a byte
      num = num | (incomingByte << (8*i));               // Compile a variable from the bytes you got
    }

// say what you got:
  Serial.print("I received: ");
  Serial.print(", ");
  Serial.print(num, DEC);

  Serial.flush(); //Flush serial input buffer before the next cycle

  }

}

On the command window in matlab the following is displayed:

DEBUG: setup done
DEBUG: waiting on number
DEBUG: waiting on number
done

This indicates to me that the number is never sent to serial, so maybe the problem is in matlab. Any suggestions?

This indicates to me that the number is never sent to serial

Not necessarily. The problem could lie the other way round.

Change the Arduino code to turn on the built-in LED when anything arrives on the serial port. Does the LED light?

Change the Arduino code to turn on the built-in LED when anything arrives on the serial port. Does the LED light?

Here is what I did:

// this program receives a number from matlab and then sends the number back to matlab

// variable declerations

  int incomingByte = 0;               // variable for incoming serial data
  unsigned long num=0;             // variables for num (values should range from 0 to 1023)
  int i =0;                        // variable used for counting
  int ledPin = 13;                 // LED connected to pin 13
  
  void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  pinMode(ledPin, OUTPUT);
  Serial.print("DEBUG: setup done\r\n");  
}
  
void loop()
{
  Serial.print("DEBUG: waiting on number\r\n");
  
  // flash the led until you receive the number
  digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  
  if (Serial.available() > 0)                         // check to see if there is data in the bus
  {
  // read the incoming byte:
    
    digitalWrite(ledPin, HIGH);                          // keep the led on (indicates the number has been sent)
    
    Serial.print("DEBUG: received number\r\n");

    for(i=0; i<4; i++)                               // read four bytes in sequence from serial port and
    {                                           // put them together into one unsinged long variable which is four bytes.

      while(Serial.available()==0)                   // Wait until the next byte becomes available
      {
      }

      incomingByte = Serial.read();                   // Get a byte
      num = num | (incomingByte << (8*i));               // Compile a variable from the bytes you got
    }

// say what you got:
  Serial.print("I received: ");
  Serial.print(", ");
  Serial.print(num, DEC);

  Serial.flush(); //Flush serial input buffer before the next cycle

  }

}

The code blinks the led when it is waiting on the number (this is working) and is supposed to keep the led on once it receives the number until it starts waiting for the number again (don’t know if this is working).

This is what happens: before I run the matlab program the led is blinking, when I run the matlab program the led stops blinking until “done” is displayed in the matlab command window, then the led blinks until I run the matlab program again. The same DEBUG statements are displayed as before.

Does fwrite, in matlab, have a return code that you are ignoring?

It looks to me like you are telling matlab to send the integer value 1023 in byte-sized pieces. That may result in sending only 2 bytes. Does B have a type?

The Arduino, then, is waiting for all 4 of them.

PaulS

I am not sure what you mean by return code. Also, If only 2 bytes are sent by matlab and the arduino is just waiting on the other two, the "DEBUG: received number" statement should have been displayed in the matlab command window, right? Can you tell me what makes you think that only two bytes are being sent?

is supposed to keep the led on once it receives the number until it starts waiting for the number again (don't know if this is working)

It is not. Remove the four lines of code that blink the LED.

Does the LED light when you run the test?

Does the LED flicker when you run the test?

You have a statement like s = serial(...) in the matlab code. This means that the serial function returns a value.

Typically code that writes to the serial port (fwrite) returns the number of bytes written to the port.

Since B contains an integer value, and integers are 2 bytes, I suspect that fwrite is sending 2 bytes. I don't know if B is typed anywhere (in C/C++/C#, etc. variables have types. In PHP, they do not). If so, what is it's type? If not, is there any way to know how many bytes are actually sent?

The DEBUG statement will be returned after 4 bytes have been successfully read from the serial port, by the Arduino. If it's not getting sent, that is a pretty good indication that there are not 4 bytes to read.

As a test, change the loop to only expect to read 2 values. What happens?

Try this basic sending of a string from the MATLAB program.

http://www.arduino.cc/playground/Interfacing/Matlab

Coding Badly,

The reason I said, that I did not know if it was working (the LED staying on in the if statement), was because I still do not think that the if statement is being satisfied (that is i do not think that arduino is seeing anything in the serial port or matlab is not sending anything). I removed the blinking LED part of the code, but kept the LED code in the if statement. There was no difference between having the code for the LED in the if statement or not having it there. I even put a delay of 5 seconds after the LED statement in the if statement, but it still never came on. Now, it did flicker, but it also flickered when there was no LED code.

PaulS,

In the for loop I changed i<4 to i<2 which should make it so that it expects only two bytes instead of four. This did not appear to change anything.

Thank you guys very much for you help so far, I will really appreciate any further suggestions.

I believe, opening the serial port resets the Arduino.

Increase the first delay so the Arduino has time to “boot”…

s = serial('COM3', 'BaudRate', 9600);
fopen(s);
pause([glow]5.0[/glow]);
B = 1023;
fwrite(s, B,'uint8','sync');

PaulS,

I found that I can do the following to find out about a variable in matlab:

B = 1023; whos B

which returns:

Name Size Bytes Class

B 1x1 8 double array

Now, I can change the number of bytes used to construct the variable, or I can make it so that the arduino code expects 8 bytes. I tested it by making arduino expect 8 bytes, but this did not change anything.

Coding Badly,

I tried making that pause 5 seconds and even 10 seconds, but I got the same results as before.

I also tired doing what InvalidApple suggested. I wrote, as simply as I can image, code in matlab and arduino to do a hello world type test. here is what I did in matlab:

clear all;
close all;

display('begin');

s = serial('COM3', 'BaudRate', 9600);
fopen(s);

%pause(1);

fwrite(s, 'hello arduino','sync');

%pause(1);

fscanf(s)
pause(.01);

display('done');

fclose(s);
delete(s);

and in arduino:

 void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
  
void loop()
{ 
  if (Serial.available() > 0)                         // check to see if there is data in the bus
  {
     Serial.print("Hello Matlab\r\n");
  }
}

When I tested this, Hello Matlab was displayed in the matlab command window!! This is good? Now, I am confused... Since this code works, when I test my original code the "DEBUG: received number" statement should be displayed, since the DEBUG statement just takes the place of the Hello Matlab statement, right? What is this implying??

To your original test program, make this change...

// say what you got:
  Serial.print("I received: ");
  Serial.print(", ");
  Serial.print(num, DEC);
  [glow]Serial.print("\r\n");[/glow]

HI! I'm also working in the communication between Matlab and arduino, and there is a problem that I can not understand

if I type the lines in the command window separately, ardiuno is recieving them and making what I want,

but If I put the lines in the function, then arduino don't get it... I'm totally lost... could anyone help me??? thank you! the sample function is the following!

function com(pols, compas) global s; s= serial('COM3', 'BaudRate', 9600, 'Parity', 'none', 'DataBits', 8,'StopBits',1); fopen(s); fwrite(s,3) fwrite(s,2) for i=1:(pols*compas) val=fscanf(s); end end

thank you!!!

fopen(s);
fwrite(s,3)
fwrite(s,2)
for i=1:(pols*compas)
   val=fscanf(s);

Unless you have modified your Arduino, opening the serial port resets the Arduino. Before the Arduino is ready, you jam some data at it, and expect a response. The Arduino may not be sending anything because it doesn't know it needs to.

Posting the Arduino code might have been useful.

Here is the loop,

void loop() { while(Serial.available()==0); tempo = Serial.read(); while(Serial.available()==0); compas = Serial.read(); digitalWrite(ledPin, HIGH); captant=1; while (go==0) Serial.println(tempo); }

When I send within the command window the instruccions the led become lighted, but when I execute the function don't...

Thank you!

Posting the Arduino code might have been useful.

Or not.

Have you modified the Arduino to not reset when the serial port is opened?

Have you tried putting in a small delay between opening the serial port and the sending of data in your matlab function?

YES!!!!!!! Thank you!

fopen(s); pause(2); fwrite(s,3) fwrite(s,2)

you had reason when opening reset!!!!! if I pause during 2 seconds then is perfect!!! THAAAAAAAAANK YOU!!!