Проблема с последовательным соединением с Arduino из Matlab

Обновление 2. Оказалось, что достаточно было добавить pause(2) после открытия последовательного порта.

Обновление: Я могу вручную ввести код Matlab в командное окно Matlab, и он обновит светодиоды, как ожидалось, но я не могу вызвать свою функцию, которая делает это. Я попробую добавить задержки, возможно, буфер Arduino не успевает.

Я использую Arduino Uno с экраном Sparkfun PWM для управления 3 светодиодами. Я написал скетч Arduino, который ищет последовательный ввод для установки значений светодиодов, и код Matlab, который подготавливает и отправляет последовательный вывод. Смотрите весь код ниже.

По какой-то причине перестал работать этот код, работавший несколько месяцев назад. Сейчас я использую версию Matlab 2011b, а раньше использовал 2013a. Больше ничего не изменилось.

Я считаю, что проблема связана с последовательной связью, так как я могу заставить ее работать, запустив Matlab и Arduino IDE одновременно, открыв последовательный монитор в Arduino IDE, а затем выполнив команду Matlab. Он устанавливает желаемые значения светодиодов. Чтобы отправить другую команду, мне нужно сначала закрыть и снова открыть последовательный монитор Arduino.

Код Matlab:

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:

#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;
    }
  }  
}

person Alex    schedule 25.02.2014    source источник
comment
Может быть, это глупый вопрос, но уверены ли вы, что ваш USB / последовательный адаптер все еще /dev/tty.usbmodem1411?   -  person ChrisJ    schedule 26.02.2014
comment
Привет, @ChrisJ, да - сейчас я просто вручную проверяю последовательный порт и при необходимости обновляю.   -  person Alex    schedule 26.02.2014
comment
Можете ли вы поговорить с вашей платой Arduino, используя только приложение Arduino, а не Matlab (например, один из примеров, в котором используется последовательный порт)? Приложение Arduino также настроено на использование /dev/tty.usbmodem1411? Кроме того, не забудьте прочитать архивную документацию для 2011b, а не новые материалы, которые вы можете найти через Google (или просто используйте help и doc).   -  person horchler    schedule 26.02.2014
comment
Привет, @horchler. Приложение Arduino настроено на использование того же порта. Я могу общаться с платой напрямую через приложение - я написал еще один фрагмент кода для отправки простых целочисленных команд для установки значений светодиодов через командную строку Arduino Serial Monitor. Однако я не знаю, как передать тот же битовый ввод, который Matlab отправляет через последовательный монитор Arduino.   -  person Alex    schedule 26.02.2014
comment
@Alex, можете ли вы поставить свое обновление в качестве ответа и отметить его как принятое, чтобы этот вопрос отображался как ответ? Спасибо.   -  person dsolimano    schedule 07.03.2014


Ответы (2)


Чтобы задействовать Arduino через последовательный порт через Matlab, кажется, требуется временная задержка ~ 2 секунды. Добавление задержки перед началом отправки данных по последовательной линии помогло.

person Alex    schedule 09.03.2014

Я решил эту проблему, установив свой собственный терминатор последовательного порта (в качестве терминатора я использовал !). И когда я отправляю последовательную команду, я использую ! как терминатор.

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

тогда в моем коде:

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

Думаю, проблема в том, что Матлаб ждет терминатора. Тогда, если нет полного заполнения, выполняется тайм-аут и устанавливается на 2 секунды. Поэтому выполнение возможно после задержки, превышающей таймаут.

person Gabriel    schedule 23.06.2015