2
votes

Update 2: Turns out adding a pause(2) after opening the serial port was all it needed.

Update: I am able to manually enter the Matlab code into the Matlab command window and it will update the LEDs as expected, but I cannot call my function that does so. I will try adding time delays, perhaps the Arduino buffer cannot keep up.

I am using an Arduino Uno with the Sparkfun PWM shield to control 3 LEDs. I have written an Arduino sketch that looks for serial input to set the LED values, and Matlab code that prepares and sends the serial output. See all the code below.

For some reason this code, which was working several months ago, has stopped working. I am using 2011b version of Matlab now, and was using 2013a before. Nothing else has changed.

I believe the issue is with the serial communication, as I can get it to work by having Matlab and Arduino IDE running at the same time, opening the serial monitor in Arduino IDE, then issuing the Matlab command. It sets the LED values as desired. In order to send another command I need to first close, and re-open the Arduino serial monitor.

Matlab code:

function [] = displayColor(RGB)

s1 = serial('/dev/tty.usbmodem1411','BaudRate',9600);

fopen(s1)

messageRed = bitshift(1,12)+RGB(1);
messageGreen = bitshift(2,12)+RGB(2);
messageBlue = bitshift(3,12)+RGB(3);
fwrite(s1,messageRed,'uint16','sync');
fwrite(s1,messageGreen,'uint16','sync');
fwrite(s1,messageBlue,'uint16','sync');
updateMessage = 0;
fwrite(s1,updateMessage,'uint16','sync');

fclose(s1)

end

Arduino code:

#include "Tlc9540.h"
int newVal = 0;

void setup(){
Tlc.init();
Serial.begin(9600);
delay(1000);
}

void loop(){

updateChannel();  

}

int updateChannel()
{

int B;
int code;
int value;

  if (Serial.available())
  {
    //Read First Byte
    B = Serial.read();
    //Blocking - waiting for second byte
    while (!Serial.available()){}
    B+=Serial.read()<<8;
    code = (B&(B1111<<12))>>12;
    value = B&4095;
    switch (code)
    {
      case 0:
        Tlc.update();
        break;
      case 1:
        Tlc.set(0,value);
        Serial.print(Tlc.get(0));
        break;
      case 2:
        Tlc.set(1,value);
        Serial.print(Tlc.get(1));
        break;
      case 3:
        Tlc.set(2,value);
        Serial.print(Tlc.get(2));
        break;
    }
  }  
}
2
Maybe it's a silly question, but are you sure your USB/serial adapter is still /dev/tty.usbmodem1411?ChrisJ
Hey @ChrisJ, yeah - currently I just manually check the serial port and update when necessary.Alex
Can you talk to you Arduino board using the Arduino application alone and no Matlab (one of the examples that uses serial, e.g.)? Is the Arduino application set to use /dev/tty.usbmodem1411 as well? Also, make sure that you read the archived documentation for 2011b rather than the new stuff you might find via Google (or just use help and doc).horchler
Hey @horchler. The Arduino application is set to use the same port. I can communicate with the board directly through the app - I wrote another bit of code for sending simple integer commands to set the LED values through Arduino Serial Monitor command line. I don't know how to pass the same bit input Matlab is sending through the Arduino serial monitor however.Alex
@Alex, can you put your update as an answer and mark it as accepted, so this question shows as answered? Thanks.dsolimano

2 Answers

0
votes

In order to engage the Arduino over the serial port through Matlab it seems to need a time delay of ~2 seconds. Adding a delay before starting to send data over the serial line did the trick.

0
votes

I solved that problem by setting my own serial terminator (I used ! as terminator). And when I send a serial command, I use ! as terminator.

set(arduino,'Terminator','!'); % setting my terminator

then in my code:

test_free = 'mode=free,axis=1,dir=1,speed=50,pos=13245!';
fprintf(arduino,test_free);

I think that the problem is that matlab is waiting for a terminator. Than if there's not fullfilling, timeout is executed and set to 2sec. That's why execution is possible after a delay bigger than timeout.