Странное поведение ардуино.
- Войдите на сайт для отправки комментариев
Чт, 06/12/2012 - 20:13
Помогите пожалуйста, а то что-то я совсем запутался. Берем простейший код:
String str = ""; boolean stringComplete = false; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); } void loop() { int cur; if (str == "0" ) { digitalWrite(13, LOW); cur=0; } if (str == "1" ) { digitalWrite(13, HIGH); cur=1; } if (str == "2" ) { Serial.print(cur); } str = ""; stringComplete = false; } void serialEvent() { while (Serial.available()) { char in=(char)Serial.read(); str += in; if (in == '\n') { Serial.print(in); stringComplete = true; } } }
Если в порт записать 1 то LED загорается, если 0 то гаснет. А вот если кинуть 2 то на выходе всегда имеем 0. Более того если записать 22 то на выходе получим 00, если 222 то 000 и т.д. Если писать в порт 111, то LED зажигается, и т.д. Я почему-то по наивности считал что сравнение идет по полной строке а не по выборочному символу. А самое главное непонятно почему при записи 2 всегда имеем на выходе 0. Может я чего-то недопонимаю?
А самое главное непонятно почему при записи 2 всегда имеем на выходе 0. Может я чего-то недопонимаю?
Рискну предположить: потому, что "два" в машинных кодах - это 10, учитывая, что состояние порта хранится в одном знаке, получаем последнюю цифру - 0. Чтобы не вставать на такие грабли - как раз и придуманы типы переменных int, float, char и т.д. В Вашем случае - программа должна делать обработку на вводе данных с клавиатуры и отбрасывать бессмысленные значения с соответствующей диагностикой. Ну, типа, помигать 13-м диодом часто-часто в случае ошибки. :)
К сожалению Ваше предположение не катит. Если поменять местами if с 0 и if с 1 то на выходе всегда будет 1. Да и причем-тут машинные коды, я же сравниваю не их а цифру 2.
К сожалению Ваше предположение не катит. Если поменять местами if с 0 и if с 1 то на выходе всегда будет 1. Да и причем-тут машинные коды, я же сравниваю не их а цифру 2.
Кто сказал "цифру"? У Вас переменная - типа "строка" и сравниваете Вы, скорее всего, коды знаков. Сделайте переменную типа unsigned int - будут Вам цифры...
Делал. Делал и переменную типа char[] и срвнивал char[0] == '2' и переменную типа int и сравнивал int ==2 эффект один и тот-же, всегда возвращается то значение переменной cur которая стоит в первом if.
Это не странное поведение ардуино, это странная программа.
stringComplete нигде не используется.
В 21 строке лучше написать Serial.println иначе будут цифры лепиться друг к другу.
Вообще, если хотите, чтобы программа срабатывала только по Enter, вставьте весь loop в такую конструкцию:
тогда str к Вам приедет всей строкой, что Вы передали в мониторе. Однако помните, что если Вы введете 22, то программа работать не будет (так как Вы хотите).
int cur - лучше инициализировать, либо сделать глобальной переменной, в противном случае она у Вас при каждом вызове loop имеет неопределенное значение (зависит от компилятора).
И мелочи, если пишите несколько if, делайте так:
Во всяком случае в этом исходнике так было бы лучше. Потому что если там "0", то два оставшихся if не сработают.
Впрочем, не настаиваю, пишите как Вам нравится :) Работать будет, но не эффективно.
Удачи!
Спасибо за ответ, наконец-то я разобрался. Виноват несколько запутанный пример на SerialEvent. Я почему-то решил что stringComplete это какая-то служебная переменная, ну и плюс подзапутался с инициализацией переменных. Все-таки Arduino несколько отличается от C к которому я привык.