Официальный сайт компании Arduino по адресу arduino.cc
Что-то со считыванием из Serial...
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
И снова всем привет! Мужики, помогите мне разобраться с таким моментом: есть заинтересовавшая меня статья https://habrahabr.ru/post/167209/ в которой снизу есть такой код:
#include <Servo.h> Servo myservo; void setup() { Serial.begin(9600); } String getParam(){ String re; while (Serial.available()) { re.concat(Serial.read()-48); } return re; } int getPin(String p){ return p.substring(0,2).toInt(); } int getVal(String p){ return p.substring(2,6).toInt(); } // Главный цикл void loop() { while (Serial.available()) { char command = (char)Serial.read(); String param = getParam(); int pin = getPin(param); int p; switch (command) { case '0': //Digital write pinMode(pin,OUTPUT); digitalWrite(pin, LOW); break; case '1': //Digital write pinMode(pin,OUTPUT); digitalWrite(pin, HIGH); break; case '2': //Servo myservo.attach(pin); p = getVal(param); myservo.write(p); break; case '3': //Digital read pinMode(pin,INPUT); Serial.print(digitalRead(pin)); break; case '4': { //Analog read int aPin = A0; switch (pin) { case 1: aPin = A1; break; case 2: aPin = A2; break; case 3: aPin = A3; break; case 4: aPin = A4; break; case 5: aPin = A5; break; } Serial.print(analogRead(aPin)); } break; case '5': //Analog write pinMode(pin,OUTPUT); p = getVal(param); analogWrite(pin, p); break; } } }
Исходя из статьи, если залить этот код в дуинку и отправить по Serial "113" должен включиться 13 пин...Если отправит 013 - выключиться (это написано в статье под самим кодом)... В итоге все работает на моих 2х китайских МЕГАх как то не так... Не буду вспоминать сколько я игрался с этим в часах, но заработал этот код только тогда, когда я скорость поменял на 115200 и после строки "char command = (char)Serial.read();" добавил еще 2:
Serial.print("command="); Serial.println(command);
Как я понимаю, эти 2 строки всего лишь создали небольшую временную задержку, без них байтики начинают пропадать... Если вернуть скорость на 9600 и отправить команду "113" то все цифры попадают в эти две строчки и ответ приходит:
command=1 command=1 command=3
Получается, что функция getParam() не работает... Буду благодарен любой помощи.
Так поставьте вместо 12-ой строки три такие:
"сразу прояснится на доске"
В приведённом коде отсутствует обработка ошибок, отсутствует проверка на то, что команда принята полностью. Это - как минимум, глубже не смотрел.
Я не раз повторял уже, повторю ещё раз: чтение "в лоб" по Serial.available - самая хадшая идея из тех, что могут возникнуть. Вот смотрите: вы попали в очередной вызов loop, проверили Serial.available - есть что-то там в порту, начали читать всё, что упало в буфер. И потом - начали выполнять свои действия в зависимости от того, что в буфере UART покладено/положено/зарыто.
НО! В буфер могли ещё не упасть все символы, переданные с той стороны, с чем вы, собственно, и столкнулись.
Как это решается при вдумчивом подходе? Обычно - вводят нечто вроде стоп-последовательности, при получении которой мы понимаем, что в буфере накопилась вся команда, переданная нам извне. Можно юзать хоть три 0xFF подряд (как делает дисплей Nextion), хоть символы новой строки (\r\n) - тут каждый пляшет, как умеет.
В итоге, псевдокод выглядит как-то так:
В приведённом коде, кстати, тоже нет контроля максимальной длины пакета - можно засрать оперативу, посылая какие угодно символы, кроме \n ;) Но всё дописывается парой строчек.
Ещё раз убеждаюсь, что over9000 провентов примеров из статей в интернете - стоит рассматривать только как примеры. Как плохие примеры.
Так поставьте вместо 12-ой строки три такие:
"сразу прояснится на доске"
Сделал так:
Ругается на re.concat(с); Говорит
Arduino: 1.6.5 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
Ругается на re.concat(с); Говорит
Во ж блин, никогда не попадал на такие ошибки еще... Спасибо - буду знать... Итого результат отправки 113 на скорости 9600 ="1"... отправка 013 дает тот же результат...
Во ж блин, никогда не попадал на такие ошибки еще... Спасибо - буду знать... Итого результат отправки 113 на скорости 9600 ="1"... отправка 013 дает тот же результат...
Вы что-то невнятное написали. Лог скопипастите из сериал-монитора сюда.
DIYMan, спасибо за пояснение... Возможно, как раз это именно мой случай... Попробую провернуть нечто подобное сейчас. Спасибо!
ЕвгенийП, отправляю (кавычки не в счет) "113" а в монитор просто единица выскакивает одна-одинёшенька... Похоже очень на то, про что говорил DIYMan... Как я понял код, первая единица из "113" вылавливается и отправляется в блок свич-кейс, а все что за ней следует - в функцию getParam(),из которая потом сабстрингами вынимаются нужные циферки (поправьте если я не прав)... И в итоге данные еще не успели все сложиться в буфер, а дуинка их уже поперла обрабатывать... Это всего лишь мое предположение на основе многочасовой камасутры с этим кодом...
здесь #76 DigiUSB замени на Serial и юзай.
*не в первый раз наталкиваюсь на дурное пользование циклов - походу, какая-то эпидемия.
Клапауций 322, благодарю! Поразбираюсь что там и зачем... А может кто-нибудь посоветует статейку, в которой использую ту же связку ардуино-питон-веб страничка, в которой будет попонятнее объясняться вся эта схема? А то что-то в ссылке с первого поста все никак не запускается нифига то одно, то другое... Косяков там мелких дофига и догонять их времени вагон уходит. Интересует, чтобы дуинка общалась с веб-страничкой именно через УАРТ.