IRremote проблемы с PWM 6

В прошлой статье мы научились управлять Ардуино с помощью пульта управления, включать и выключать светодиод.

Что в свою очередь позволяет экономить используемые выводы. Мы использовали один цифровой пин, вместо двух, если бы использовали две кнопки.

В этой статье мы попытаемся регулировать яркость светодиода.

Задача: увеличение и уменьшение яркости светодиода с помощью двух кнопок пульта

Изменим скетч с прошлой статьи.

1. Добавим переменную, для анализа кода нажатой кнопки [vall].

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

2. Код кнопки будем хранить в переменной типа int. Поэтому для анализа новых кодов меняем

1
Serial.println(results.value, HEX);
Serial.println(results.value, HEX);

на

1
Serial.println(results.value);
Serial.println(results.value);

3. Введем переменную яркости [pin1]. Которая будет изменяться от 0 до 255.

Получаем такой скетч:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
* : IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/
 
#include <IRremote.h>
 
int RECV_PIN = 11;
int vall;//код кнопки
int pin1;//яркость светодиода
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
void setup()
{
Serial.begin(9600);
pinMode(3, OUTPUT);
 
vall=0;
 
}
 
void loop() {
 
irrecv.enableIRIn();
if (irrecv.decode(&results)) {
Serial.println(results.value);
if (results.value!=4294967295) {
vall=results.value;
}
 
if (vall==-28561){
pin1=pin1+20;
if (pin1>255){pin1=255;}
}
if (vall==-22441){
pin1=pin1-20;
if (pin1<0){pin1=0;}
Serial.print(pin1);
}
analogWrite(3,pinl)
irrecv.resume(); // Receive the next value
}
 
}
/*
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/

#include <IRremote.h>

int RECV_PIN = 11;
int vall;//код кнопки
int pin1;//яркость светодиода

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
Serial.begin(9600);
pinMode(3, OUTPUT);

vall=0;

}

void loop() {

irrecv.enableIRIn();
if (irrecv.decode(&results)) {
Serial.println(results.value);
if (results.value!=4294967295) {
vall=results.value;
}

if (vall==-28561){
pin1=pin1+20;
if (pin1>255){pin1=255;}
}
if (vall==-22441){
pin1=pin1-20;
if (pin1<0){pin1=0;}
Serial.print(pin1);
}
analogWrite(3,pinl)
irrecv.resume(); // Receive the next value
}

}

Запускаем и что мы видим? светодиод либо горит ярко, либо не горит.

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

1
irrecv.enableIRIn(); // Start the receiver
irrecv.enableIRIn(); // Start the receiver

перестает работать , как нам этого хотелось

1
analogWrite(pin,100)
analogWrite(pin,100)

не дает ни каких результатов. Светодиод не загорается.

1
analogWrite(pin,255)
analogWrite(pin,255)

Включает его на полную яркость.

В чем же проблема?

В файле IRremote.cpp находим функцию

1
void IRrecv::enableIRIn()
void IRrecv::enableIRIn()

Читаем в ней комментарий

1
2
3
4
5
// setup pulse clock timer interrupt
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
TIMER_CONFIG_NORMAL();
// setup pulse clock timer interrupt
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
TIMER_CONFIG_NORMAL();

комментируем строку

1
TIMER_CONFIG_NORMAL();
TIMER_CONFIG_NORMAL();

analogWrite работает как должен. Сразу становится понятно, что дело в таймере.

Копаем дальше. Открываем IRremoteInt.h, находим

1
2
3
4
5
//  Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else
//#define IR_USE_TIMER1 // tx = pin 9
#define IR_USE_TIMER2 // tx = pin 3
#endif
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
#else
//#define IR_USE_TIMER1 // tx = pin 9
#define IR_USE_TIMER2 // tx = pin 3
#endif

Как мы видим библиотека IRremote использует тот же таймер, что и analogWrite — TIMER2

Меняем данный код на этот

1
2
3
4
#else
#define IR_USE_TIMER1 // tx = pin 9
//#define IR_USE_TIMER2 // tx = pin 3
#endif
#else
#define IR_USE_TIMER1 // tx = pin 9
//#define IR_USE_TIMER2 // tx = pin 3
#endif

Таким образом мы поменяли таймер IRremote с TIMER2 на TIMER1.

Заливаем скетч и проверяем. Если все сделано как описано выше, то светодиод должен менять яркость от нуля до 255 и обратно, при нажатии на наши две кнопки..

6 комментс для “IRremote проблемы с PWM

  1. Ответить asci Мар 21, 2014 00:59

    Спасибо! Как раз часа два мучался с этой фигней!

  2. Ответить PlazmX Мар 23, 2014 02:36

    Спасибо большое! =)

  3. Ответить Roywalk Апр 10, 2017 13:42

    Нет таких строк ни в одном из файлов. Пробовал разные библиотеки — нигде не нашел подобного. Не знаю где автор взял их, либо в новых версий библиотек все конкретно изменено. Запустить шим с пульта так и не удалось….

  4. Ответить wargoth Апр 29, 2017 19:00

    Запустить ШИМ получилось, но все равно не так, как надо… либо автоматом изменяет яркость от 255 до 0 и обратно, при этом ардуинка перестает реагировать на что либо… либо перескакивают значения и останавливается на минимальном — в этом случае при нажатии любой кнопки воспламеняется светодиод по максимуму…

  5. Ответить comparator Июл 31, 2017 22:38

    Спасибо! В последней версии библиотеки описанные таймеры задаются в файле boarddefs.h Перезагружать приложение Arduino не надо после изменения, просто нажать Проверить (скомпилировать заново).

  6. Ответить Strit Окт 21, 2017 20:25

    Да,помогло. Но возник конфликт с библиотекой Servo.h.Хочу на одну нано почепить 3 сервака на жалюзи, чтобы с пульта закрывать (уже работает) и добавить RGB подсветку(типа ночник будет).Но Servo блокирует ШИМ на 9 и 10 пинах,а IRremote на 3 и 11 пинах. Остается 5 и 6,а для RGB маловато. Субота коту под хвост,а что делать так и не знаю. Помогите добрые люди.

Добавить комментарий