Отследить состояние кнопки
- Войдите на сайт для отправки комментариев
Чт, 24/03/2016 - 20:32
Всем привет! Необходимо отследить состояние кнопки. Задача состоит в том что бы сделать включение и выключение диода с кнопки и пульта одновременно, не зависимо друг от друга.
Не работает в том месте когда после операции с пультом (включения или выключения), следующее переключение кнопки не к чему не приводит, и только после второго все корректно. Я понимаю что нужно отслеживать состояние кнопки когда переключаю с пульта, но не понимаю как. Подскажите пожалуйсто гуда ковырять. (новичек).
#include <IRremote.h> // https://github.com/shirriff/Arduino-IRremote #define RECV_PIN 4 // IR приемник #define OUT1 9// выхода на мосфеты const int buttonPin = 7; // кнопка включения с фиксацией #define POWER_KEY 0xFF00FF // коды пульта ДУ #define KEY1 0xFF807F // v- #define KEY2 0xFF40BF // v+ byte analogData1 = 0; // значения аналогово выхода uint32_t val; int buttonState = 0; //переменная состояния кнопки int oldButtonState = 0; //переменная старое состояние кнопки IRrecv irrecv(RECV_PIN); decode_results results; void setup() { irrecv.enableIRIn(); //запускаем ик Serial.begin(9600); //включаем сериал pinMode(buttonPin, INPUT); //кнопка как вход } void loop() { buttonState = digitalRead(buttonPin); if (oldButtonState==LOW && buttonState==HIGH) { analogWrite(OUT1, 255); // включаем analogData1 = 255; oldButtonState = buttonState; } if (oldButtonState==HIGH && buttonState==LOW)//выключили { analogWrite(OUT1, 0); // выключаем analogData1 = 0; oldButtonState = buttonState; } //////////////////////////////////////////////////////////////////////////// //************************************************************************// //////////////////////////////////////////////////////////////////////////// if (irrecv.decode(&results)) { // если пришел пакет if (results.value != 0xFFFFFFFF){ // и этот пакет не FF val = results.value; // сохраняем правельный пакет в переменную } // если пришел FF, соответственно пропускаем. /// сверяем значение из переменной val.. если пришла команда повтора (пакет с FF) /// в переменной останется прошлый, правельный, пакет и код выполнится повторно. if (val == KEY1){ if (analogData1 != 0)analogData1 -=5; // если шим не равно 0 отнимаем 1 analogWrite(OUT1, analogData1); // устанавливаем значение в выход } if (val == KEY2){ // и это вторая кнопка if (analogData1 < 255) analogData1 +=5; // если шим меньше 255 прибовляем 1 analogWrite(OUT1, analogData1); // устанавливаем значение } if (results.value == POWER_KEY) { if (analogData1 != 0){ // если ШИМ неравно 0 analogWrite(OUT1, 0); // выключаем //наверно где то тут нужно отслеживать кнопку analogData1 = 0; } else { analogWrite(OUT1, 255); // включаем //наверно где то тут нужно отслеживать кнопку analogData1 = 255; } } Serial.println(val, HEX); //// ТЕСТЫ! Serial.println(results.value, HEX); Serial.println(analogData1); Serial.println(); //Serial.print("положение кнопки "); //Serial.println(buttonState); irrecv.resume(); } }
Мне наверное стоило прочесть код более внимательно. Но я пока что обойдусь советом.
Как насчет конструкции где есть общая переменная и обработкик контроллирующий состояние переменной кнопки. И изменяет состояние светодиода если было изменение опираясь на предыдущее значение.
Тоесть три куска кода:
1- обработчик контроллирует состояние переменной скажем keyvar
2 - обработчик кнопки на устройстве. при нажатии меняет состояние на keyvar
3 - обработчик приема данных с пульта и так же вносит изменение в keyvar
суть проста. 2 и 3 обработчики не работают с командой вывода сигнала на светодиод. этм занимается первый обработчик который просто контроллирует переменную и делает выводы стоит что-то менять или нет.
Если вы хотите, что бы работало по такому алгоритму:
1. Включили кнопкой (кнопка, как я понимаю, например замкнула контакт и зафиксировалась в этом положении) -> 2. Выключили с пульта -> 3. Включили кнопкой (кнопка разомкнула котакт и зафиксировалась в этом положении)
Т.е. у кнопки нет фиксированных положений вот так она вкл, а вот так выкл, то вместо строк 30-41 нужно что-то такое:
Я уж отчаялся, думал не ответят. Спасибо Вам добрые дяденьки программисты! Домой приду сразу попробую.
Да, должно получится что то вроде проходного выключателя, что бы можно было независимо включать и с пульта и с кнопки (совершенно верно, кнопка с фиксированным положением), и выключать соотвецтвенно, и не важно что в каком порядке. Без Вас мне не справится, так что надеюсь на вашу помощь.
Ну тогда однозначно, тот код что я привел в предыдущем посте решит вопрос.
Господи!!! Это прекрасно!!! Оно работает!!! Спасибо громадное!!! Я несколько недель этого добивался. Спасибо Вам!!! 11 строчек кода, как нужно мало для счастья)))
Вот так теперь выглядит полный вариант.
1. Тут местные критики сразу бы тебя распинали, как меня в свое время, за использование "if", которое при выполнении одного из условий, все равно проверяет все остальные, которые заведомо не выполнятся. Посоветовали применить конструкцию "swith-case", с которой я потом намучался досыта, но оставил чисто в целях расширеня кругозора.
2. Лично я на своём опыте убедился, что "
irrecv.resume();
" надо ставть сразу после считывания "results.value
" в переменную, что бы подготовить ее для следующего значения. Проверено - работает более стабильно.Нормально у него написан, дай бог всем новичкам так. Ну придратся конечно завсегда можно - в коде константы цифрами, а не вынесены в дефайны, скобочки раставлены не в соответствии с моим личным предпочтением )) и т.д. но то фигня от скуки.
Про "swith-case" зря вы так, эта штука очень удобна и проста для старта, намного наглядней кучи ифов.
Нормально у него написан, дай бог всем новичкам так. Ну придратся конечно завсегда можно - в коде константы цифрами, а не вынесены в дефайны, скобочки раставлены не в соответствии с моим личным предпочтением )) и т.д. но то фигня от скуки.
Не, ну парень, несомненно - молодец! Но я хотел свести замечания, которые получил в свой адрес, в одно сообщение и справедливости ради, хочу заметить что все они меня, конечно же, продвинули в смысле программирования в среде.
Однако же не могу упустить момент пожаловаться на "switсh-case", который добавил мне головняка на днях...
Что бы не забредать в дебри - в двух словах:
Есть скетч-часы, время выставляется кнопками с пульта, кнопки прописаны в "#define", где им присваиваются совершенно отвольные значения, которые потом нигде не фигурируют и главное в каждом "#define"-е - только название самой кнопки. (Тут у меня закрадываются некоторые сомнения насчет этих названий: зачем им присваивать какие-то числа, по которым потом все равно не выполняются никакие проверки и эта величина нигде не используется? Неужели это нормально: объявить константу только ради самого имени? Возможно я чего-то недопонял или невнимательно изучил алгоритм, но по "CTRL+F" всё что я нашёл, это только "return btn_..." или "case btn_..." и ни слова о его значении). Так вот если одной из этих констант присвоить значение "ноль", то ваш любимый "switсh-case" обязательно считает что это событие уже настало! Но стоило мне убрать "0" из этой константы, как всё стало на свои места.
Ну и где тут, скажите, удобство и простота? Я чуть не тронулся, пока не убрал этот ноль из списка "#define"! И причем - совершенно случайно...