Ардуина долго принимает (или обрабатывает?) данные из 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 опять с порта считываете данные, если у вас выше уже все считано
м/б надо было так сделать
После нажатия кнопки "отправить" и зажигания светодиодов на ардуине проходит 5-7 секунд. Не могу понять-почему так происходит.
А если после последней сотки поставить,скажем, запятую? Отправить строку
a200,200,200,200,100,100,100,100,100,100,100,100,100,
Есть задержка? (после внесения поправки предложенной Michal)
А еще, после своих parseInt, можете добавить
Что-бы разделить "мухи и котлеты". Узнать где дуплеж происходит, на приемке данных или на исполнении команды.
При вызове
parseInt() задержка ожидания последующего символа по умолчанию 1 секунда, функцией setTimeout() можно изменить эту задержку, в вашем случае при скорости 115200 достаточно 1-2 мс.Просто добавьте в setup() строку:
и будет вам счастье.
При вызове
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));
стало работать мгновенно. Больше никакие манипуляции делать не пришлось. Большое спасибо.