"Дребезг" кнопок ИК пульта

alexeykalin
Offline
Зарегистрирован: 05.06.2013

Всем привет! Помогите новичку. Делаю мигалку на трёх светодиодах. В мигалке 2 режима мигания, которые переключаются с пульта. Написал скетч, всё вроде работает, но при нажатии кнопок на пульте, режимы не всегда сразу переключаются. Мне кажется это что-то типа "дребезга", но как исправить не знаю. Что нужно в скетче дописать?
 

#include <IRremote.h> // библиотека ИК
int RECV_PIN = 2; //вход ИК приёмника
IRrecv irrecv(RECV_PIN);
decode_results results;
int a=0;

void setup()
{
pinMode(2, INPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
attachInterrupt(0,function,CHANGE); //прерывание
irrecv.enableIRIn();
}

void loop()
{
//режим 1
irrecv.resume();
if (a==1) {
digitalWrite(11, HIGH);
delay(10);
digitalWrite(11, LOW);
delay(100);
digitalWrite(12, HIGH);
delay(10);
digitalWrite(12, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(100);
}
//режим 2
if (a==0){
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
// подождем секунду
delay(100);
// погасим светодиод, убрав напряжение с ножки
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
// подождем секунду
delay(100);
}
}
//функция прерывания
void function()
{
irrecv.decode(&results);
if (results.value == 0x3407DE1F) {a=1;}
if (results.value == 0xCAD80373) {a=0;}
}

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

при управлении с ИК пульта не может быть дребезга...

alexeykalin
Offline
Зарегистрирован: 05.06.2013

А почему тогда не всегда переключается с первго раза?

alexeykalin
Offline
Зарегистрирован: 05.06.2013

И как устранить проблему?????

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

Факторов много, один из первых - частота приемника и передатчика должны совпадать. Если нет - то ослабление сигнала может сильно испортить обмен.
UPD: следующее - это корректный скетч, а у Вас он еще и использует прерывания, вполне возможно, что некорректно.

alexeykalin
Offline
Зарегистрирован: 05.06.2013

Без использования прерываний проблем никаких не возхникает. А вот с что делать с прерываниями?

maksim
Offline
Зарегистрирован: 12.02.2012
void function()
{
  detachInterrupt(0);
  irrecv.decode(&results);
  if (results.value == 0x3407DE1F) a = 1;
  if (results.value == 0xCAD80373) a = 0;
  attachInterrupt(0,function,CHANGE);
}

 

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

Сожалею, но не понял, зачем Вам обработка прерываний, плюс декодирование достаточно тяжелое и времязатратное действие, что может привести к разным, порой сложнообъяснимым глюкам

alexeykalin
Offline
Зарегистрирован: 05.06.2013

А может можно обойтись без прерываний?

leshak
Offline
Зарегистрирован: 29.09.2011

alexeykalin пишет:

А может можно обойтись без прерываний?

Зайдите с другого конца - а зачем тут вы тут вообще используете прерывание? IR-ремоте - все что нужно для захвата импульсов - делает сама. Ваше дело - только регулярно вызвать ее в loop() и спрашивать "ну что, есть декодированные данные?"

Посмотрите примеры идущие с библиотекой, есть там какие-то обработчкики прерываний?

alexeykalin
Offline
Зарегистрирован: 05.06.2013

Помоему нет(

alexeykalin
Offline
Зарегистрирован: 05.06.2013

Так кто-нибудь знает как написать корректный скетч?

Клапауций
Offline
Зарегистрирован: 10.02.2013

alexeykalin пишет:
Так кто-нибудь знает как написать корректный скетч?

Я себе IR-кнопку простую делал - от этого и скачи, хочешь включай/выключай, мигай.

Нафига там у тебя какие-то ожидания и прерывания - не понятно.

В void LED() {} пиши нужные тебе функции - будет работать по событиям приёма нового сигнала.

Да, и... повторное нажатие кнопок отрублено специально, хочешь - выпили.


#include <IRremote.h>

IRrecv irrecv(4);
decode_results results;

unsigned long ir;

void setup() {

pinMode(14, OUTPUT);
digitalWrite(14, LOW);

irrecv.enableIRIn(); // включить приемник
ir = results.value;
}

void loop() {

if (irrecv.decode(&results)) {if ((results.value > 0) && (results.value < 0xFFFFFFFF)) {unsigned long nir = results.value; if (nir != ir) {ir = nir; LED();}} irrecv.resume();}
}

void LED() {

if (ir == 50168445) {if (digitalRead(14) != HIGH) {digitalWrite(14, HIGH);}}
if (ir == 50156205) {if (digitalRead(14) != LOW) {digitalWrite(14, LOW);}}

}

 

alexeykalin
Offline
Зарегистрирован: 05.06.2013

Но всё равно при нажатии кнопок, срабатывает не всегда сразу(

Клапауций
Offline
Зарегистрирован: 10.02.2013

alexeykalin пишет:
Но всё равно при нажатии кнопок, срабатывает не всегда сразу(

А, через сколько срабатывает простое переключение?

24 if (ir == 50168445) {if (digitalRead(14) != HIGH) {digitalWrite(14, HIGH);}}
25 if (ir == 50156205) {if (digitalRead(14) != LOW) {digitalWrite(14, LOW);}}

через минуту, час, сутки?

Будет переключаться ровно через столько, сколько требуется МК на отработку предыдущей задачи и приём новой команды.

Это в случае, если нет проблем на уровне железа - макетка на соплях, фильтрующих конденсаторов на IR-приёмнике нет, и вообще частоты пульта и приёмника не совпадают.

Выведите индикацию переменной "ir" в сериал порт или на LCD - будете понимать, что происходит в реальном времени.