Ардуина долго принимает (или обрабатывает?) данные из serial
- Войдите на сайт для отправки комментариев
Втр, 04/06/2013 - 08:20
Здравствуйте. В ардуину из монитора порта на скорости 115200 отправляется строка вида: a200,200,200,200,100,100,100,100,100,100,100,100,100 где:
а- символ начала передачи, значения - значения канала управления, запятые - это разделители каналов.
После нажатия кнопки "отправить" и зажигания светодиодов на ардуине проходит 5-7 секунд. Не могу понять-почему так происходит.
#include <Servo.h>
int Kn1 = 4; //канал кнопки 1 подключен к 4 пину
int Kn2 = 7; //...
int Kn3 = 8;
int Kn4 = 9;
int Kn7 = 10;
int Kn8 = 12;
int Kn9 = 13;
// int Kn11 = ...; //не хватило пинов
// int Kn12 = ...; //не хватило пинов
int KanA, KanB, KanC, KanD, KanE, KanF, KanJ, KanH, KanI, KanG, KanK, KanL, KanM;
Servo M1; //мотор 1 (горизонтального перемешения) подключен к 3 пину
Servo M2; //мотор 2 (горизонтального перемешения) подключен к 5 пину
Servo M3; //мотор 3 (вертикального перемешения) подключен к 6 пину
Servo M4; //мотор 4 (вертикального перемешения) подключен к 11 пину
void setup()
{
Serial.begin(115200);
M1.attach(3);
M2.attach(5);
M3.attach(6);
M4.attach(11);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
void loop()
{
while (Serial.read() != 'a'); //начало передачи данных с символа "а" и далее каждый канал через запятую. (значения от -255 до 255)
KanA = Serial.parseInt();
KanB = Serial.parseInt();
KanC = Serial.parseInt();
KanD = Serial.parseInt();
KanE = Serial.parseInt();
KanF = Serial.parseInt();
KanJ = Serial.parseInt();
KanH = Serial.parseInt();
KanI = Serial.parseInt();
KanG = Serial.parseInt();
KanK = Serial.parseInt();
KanL = Serial.parseInt();
KanM = Serial.parseInt();
// + Канал А (двигатель 1)
KanA=map(Serial.parseInt(), -255, 255, 20,160);
M1.write(KanA);
// + Канал B (двигатель 2)
KanB=map(Serial.parseInt(), -255, 255, 20,160);
M2.write(KanB);
// + Канал C (двигатель 3)
KanC=map(Serial.parseInt(), -255, 255, 20,160);
M3.write(KanC);
// + Канал D (двигатель 4)
KanD=map(Serial.parseInt(), -255, 255, 20,160);
M4.write(KanD);
// Канал E (соответствует кнопке 1 на пульте- фикс)
// Канал F (соответствует кнопке 2 на пульте- фикс)
// Канал J (соответствует кнопке 3 на пульте- фикс)
// Канал H (соответствует кнопке 4 на пульте- фикс)
// + Канал I (соответствует кнопке 7 на пульте)
if (KanI > 0) {digitalWrite(Kn7, HIGH);}
else {digitalWrite(Kn7,LOW);}
//Канал G (соответствует кнопке 8 на пульте)
if (KanG > 0) {digitalWrite(Kn8, HIGH);}
else {digitalWrite(Kn8,LOW);}
//Канал K (соответствует кнопке 9 на пульте)
if (KanK > 0)
{digitalWrite(Kn9, HIGH);}
else
{digitalWrite(Kn9,LOW);}
// Канал L (соответствует кнопке 11 на пульте)
// Канал M (соответствует кнопке 12 на пульте)
}
зачем в map опять с порта считываете данные, если у вас выше уже все считано
м/б надо было так сделать
M1.write(map(KanA, -255, 255, 20,160));После нажатия кнопки "отправить" и зажигания светодиодов на ардуине проходит 5-7 секунд. Не могу понять-почему так происходит.
А если после последней сотки поставить,скажем, запятую? Отправить строку
a200,200,200,200,100,100,100,100,100,100,100,100,100,
Есть задержка? (после внесения поправки предложенной Michal)
А еще, после своих parseInt, можете добавить
Serial.print(millis()); Serial.println(": Command parsed");Что-бы разделить "мухи и котлеты". Узнать где дуплеж происходит, на приемке данных или на исполнении команды.
При вызовеparseInt() задержка ожидания последующего символа по умолчанию 1 секунда, функцией setTimeout() можно изменить эту задержку, в вашем случае при скорости 115200 достаточно 1-2 мс.Просто добавьте в setup() строку:
void setup() { Serial.begin(115200); Serial.setTimeout(2); ......и будет вам счастье.
При вызовеparseInt() задержка ожидания последующего символа по умолчанию 1 секунда, функцией setTimeout() можно изменить эту задержку, в вашем случае при скорости 115200 достаточно 1-2 мс.timeOut можно и не трогать (он как раз, может не лишним оказатся, хотя-бы для своевременного обнаружения проблем). Вы предлагаете уменьшить timeOut но ведь он не на ровном месте возник. При норме - он вообще не должен срабатывать (и не важно в какой интервал он выставлен).
1. parseInt() - должен вызваться именно столько раз сколько данных послали (поправка от Michal)
2. После последней цифры желательней терминатор, означачющий что "передача закончена". Это может быть "добавить запятую" (для проверки этой версии я предложил) или просто в терминали выставить "line ending"
setTimeout() в данном случае будет лечением больного зуба с помощью обезболивающих. Вроде "помогло", но воспаление осталось. Оно может пролечить проблему "последней цифры", но зато скроет проблемы лишних вызовов (и всех подобных ошибок). Причем скроет подло - будут выскакивать нули, "не те цифры", непонятно откуда берующиеся.
Не говоря уже про то, что timeOut-ты - это, все-таки, блокировка скетча. Которые обычно - не желательны.
Вообщем не нужно timeOut-ты, нужно причину лечить: не делать лишних вызовов и после последней цифры, тем или иным способом послыать что-то не цифвровое.
Может 5 - 7 секунд это и есть тот самый Timeout в 1 секунду (во времени все по разному ориентируются) и если конец строки это цифра - то вот вам и таймаут. Поставить запятую в конце решение конечно же лучше.
Может 5 - 7 секунд это и есть тот самый Timeout в 1 секунду (во времени все по разному ориентируются) и если конец строки это цифра - то вот вам и таймаут. Поставить запятую в конце решение конечно же лучше.
Ну "Запятую" - это чисто проверить догадку. Красивей, все-таки просто слать \r\n
После исправления кода на:
1 M1.write(map(KanA, -255, 255, 20,160));
стало работать мгновенно. Больше никакие манипуляции делать не пришлось. Большое спасибо.