Serial Communication of Matlab and Arduino through GUI

Hey all,

I am working on making a GUI that takes in Three(3) 'int' values from the user separated by commas (i.e. 1000,1000,1000) and sends that entire string through the COM port to the Arduino which uses those 3 int values as the delay() time input for each of the 3 LEDs.

I have it working to the point where:

  1. the user can select the COM port from the GUI that the Arduino is connected to

  2. user can enter the 3 'int' values into a "edit text" box separated by commas as mentioned above

  3. then the GUI code retrieves that string and saved it to a variable called: xyz

  4. using the command fprintf(s,xyz), where "s" is the serial object, the value of xyz is sent to the Arduino without any errors

  5. the Arduino "RX" led blinks indicating the value from serial port has been received

-- now the problem is that Arduino is not doing anything with the received serial input from matlab! if I used the Arduino IDE's Serial Monitor to send 1000,1000,1000 it does what its suppose to!

So I am thinking Arduino doesn't like the "data type"/"format" of the value im sending through the matlab GUI and I am not sure how to fix this...!

I am a newbie with programing/arduino/matlab so please excuse any novice mistakes. ANY help will be greatly appreciated!!

Below is the TEST Arduino Code and the MATLAB GUI Code:

Thank you guys in advanced!!!

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Relevant MATLAB GUI CODE:

``function stepInput_Callback(hObject, eventdata, handles)

xyz = get(hObject,'String');

disp('Value entered: ')

disp(xyz)

global COM;

global s;

s = serial(COM,'BaudRate',9600);

fopen(s);

disp('After OPEN')

disp(s)

fprintf(s,xyz);

fclose(s);

disp('After CLOSE')

disp(s)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Arduino Code:

``int x;

int y;

int z;

void setup() {

pinMode(2,OUTPUT);
pinMode(6,OUTPUT);
pinMode(10,OUTPUT);
Serial.begin(9600);
}
void loop() {

while (Serial.available()) // check if Serial data is available to read
{
x = Serial.parseInt();
y = Serial.parseInt();
z = Serial.parseInt();
if (Serial.read() == '\n') // check if ENTER has been pressed (newline)
{
digitalWrite(2,1);
delay(x);
digitalWrite(6,1);
delay(y);
digitalWrite(10,1);
delay(z);
digitalWrite(10,0);
delay(z);
digitalWrite(6,0);
delay(y);
digitalWrite(2,0);
delay(x);
}
}
}``

There is a thread called 'Serial Input Basics'. I suggest that you do a sesrch and read that thread.

The basics is that you read a full message, break the received data into pieces based on the commas and use the data.

I think your current code fails due to the commas in the string because you're using parseInt.

PS
To eliminate problems caused by the matlab side of things, you can send the string from serisl monitor. Once the Arduino behaves as you want, you csn concentrate on the matlsb sidr of things.

fprintf(s,xyz);

Does this also send the linefeed after the 1000,1000,1000 ?
If it doesn't you'll never detect that ENTER has been pressed.

If it does, you still have a problem. The third Serial.parseInt will have read the linefeed as the terminator of the third number and so there won't be a linefeed in the buffer when you execute the Serial.read()
In this case, just remove the test for ENTER being pressed and proceed anyway.

Pete

Some one suggested this solution but i am not getting how to make it compatible with my code kindly help using this code and my original arduino code and tell me how to use that code in this one.
void loop() { if (Serial.available()>0) { my_data = Serial.read(); ... } ] // end loop()

Here is the link to Serial Input Basics.

If you can make your PC program send, for example “<1000, 1000, 1000>” and use the 3rd example it will be most reliable.

The parse example illustrates how to separate the values and store them into variables.

…R

Remove the if statement.

while (Serial.available()) // check if Serial data is available to read
{
    x = Serial.parseInt();
    y = Serial.parseInt();
    z = Serial.parseInt();

    digitalWrite(2,1);
    delay(x);
    digitalWrite(6,1);
    delay(y);
    digitalWrite(10,1);
    delay(z);
    digitalWrite(10,0);
    delay(z);
    digitalWrite(6,0);
    delay(y);
    digitalWrite(2,0);
    delay(x); 
 }

Pete

hi pete.
I have tried it but not getting any useful results.
void setup() {
// put your setup code here, to run once:
pinMode(13, OUTPUT);
Serial.begin(9600);
}
i am trying this in matlab
``x =str2num(get(handles.edit1,'String'));

disp('Value entered: ')

disp(x)

delete(instrfind({'Port'},{'COM6'}));
s=serial('COM6');
s.BaudRate=9600;

fopen(s);

disp('After OPEN')

disp(s)

fprintf(s,x);

fclose(s);

disp('After CLOSE')

disp(s)``
after writing value in edit box and entering i get this in matlab command windows.
Value entered:
10000

After OPEN

Serial Port Object : Serial-COM6

Communication Settings
Port: COM6
BaudRate: 9600
Terminator: 'LF'

Communication State
Status: open
RecordStatus: off

Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0

After CLOSE

Serial Port Object : Serial-COM6

Communication Settings
Port: COM6
BaudRate: 9600
Terminator: 'LF'

Communication State
Status: closed
RecordStatus: off

Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 2

and this code in arduino.
``void loop() {
// put your main code here, to run repeatedly:
while (Serial.available()>0) // check if Serial data is available to read
{
int x=Serial.read();
//int x = Serial.parseInt();
//int y = Serial.parseInt();
//int z = Serial.parseInt();

digitalWrite(13, HIGH);
delay(x);
digitalWrite(13, LOW);
delay(x);
/*digitalWrite(13, HIGH);
delay(y);
digitalWrite(13, LOW);
delay(y);
digitalWrite(13, HIGH);
delay(z);
digitalWrite(13, LOW);
delay(z);

}
}``
but not getting the blinking led.

kindly help me in solving this problem as i am in trouble.

For the MatLab part, you’re on your own.

Simple code to do text-based communication. Message format <value1,value2,value3>

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

void loop()
{

  static char buffer[32];
  static char index;
  bool fNewmessage = false;
  bool fError = false;
  if (Serial.available())
  {
    buffer[index] = Serial.read();
    // if not start of message
    if (buffer[0] != '<')
    {
      // bail out
      return;
    }
    // if end of message
    if (buffer[index] == '>')
    {
      // append NUL character
      buffer[index + 1] = '\0';

      // message complete
      fNewmessage = true;
    }

    // increment index
    index++;

    if (index >= sizeof(buffer))
    {
      // error; buffer overflow
      // cleanup
      memset(buffer, 0, sizeof(buffer));
      index = 0;
      // bail out
      return;
    }
  }

  // message not complete yet
  if (!fNewmessage)
  {
    // bail out
    return;
  }

  char *ptrStart = &buffer[1];
  char *ptrSplit;

  int x, y, z;

  // find first comma
  ptrSplit = strchr(ptrStart, ',');
  if (ptrSplit == NULL)
  {
    // error, no comma found
    fError = true;
  }

  // if no error, get value
  if (!fError)
  {
    *ptrSplit = '\0';
    x = atoi(ptrStart);
    ptrStart = ++ptrSplit;
  }

  // find second comma
  ptrSplit = strchr(ptrStart, ',');
  if (ptrSplit == NULL)
  {
    // error, no comma found
    fError = true;
  }

  // if no error, get value
  if (!fError)
  {
    *ptrSplit = '\0';
    y = atoi(ptrStart);
    ptrStart = ++ptrSplit;
  }

  // find endmarker
  ptrSplit = strchr(ptrStart, '>');
  if (ptrSplit == NULL)
  {
    // error, no endmarker found
    fError = true;
  }

  // if no error, get value
  if (!fError)
  {
    *ptrSplit = '\0';
    z = atoi(ptrStart);
  }

  // cleanup
  memset(buffer, 0, sizeof(buffer));
  index = 0;

  // if no error occured
  if (!fError)
  {
    Serial.print("x: "); Serial.println(x);
    Serial.print("y: "); Serial.println(y);
    Serial.print("z: "); Serial.println(z);
  }
}

You can test this with serial monitor; just modify the last part. Next you can modify your MatLab part to use textbased serial communication.

It’s not perfect as there is e.g. no check for negative values or invalid textdata.

haroon_aziz:
kindly help me in solving this problem as i am in trouble.

Did you read Reply #4 and study the link.

...R

yes i did Robin. But i didn't understand it.

sterretje i am not getting anything in serial monitor with your code.

I have tried it but not getting any useful results.

The code you posted in #6 is not the same as what I posted in #5.
You are reading one character and expecting x,y and z to be valid.

If you actually did try my code, what results did you get?

It's also time that you read How to post code properly to make it easier to read.

Pete

pete i have tried your code right now with some modifications in that as i want to see the values of variables in serial monitor.
ok i am posting my matlab and arduino codes again properly so that they are easy to read for the readers.
my matlab code.

xyz =get(hObject,'String');

disp('Value entered: ')

disp(xyz)

delete(instrfind({'Port'},{'COM6'}));
s=serial('COM6');
s.BaudRate=9600;

fopen(s);

disp('After OPEN')

disp(s)

fprintf(s,xyz);

fclose(s);

disp('After CLOSE')

disp(s)

and here is arduino code which i am trying.

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available()) // check if Serial data is available to read
  {
    int x = Serial.parseInt();
    int y = Serial.parseInt();
    int z = Serial.parseInt();

    Serial.println(x);
    delay(1000);
    Serial.println(y);
    delay(1000);
    Serial.println(z);
    delay(3000);
  }
}

haroon_aziz:
sterretje i am not getting anything in serial monitor with your code.

Forget MatLab for now; quit it if it’s running as only one application can use the serial port at a time. Start Serial monitor, type <1000,2000,3000> and it should reply with

x: 1000
y: 2000
z: 3000

@haroon_aziz: Thanks for the code tags.

Why do you need a delay between each number? Use this:

    Serial.println(x);
    Serial.println(y);
    Serial.println(z);
    Serial.println();
   delay(1000);

Now, what do you get in the serial monitor with this change to the code in #12?

Pete

sterretje done .
it has shown what u posted what should i do right now?

Instead of serial printing, implement the x, y and z delays. Note that this code will only flash once (after receiving data).

Next you can modify the MatLab side of things to send a string in the correct format.

haroon_aziz:
yes i did Robin. But i didn't understand it.

I can't help unless you tell me that and tell me what you don't understand.

...R