Управление светодиодами с ИК пульта

Добрый день.Помогите пожалуйста с написанием скетча.Мне необходимо, что-бы светодиод загарался только при нажатии кнопки на пульте.Смог написать следующий скеч ̀̀̀
#include “IRremote.h”
IRrecv irrecv(2);
decode_results results;
int led1 = 0;
int led2 = 0;
int led3 = 0;
int led4 = 0;
int led5 = 0;
int led6 = 0;
int led7 = 0;

void setup() {
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(9600);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);

if (results.value == 0x5EA1B04F && led1 == 0) {
  digitalWrite(4, HIGH);
  led1 = 1;
  results.value = 0;
}
if (results.value == 0x5EA1B04F && led1 == 1) {
  digitalWrite(4, LOW);
  led1 = 0;
  results.value = 0;
}

if (results.value == 0x5EA130CF && led2 == 0) {
  digitalWrite(5, HIGH);
  led2 = 1;
  results.value = 0;
}
if (results.value == 0x5EA130CF && led2 == 1) {
  digitalWrite(5, LOW);
  led2 = 0;
  results.value = 0;
}
if (results.value == 0x9E6150AF && led3 == 0) {
  digitalWrite(6, HIGH);
  led3 = 1;
  results.value = 0;
}
if (results.value == 0x9E6150AF && led3 == 1) {
  digitalWrite(6, LOW);
  led3 = 0;
  results.value = 0;
  }
   if (results.value == 0x5EA1D02F && led4 == 0) {
  digitalWrite(7, HIGH);
  led4 = 1;
  results.value = 0;
}
if (results.value == 0x5EA1D02F && led4 == 1) {
  digitalWrite(7, LOW);
  led4 = 0;
  results.value = 0;
  }
    if (results.value == 0x5EA1906F && led5 == 0) {
  digitalWrite(8, HIGH);
  led5 = 1;
  results.value = 0;
}
if (results.value == 0x5EA1906F && led5 == 1) {
  digitalWrite(8, LOW);
  led5 = 0;
  results.value = 0;
  } 
    if (results.value == 0x5EA150AF && led6 == 0) {
  digitalWrite(9, HIGH);
  led6 = 1;
  results.value = 0;
}
if (results.value == 0x5EA150AF && led6 == 1) {
  digitalWrite(9, LOW);
  led6 = 0;
  results.value = 0;
  } 
      if (results.value == 0x5EA1F20D && led7 == 0) {
  digitalWrite(10, HIGH);
  led7 = 1;
  results.value = 0;
}
if (results.value == 0x5EA1F20D && led7 == 1) {
  digitalWrite(10, LOW);
  led7 = 0;
  results.value = 0;
  } 
irrecv.resume();

}
}
̀̀̀
При нажатии светодиод загорается, и при повторном гаснет.Это всё, что мне удалось.Пгобовал разные варианты, но выходят только ошибки

Уважуха!

1 лайк
  1. Потрудитесь привести в порядок форматирование кода и оформление в вашем вопросе.

  2. Копипаста - зло! Используйте циклы, списки, массивы, структуры. Куча вариантов, как сократить эту лапшу в разы.

По вашему вопросу, на вскидку (не проверял):

void loop()
{
    if (irrecv.decode(&results)) {
 
        if (results.value == 0x5EA1B04F) {
            digitalWrite(4, HIGH);
            // results.value = 0; // это зачем вообще?
        } else digitalWrite(4, LOW);

        // ...аналогичные блоки if..else для каждого светодиода

        irrecv.resume();
    }
}

Смысл написанного: с каждой итерацией проверяем, какой сигнал получили с пульта. Если подходит для конкретного диода - зажигаем его, если нет - тушим. Так будут тухнуть все непричастные. И если кнопу на пульте отпустить, то и соответствующий ей диод потухнет.

Переменные led1...led7 будут не нужны.

Можно более лаконично исполнить. Получить сигнал, определить, на какой пин будем подавать HIGH (тут нужна карта). В цикле перебрать массив пинов и внутри проверять условием, какой зажечь, остальные выключать. Тут есть место для фантазии.

Большое спасибо, буду пробовать

Я понял, зачем это. Сразу не увидел. Эту строку нужно в конце внешнего блока if прописать один раз.

Все - фигня! Придумал, как нужно :slight_smile:

uint8_t previousPinOn = 0;
uint8_t pinOn = 0;

void loop()
{
    if (irrecv.decode(&results)) {
        switch (results.value) {
        case 0x5EA1B04F:
            pinOn = 4;
            break;
        case 0x5EA130CF:
            pinOn = 5;
            break;

            // все остальные сигналы...

        default:
            pinOn = 0;
        }

        if (previousPinOn != pinOn) {
            if (previousPinOn != 0) {
                digitalWrite(previousPinOn, LOW);
            }
            if (pinOn != 0) {
                digitalWrite(pinOn, HIGH);
            }
            previousPinOn = pinOn;
        }

        results.value = 0;
        irrecv.resume();
    }
}

В конкретный момент времени может гореть только один светодиод, максимум. Поэтому достаточно запоминать, на каком пине зажгли диод и если с очередной итерацией сигнал с пульта поменялся, текущий диод потушить и возможно зажечь другой.

И не нужны тут циклы с выключением всех светодиодов, это я думать не хотел.

Как по мне - нечёткая постановка задачи.
Например, варианты:

  • при нажатии, диод загорается, и горит дальше после отпускания кнопки, независимо от нажатия других кнопок.
  • при нажатии загорается, и, горит, лишь пока кнопка удерживается
  • при нажатии , диод загорается, и , горит после отпускания кнопки, но, с нажатием любой другой кнопки - гаснет
1 лайк

При нажатии загорается, и горит, лишь пока кнопка удерживается.При отпускании кнопки гаснет.И так для каждой кнопки ИК пульта

Спасибо, но я возможно плохо конкретизировал задачу.Светодиод должен при нажатии загорается, и гореть, лишь пока кнопка удерживается.При отпускании кнопки должен гаснуть.И так для каждой кнопки ИК пульта

А вы мое последнее решение проверяли? Оно тоже не работает? Результат какой?

Я-то тут в теории расписываю код, а у вас сборка на руках. И у меня нет ИК-приемника, чтобы проверить. Да и желания не особо )

Для начала нужно уточнить, что Ваш пульт шлёт при удержании кнопки. Скорее всего он один раз шлёт код кнопки, а потом до отпускания специальный код повторения (но это не обязательно так). Это надо учесть при составлении алгоритма работы.
В остальном вроде ничего сложного не должно быть.

1 лайк

Добрый день.
Не понял как это работает

uint8_t previousPinOn = 0;
uint8_t pinOn = 0;

Написал следующее
#include “IRremote.h”
IRrecv irrecv(2);
decode_results results;
int led1 = 0;
int led2 = 0;
int led3 = 0;
int led4 = 0;
int led5 = 0;
int led6 = 0;
int led7 = 0;

void setup() {
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

Serial.begin(9600);
irrecv.enableIRIn();
}
uint8_t previousPinOn = 0;
uint8_t pinOn = 0;

void loop() {
if (irrecv.decode(&results)) {
if (irrecv.decode(&results)) {
switch (results.value) {
case 0x5EA1B04F:
pinOn = 4;
break;
case 0x5EA1B04F:
pinOn = 5;
break;
case 0x5EA130CF:
pinOn = 6;
break;
case 0x5EA1B04F:
pinOn = 7;
break;
case 0x5EA130CF:
pinOn = 8;
break;
case 0x9E6150AF:
pinOn = 9;
break;
case 0x5EA1D02F:
pinOn = 10;
break;
default:
pinOn = 0;
}
if (previousPinOn != pinOn) {
if (previousPinOn != 0) {
digitalWrite(previousPinOn, LOW);
}
if (pinOn != 0) {
digitalWrite(pinOn, HIGH);
}
previousPinOn = pinOn;
}
results.value = 0;
}
irrecv.resume();
}
}
Скетч написан не верно, а где напортачил не вижу.Прошу снисхождения, я только пробую что нибудь собрать

Оформите код нормально, второй раз говорю. Потом будем обсуждать.

Скетч написан не верно

А ошибку-то покажете или догадаться нужно? )

Извините,
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino: In function ‘void loop()’:
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:36:11: error: duplicate case value
case 0x5EA1B04F:
^~~~
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:33:11: note: previously used here
case 0x5EA1B04F:
^~~~
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:42:9: error: duplicate case value
case 0x5EA1B04F:
^~~~
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:33:11: note: previously used here
case 0x5EA1B04F:
^~~~
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:45:9: error: duplicate case value
case 0x5EA130CF:
^~~~
C:\Users\s001\Documents\Arduino\Akai635_weiter\Akai635_weiter.ino:39:9: note: previously used here
case 0x5EA130CF:
^~~~

exit status 1

Compilation error: duplicate case value

Подскажите как оформить код, я сделаю

Надо глаза разуть прежде чем начинать печатать !!!

#include "IRremote.h"
IRrecv irrecv(2);
decode_results results;
int led1 = 0;
int led2 = 0;
int led3 = 0;
int led4 = 0;
int led5 = 0;
int led6 = 0;
int led7 = 0;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);


  Serial.begin(9600);
  irrecv.enableIRIn();
}
uint8_t previousPinOn = 0;
uint8_t pinOn = 0;

void loop() {
  if (irrecv.decode(&results)) {
    if (irrecv.decode(&results)) {
      switch (results.value) {
        case 0x5EA1B04F:
          pinOn = 4;
          break;
        case 0x5EA1B04F:
          pinOn = 5;
          break;
        case 0x5EA130CF:
          pinOn = 6;
          break;
        case 0x5EA1B04F:
          pinOn = 7;
          break;
        case 0x5EA130CF:
          pinOn = 8;
          break;
        case 0x9E6150AF:
          pinOn = 9;
          break;
        case 0x5EA1D02F:
          pinOn = 10;
          break;
        default:
          pinOn = 0;
      }
      if (previousPinOn != pinOn) {
        if (previousPinOn != 0) {
          digitalWrite(previousPinOn, LOW);
        }
        if (pinOn != 0) {
          digitalWrite(pinOn, HIGH);
        }
        previousPinOn = pinOn;
      }
      results.value = 0;
    }
    irrecv.resume();
  }
}

Ошибка

 case 0x5EA130CF:
         ^~~~

exit status 1

Compilation error: duplicate case value

В case не могут дублироваться значения !

Всё получилось.Большое спасибо.Учту ошибки на будущее