ик не принимается если померить напряжение ацп
- Войдите на сайт для отправки комментариев
Пнд, 14/05/2012 - 06:30
#include <LiquidCrystal.h> #include <IRremote.h> IRrecv irrecv(9); LiquidCrystal lcd(11, 10, 5, 4, 3, 2); decode_results results; unsigned long last_ir,last_bat; int i_bat; float f_bat; char s_bat[6]; void setup(){ irrecv.enableIRIn(); last_ir=millis(); last_bat=millis(); lcd.begin(16,2); lcd.clear(); lcd.cursor(); lcd.blink(); lcd.setCursor(0,0); lcd.print("LCDM init Ok."); delay(1500); } void loop() { if(irrecv.decode(&results) && millis()-last_ir>250){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Protocol: "); switch (results.decode_type) { case -1: lcd.println("RAW "); break; case 1: lcd.println("NEC "); break; case 2: lcd.println("SIRC "); break; case 3: lcd.println("RC5 "); break; case 4: lcd.println("RC6 "); break; } lcd.setCursor(0,1); if(results.bits!=0){ lcd.print("Length: "); lcd.print(results.bits, HEX); }else{ lcd.print("Read error"); } delay(1500); if(results.bits!=0){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Data:"); lcd.setCursor(0,1); lcd.print(results.value, HEX); delay(2000); } irrecv.resume(); last_ir=millis(); }else{ if(millis()-last_bat>500){ i_bat=analogRead(A0); if(i_bat<100){ lcd.clear(); lcd.setCursor(0,0); lcd.print("No Bat"); lcd.setCursor(0,1); lcd.print("No IR data"); }else{ f_bat=i_bat/176.283; lcd.clear(); lcd.setCursor(0,0); lcd.print("Voltage: "); dtostrf(f_bat,1,4,s_bat); lcd.print(s_bat); lcd.setCursor(0,1); lcd.print("Charge: "); f_bat/=5.4; f_bat*=100; dtostrf(f_bat,3,2,s_bat); lcd.print(s_bat); lcd.setCursor(15,0); lcd.print(" "); lcd.setCursor(13,1); lcd.print("%"); irrecv.enableIRIn(); } irrecv.resume(); last_bat=millis(); } } }
показывает либо данные ик кода, если посветить из пульта, либо напряжение и заряд, если подключить к A0 батарею из 4х NiMH через делитель 1k+5.1k. суть проблемы: после того как в первый раз подключу батарею - все, коды больше не ловятся вплоть до ресета, как ты там не свети в ЦОП, хоть пульт в трех сантиметрах от него.
где туплю?
Для начала - откомментируйте закрывающие скопки. В простынях на два экрана очень трудно отслеживать отступы и, соответственно, следить за логикой программы. А ошибка скорее всего в логике.
Опять же - для повышения читабельности и удобства в отладке - вынесите более-менее длинные (от десяти строк и выше) неветвящиеся куски кода в отдельные функции.
Вполне возможно, что сделав эти простые вещи вы и сами увидите, где у вас проблемка притаилась.
PS: еще неплохо было бы придерживаться общепринятых стандартов в написании С-кода: лично я спотыкаюсь об конструкцию
}else{
Дело, конечно, хозяйское, но при обращении за помощью к обществу стоит немного потрудиться, чтобы обеспечить этому обществу минимальный комфорт при изучении ваших кодов.
Попробуйте разделить мухи и котлеты IR/LCD и батарейки.
Возмьмите пример IRrecvDump.pde (он поставляется вместе с библиотекой IRremote) и посмотрите в Serial, что там у вас приходит. Рабоатет ли у вас вообще IR нормально.
Кстати, обратите внимание, что у вас irrecv.resume(); вызывается далеко не после каждого irrecv.decode, да и delay-и вы используете, что тоже может способствовать потери импульсов и IR-a.
поправил, надеюсь так понятно:
делеи только внутри условий если код был, в тех местах где показывается на экран. такчто они не должны влиять. обновление метки времени поледнего принятого кода только после того как все делеи пройдут.
Ну я вам высказал свои соображения на что я обратил бы внимание. И что я бы делал для локализации проблемного места.
Я вижу что автор библиотеки всегда вызывает irrecv.resume(); после удачного irrecv.decode(), а вы - нет. Я вижу что у автора библиотеки irrecv.decode(), вызывается как можно чаще - у вас нет.
Спорить и доказывать - не буду. Возможно и ошибаюсь. Считаете что это не влияет - OK. Ищите другую причину. Принимать советы во внимание или нет - ваше дело.
А что происходит после того, как в первый раз подключите батарейку?
Ветка измерения напряжения продолжает выполняться? По каким признакам это видно?
Вообще - что-нибудь меняется в системе после рокового подключения?
М.б. вы благополучно подвисаете?
Я бы на вашем месте вывод millis на дисплей дополнительно впиндюрил, ну или мигалку на 13-й ноге задействовал, чтобы видеть, что программа по крайней мере крутится.
Ну а отладочный вывод в Serial в каждой ветви вашего логического лабиринта - это вообще мечта...
Чтобы слишком много в порт не писалось - опять-таки на время отладки - можно в основном цикле delay вставить секунд эдак на две или даже пять (гулять так гулять). При этом, конечно, и диапазоны времени, участвующие в проверках, можно соответствующим образом изменить.
И кстати - определить их константами. Ибо негоже по телу программы цифири разбрасывать - с течением времени умучаетесь их изменять/настраивать. А если еще два числовых значения с разным логическим смыслом совпадут, то потенциальный геморрой на подходе.
где же нет, строка 68.
поднял это на самый верх условия. эффект: также коды ловятся только до того как в первый раз подрубить аккум. кроме этого проскакивает что-то на что цикл реагирует тем куском, где показывается read error, тоесть сначала показывает код, потом read error. также после первого подключения акка ловить перестает.
как можно чаще вставить decode() если честно - ну просто некуда, в лупе слушаем цоп, поймали, вызвали resume(), дальше делаем с results че хотим, бо decode() уже вызвалось в условии. все.
возможно опять какие-то накладки с таймерами, как в моем прошлом вопросе. исходник IRrecvDump читал, в сериал посылал. там прием такой же, только без запрета по времени. кстати там resume() делается в песледнюю очередь.
step962
точно известно что не виснет. если отцепить аккум - покажет No bat, No IR data.
если снова прицепить, то показывает параметры аккумулятора. тоесть отваливается самое верхнее условие, с приемом кодов.
>где же нет, строка 68.
все-таки хочется поспорить? А сама строчка 68-мь, разве всегда у вас вызывается после irrecv.decode(&results)? Вот это услови " millis()-last_ir>250" всегда гарантированно истинно? Тогда нафига оно вообще?
Так что "поймали, вызвали resume()" у вас выполняется далеко не всегда.
а, понял этот затык. поменял как надо, но правда все равно принимает только до первого подключения аккумулятора. уже незнаю че еще придумать.
Ну, если не знаете, что еще придумать - переткните свой монитор напряжения на А1,А2 и т.д.
Вход TSOP тоже по ножкам подвигайте - может и найдете устойчивую комбинацию
all, проблема на atmega168 никак не вылечилась, в мк atmega328 все стало работать нормально. код скетча никак не менялся, просто зашил в 328.
ну, поскольку камни в линейке ATMegaX8 в основном отличаются размером flash/RAM, то проблема, скорее всего, была связана с тем,что вы не вмещались в пределы 1 КБ RAM (ATMega168). При 2 КБ RAM (ATMega328) появилось свободное место, управляющие структуры перестали портиться, логика стала отрабатываться, как ей и положено...