Qt + Arduino через serial

Coleman
Offline
Зарегистрирован: 21.06.2017

Всем доброго времени суток. Имеется задача - управление сервомашинками, подключенными к ардуино, с компьютера, через приложение написанное на Qt. Управление осуществляется по нажатию клавиш на клавиатуре (к примеру, вперед - W). На qt код реализовал, по нажатию кнопки формирую массив qbytearray, Заношу в него данные, далее отправляю в com. К каждой передаче данных добавляю в конце символ, например t, чтобы ардуино могла понять, на какую серву посылать сигнал. Данные в com доходят, но ардуино не реагирует на них. В скетче использую readstring(). Да, если не добавлять сигнал и не разбивать данные внутри массива qbytearray, то ардуино обрабатывает приходящие числа. В чем причина? Знаю что ардуино считывает данные из com побайтово, но я использую readstring, который собирает данные.

Код qt:

if (key==Qt::Key_W && port->open(QIODevice::WriteOnly))
    {
                        if (low<245){
                        low=low+12;
                        //thr2=120;
                        ui->lineEdit_2->setText(QString::number(low));
                        data.clear();
                        data = QByteArray::number(low) + "t";
                        port->write(data);
                        port->waitForBytesWritten();
}
         port->close();
}

Код arduino:

String a;
int x;
void setup() {

Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode (13,OUTPUT);
}

void loop() {

while(Serial.available()) {

a= Serial.readString();// read the incoming data as string


if (a.endsWith("t")){
  x=a.toInt();
  if (x == 137) 
  {
    digitalWrite(13, HIGH);
  }
}

}

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Откуда видно, что доходят нормально? По мне, так нет. Поставьте печать, убедитесь сами.

К Вам приходит один байт (ну, максимум два). Вы не дождавшись остальных хватаете его в свою строку a и радостно смотрите, есть ли там t на конце. Нету. Вы ждетё следующего байта и теперь его хватаете в строку a (попутно выбросив в мусорку то, что прочитали раньше). Опять сравниваете его с t ... и так далее пока не получите t. Получив, Вы пытаетесь выжать из этой бедной буквы t число, которые Вы предварительно благополучно выбросили за ненадобностью, а его там и нету (ну, мож последняя цифра осталась случайно).

Вам надо считывать всю информацию до буквы t, не выбрасывая то, что считалось раньше.

Для проверки, можете после строки 11 поставить delay(500) - если я описал правильный сценарий, то всё сработает. Только не забудьте потом delay выбросить и сделать чтение по уму.

Coleman
Offline
Зарегистрирован: 21.06.2017

Нет, не работает с delay. Если я отправляю данные из монитора порта, то работает в моем исходном варианте без delay. Как только я пытаюсь отправить данные через qt, ничего не происходит. Я думаю что дело в том, как qt отправляет данные на com.

b707
Offline
Зарегистрирован: 26.05.2017

Coleman пишет:

Если я отправляю данные из монитора порта, то работает в моем исходном варианте без delay. Как только я пытаюсь отправить данные через qt, ничего не происходит. Я думаю что дело в том, как qt отправляет данные на com.

Это легко проверить - уберите в коде Qt все слозжные байт-преобразования и отправьте нужную строчку просто в виде текста, как вы это делали вручную.

И прислушайтесь к словам Евгения - вы неправильно получаете данные из Serial. Вы, видимо, считаете, что команда Serial.readString()  "собирает" данные, пока не получит признак конца строки. Это не так.

Coleman
Offline
Зарегистрирован: 21.06.2017

>data = QByteArray::number(low) + "t";

Это и есть простая строчка в виде текста. Делал еще вот так - port->write("137t"); посылка идет как массив символов. Все равно 0 реакции. Попробовал уже даже сторонние программы по управлению com, отправляя данные с них, все работает. Да, за delay спасибо, убрались ложные срабатывания светодиода по нажатию кнопки.

b707
Offline
Зарегистрирован: 26.05.2017

Coleman пишет:

Делал еще вот так - port->write("137t"); посылка идет как массив символов. Все равно 0 реакции.

ну тогда подключить второй Serial к ардуине, чтобы посмотреть, что она принимает

Coleman
Offline
Зарегистрирован: 21.06.2017
b707
Offline
Зарегистрирован: 26.05.2017

Coleman пишет:

Речь об этом? http://arduino-diy.com/arduino-to-arduino-serial

да как угодно - можно через вторую ардуину, можно через USB-TTL адаптер... Если есть - можно дисплей подключить и выводить диагностику туда

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А скорости-то одинаковые? И другие параметры.

Coleman
Offline
Зарегистрирован: 21.06.2017

Естественно, это первое на что обратил внимание. В общем, сделал вывод в qDebug сообщений с порта. И получил нужное число и букву, но с символами возврата каретки. Использовал

a.replace("\n","");

a.replace("\r","");

и все заработало. Всем спасибо за внимание, проблема решена.

Maximus
Offline
Зарегистрирован: 24.07.2015

 Добрый вечер! Если не жалко, можите выложить код на Qt?