Режим работы кнопки пульта

Hleb13
Offline
Зарегистрирован: 16.04.2015

Добрый день!

Совсем недавно начал изучать Arduino, поэтому столкнулся с таким вопросом, не знаю как его решить, подскажите, пожалуйста.

Есть пульт, приемник и два светодиода. Добился того, что при нажатии клавиши POWER на пульте включается светодиод, а при нажатии на кнопу переключения каналов выключается текущий и включается следующий и так по кругу. Все тут верно.

Но сейчас как, нажимаю на клавишу переключения канала и держу кнопку - светоиоды включаются и выключаются по кругу пока я держу кнопку.

Но мне нужно, чтобы я нажал на клавишу переключения канала и удерживал ее, а светодиод переключился один раз и все. Повторное переключение допустимо только после того как я отпущу клавишу на пульте и нажму ее повторно.

Подскажите, в какую сторону мне копать, хотя бы общую идею...

Заранее благодарен!

vov4ik
Offline
Зарегистрирован: 10.09.2013

Попробуй всё то-же самое но под водой.

Какой пульт? Какой приемник? куда вотнул светодиоды? Где скеч?

 

Hleb13
Offline
Зарегистрирован: 16.04.2015

Извиняюсь... Вот скетч:

#include <IRremote.h>

int LED = 10;
int RECEIVE_PIN = 2;

IRrecv irrecv(RECEIVE_PIN);
decode_results results;
 
void setup() {
  
    Serial.begin(9600);
    irrecv.enableIRIn();
    pinMode(LED, OUTPUT);    
    pinMode(11, OUTPUT);
}
 
void loop() {
  
    if (irrecv.decode(&results)) {        
         
       // кнопка CHANNEL UP             
        if ((results.value == 0x24 || results.value == 0x824) && LED == 11) {digitalWrite(LED, LOW); LED = LED - 1; digitalWrite(LED, HIGH);}
        else
        if (results.value == 0x24 || results.value == 0x824) {digitalWrite(LED, LOW); LED = LED + 1; digitalWrite(LED, HIGH);}
    
      
      // кнопка CHANNEL DOWN 
        if ((results.value == 0x23 || results.value == 0x823) && LED == 10) {digitalWrite(LED, LOW); LED = LED + 1; digitalWrite(LED, HIGH);}
        else
        if (results.value == 0x23 || results.value == 0x823) {digitalWrite(LED, LOW); LED = LED - 1; digitalWrite(LED, HIGH);}

      
        irrecv.resume();
    }
  
}

Подключены два светодиода на 10 и 11 выходы. Также подключен фотодиод на 2 pin. Пульт обычный, от телевизора, коды кнопок считаны. При нажатии на кнопку и ее удерживании сигнал идет постоянно. Нажатием на пульте вверх/вниз переключаем светодиоды между собой.

Но как заставить их переключаться только один раз при нажатой и удержанной клавише, а второй раз только тогда, когда ее отпускаешь и еще раз нажимаешь?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Завести переменную, где хранить полученный код. Сохранять нужно в конце цикла. При получении кода сравнивать с сохраненным, если такой же, игнорировать (ничего не делать)

Hleb13
Offline
Зарегистрирован: 16.04.2015

Спасибо!

А можно по-подробнее про "завести переменную, где хранить полученный код"? Непонятно про хранение кода в переменной...

vov4ik
Offline
Зарегистрирован: 10.09.2013

 if ((results.value == 0x24 || results.value == 0x824) && LED == 1) {digitalWrite(11,(!digitalRead(11)); LED = 0;} 

 if (results.value != 0x24 && results.value != 0x824) {LED = 1;}

пока держится кнопка команда инверсии считанного состояния выполнится один раз.

Hleb13
Offline
Зарегистрирован: 16.04.2015

Спасибо большое, скетч применил, работает. Но тут еще есть момент, получается так: светодиод не горит, нажал кнопку, светодиод включился, удерживаю кнопку, выполняется команда инверсии один раз, все верно. Но чтобы потом этот светодиод выключить нужно сначала нажать на какую-либо другую кнопку и только потом опять на кнопку включения светодиода.

А как сделать, чтобы нажал кнопку, светодиод зажегся, удерживаю кнопку, светодиод все равно горит, отпустил - светодиод горит, нажал вновь, светодиод погас, удерживаю эту же кнопку, все равно светодиод не горит, отпустил - светодиод не горит и так до бесконечности.

vov4ik
Offline
Зарегистрирован: 10.09.2013

Хм странно я в программу включил сброс при отпускании кнопок if (results.value != 0x24 && results.value != 0x824) {LED = 1;} заведите  Serial.print(results.value); Serial.print(" "); Serial.println(LED); и посмотрите что происходит по идее коды от кнопок не приходят и LED = 0; сбрасывается на LED = 1; хотя ошибка может быть в том что программа работает когда нажата кнопка о чём свидетельствует if (irrecv.decode(&results)) { программа } итог сбросс надо вывести из скобок либо прописать если кнопка не нажата сбросить if (irrecv.decode(&results)) { программа } else {LED = 1;}  , тем самым пока кнопка нажата программа выполнит инверсию один раз а когда никакая кнопка не будет нажата сброс, но тут возникнет другой камень даже при нажатой кнопке от пульта могут прилетать нули это тоже надо учитывать, посмотреть колько максимально нулей прилетает при нажатой кнопке построить счётчик нулей и когда счет привысит максимальное значение +5% тогда и сбрасывать, выгледеть это будет так else {s++; if (s > 10) {LED = 1;}} , и чтобы счёт не накапливался if ((results.value == 0x24 || results.value == 0x824) && LED == 1) {digitalWrite(11,(!digitalRead(11)); LED = 0; s = 0;} и соответственно в начале объевить переменную int s = 0;

Hleb13
Offline
Зарегистрирован: 16.04.2015

Извиняюсь за долгое отсутствие! Спасибо за ответ, vov4ik.

Пока без счетчика нулей просто записал такой скетч

#include <IRremote.h>
int RECEIVE_PIN = 7;
int LED = 1;
IRrecv irrecv(RECEIVE_PIN);
decode_results results;
 
void setup() {
    Serial.begin(9600);
    irrecv.enableIRIn(); // Start the receiver
}
 
void loop() {
    if (irrecv.decode(&results)) {

            if ((results.value == 0xC || results.value == 0x80C) && LED == 1) {digitalWrite(8,(!digitalRead(8))); LED = 0;}

        irrecv.resume();
    }
    else {LED = 1;}
}

Получаем, что програма запускается с LED = 1, нажимаю кнопку на пульте - светодиод включается (LED становится равным 0). Отпускаю кнопку, нажимаю вновь - светодиод не гаснет. То есть получается даже при "спокойном" положении кнопок пульта переменная LED вновь не становится 1, хотя по логике должно работать так, если кнопка не нажата, то LED = 1.

Подскажите, пожалуйста, почему так выходит?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вставить  resume после  LED=1  не пробовали?

Hleb13
Offline
Зарегистрирован: 16.04.2015

А как поставить после LED = 1, если irrecv.resume(); должен располагаться внутри if (irrecv.decode(&results)) {}? Или я что-то не понял? Напишите, пожалуйста этот кусок программы, как Вы предлагаете?