Странное поведение ардуино.
- Войдите на сайт для отправки комментариев
Чт, 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 в такую конструкцию:
if( stringComplete ) { ... }тогда str к Вам приедет всей строкой, что Вы передали в мониторе. Однако помните, что если Вы введете 22, то программа работать не будет (так как Вы хотите).
int cur - лучше инициализировать, либо сделать глобальной переменной, в противном случае она у Вас при каждом вызове loop имеет неопределенное значение (зависит от компилятора).
И мелочи, если пишите несколько if, делайте так:
if( условие 1) { } else if( условие2 ) { } else { }Во всяком случае в этом исходнике так было бы лучше. Потому что если там "0", то два оставшихся if не сработают.
Впрочем, не настаиваю, пишите как Вам нравится :) Работать будет, но не эффективно.
Удачи!
Спасибо за ответ, наконец-то я разобрался. Виноват несколько запутанный пример на SerialEvent. Я почему-то решил что stringComplete это какая-то служебная переменная, ну и плюс подзапутался с инициализацией переменных. Все-таки Arduino несколько отличается от C к которому я привык.