В этом уроке мы научимся управлять устройствами с помощью любого ИК-пульта дистанционного управления, на примере управления RGB светодиодной лентой.
Нам понадобится:
- Arduino х 1шт.
- Trema Shield х 1шт.
- Trema-модуль силовой ключ х 3шт.
- Trema-модуль ИК-приёмник х 1шт.
- Источник питания 12В х 1шт.
- Коннектор Power Jack с клемником х 1шт.
- ИК-пульт дистанционного управления х 1шт.
- RGB светодиодная лента, с коннектором и проводами.
Для реализации проекта нам необходимо установить одну библиотеку:
- Библиотека iarduino_IR для работы с ИК-приёмопередатчиками
ВАЖНО: библиотека использует второй аппаратный таймер,
НЕ ВЫВОДИТЕ СИГНАЛЫ ШИМ НА 3 ИЛИ 11 ВЫВОД!
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Видео:
Схема подключения:
Силовые ключи подключаются к выводам с ШИМ: 5, 6, 9.
ИК-приёмник подключается к цифровому выводу 7 (можно заменить на любой цифровой вывод, указав его номер в скетче).
Код программы:
// Подключаем библиотеку:
#include <iarduino_IR_RX.h> // подключаем библиотеку для работы с ИК приёмником
// Объявляем переменные и константы:
iarduino_IR_RX IR(7); // объявляем переменную для работы с ИК приёмником (номер цифрового вывода к которому подключён ИК приёмник = 7)
const uint8_t PIN_LED_R = 6; // указываем номер вывода arduino, к которому подключён Trema ключ, управляющий R каналом светодиодной ленты
const uint8_t PIN_LED_G = 9; // указываем номер вывода arduino, к которому подключён Trema ключ, управляющий G каналом светодиодной ленты
const uint8_t PIN_LED_B = 5; // указываем номер вывода arduino, к которому подключён Trema ключ, управляющий B каналом светодиодной ленты
uint8_t VAL_LED_R = 0xFF; // объявляем переменную содержащую значение яркости R канала светодиодной ленты
uint8_t VAL_LED_G = 0xFF; // объявляем переменную содержащую значение яркости G канала светодиодной ленты
uint8_t VAL_LED_B = 0xFF; // объявляем переменную содержащую значение яркости B канала светодиодной ленты
uint8_t VAL_LIGHT = 0xFF; // максимальная яркость для каждого канала RGB
unsigned long MAS_PLAY[6] = {5,0,0,0,0,0}; // массив для автоперелива {задержка в мс, время старта, тип, сектор, позиция, яркость}
bool FLAG_ON = 0; // флаг вкл/выкл
bool FLAG_RGB = 1; // флаг указывающий о необходимости изменить значения ШИМ
void setup(){
IR.begin(); // инициируем ИК приёмник
}
void loop(){
// Читаем команды с ИК-пульта (если таковые есть)
if(IR.check(true)){ if(FLAG_ON){ switch(IR.data){ // если принят пакет с пульта (включая пакеты повторов), если устройство включено, проверяем какая кнопка пульта нажата
/* << = перелив 1 */ case 0xFF22DD: if(IR.key_press){MAS_PLAY[2]=MAS_PLAY[2]==1?0:1; MAS_PLAY[1] = millis();} break;
/* >> = перелив 2 */ case 0xFF02FD: if(IR.key_press){MAS_PLAY[2]=MAS_PLAY[2]==2?0:2; MAS_PLAY[1] = millis();} break;
/* >|| = перелив 3 */ case 0xFFC23D: if(IR.key_press){MAS_PLAY[2]=MAS_PLAY[2]==3?0:3; MAS_PLAY[1] = millis();} break;
/* CH+ = яркость + */ case 0xFFE21D: FLAG_RGB=1; VAL_LIGHT=VAL_LIGHT<<1|1; break;
/* - = R канал + */ case 0xFFE01F: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=VAL_LED_R<<1|1; break;
/* + = G канал + */ case 0xFFA857: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_G=VAL_LED_G<<1|1; break;
/* EQ = B канал + */ case 0xFF906F: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_B=VAL_LED_B<<1|1; break;
/* CH = яркость - */ case 0xFF629D: FLAG_RGB=1; VAL_LIGHT=VAL_LIGHT>>1; break;
/* 0 = R канал - */ case 0xFF6897: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=VAL_LED_R>>1; break;
/* 100+ = G канал - */ case 0xFF9867: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_G=VAL_LED_G>>1; break;
/* 200+ = B канал - */ case 0xFFB04F: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_B=VAL_LED_B>>1; break;
/* 1 = красный */ case 0xFF30CF: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0xFF; VAL_LED_G=0x00; VAL_LED_B=0x00; MAS_PLAY[3]=0; MAS_PLAY[4]=0x00; break;
/* 2 = оранжевый */ case 0xFF18E7: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0xFF; VAL_LED_G=0x0F; VAL_LED_B=0x00; MAS_PLAY[3]=0; MAS_PLAY[4]=0x7F; break;
/* 3 = жёлтый */ case 0xFF7A85: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0xFF; VAL_LED_G=0x3F; VAL_LED_B=0x00; MAS_PLAY[3]=1; MAS_PLAY[4]=0x00; break;
/* 4 = синий */ case 0xFF10EF: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0x00; VAL_LED_G=0x00; VAL_LED_B=0xFF; MAS_PLAY[3]=4; MAS_PLAY[4]=0x00; break;
/* 5 = голубой */ case 0xFF38C7: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0x00; VAL_LED_G=0xFF; VAL_LED_B=0xFF; MAS_PLAY[3]=3; MAS_PLAY[4]=0x00; break;
/* 6 = зелёный */ case 0xFF5AA5: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0x00; VAL_LED_G=0xFF; VAL_LED_B=0x00; MAS_PLAY[3]=2; MAS_PLAY[4]=0x00; break;
/* 7 = фиолетовый*/ case 0xFF42BD: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0xFF; VAL_LED_G=0x00; VAL_LED_B=0xFF; MAS_PLAY[3]=5; MAS_PLAY[4]=0x00; break;
/* 8 = белый */ case 0xFF4AB5: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0xFF; VAL_LED_G=0xFF; VAL_LED_B=0xFF; MAS_PLAY[3]=0; MAS_PLAY[4]=0x00; break;
/* 9 = чёрный */ case 0xFF52AD: MAS_PLAY[2]=0; FLAG_RGB=1; VAL_LED_R=0x00; VAL_LED_G=0x00; VAL_LED_B=0x00; MAS_PLAY[3]=0; MAS_PLAY[4]=0x00; break;
}}/* CH- = вкл/выкл */ if(IR.data==0xFFA25D && IR.key_press){FLAG_RGB=1; FLAG_ON=FLAG_ON?0:1;}} // если нажата кнопка пульта вкл/выкл и она не удерживается
// Запускаем функцию перелива цвета (если таковая включена)
if(MAS_PLAY[2]&&FLAG_ON){Func_color();}
// Выводим ШИМ для каждого канала RGB (если требуется изменить ШИМ хотя бы для одного из каналов)
if(FLAG_RGB){ FLAG_RGB=0; // сбрасываем флаг указывающий о необходимости изменить значения ШИМ
analogWrite(PIN_LED_R, FLAG_ON?map(VAL_LED_R,0,0xFF,0,MAS_PLAY[2]==1?MAS_PLAY[5]:VAL_LIGHT):0); // выводим ШИМ с указанием яркости R канала светодиодной ленты
analogWrite(PIN_LED_G, FLAG_ON?map(VAL_LED_G,0,0xFF,0,MAS_PLAY[2]==1?MAS_PLAY[5]:VAL_LIGHT):0); // выводим ШИМ с указанием яркости G канала светодиодной ленты
analogWrite(PIN_LED_B, FLAG_ON?map(VAL_LED_B,0,0xFF,0,MAS_PLAY[2]==1?MAS_PLAY[5]:VAL_LIGHT):0); // выводим ШИМ с указанием яркости B канала светодиодной ленты
}
}
// функция автоперелива цвета
void Func_color(){
if(MAS_PLAY[1]>millis()){MAS_PLAY[1]=0; delay(MAS_PLAY[0]);} // произошло переполнение micros()
if(MAS_PLAY[1]<millis()-MAS_PLAY[0]){ MAS_PLAY[1]=millis(); // если прошло MAS_PLAY[0] мс после последнего изменения ШИМ
switch(MAS_PLAY[3]){ // R G B R G B
case 0: VAL_LED_B=0x00; VAL_LED_R=0xFF; VAL_LED_G=MAS_PLAY[2]!=2?0xFF: MAS_PLAY[4]; break; // сектор автоперелива от красного к жёлтому (FF0000 -> FFFF00)
case 1: VAL_LED_B=0x00; VAL_LED_G=0xFF; VAL_LED_R=MAS_PLAY[2]!=2?0x00:0xFF-MAS_PLAY[4]; break; // сектор автоперелива от жёлтого к зелёному (FFFF00 -> 00FF00)
case 2: VAL_LED_R=0x00; VAL_LED_G=0xFF; VAL_LED_B=MAS_PLAY[2]!=2?0xFF: MAS_PLAY[4]; break; // сектор автоперелива от зелёного к голубому (00FF00 -> 00FFFF)
case 3: VAL_LED_R=0x00; VAL_LED_B=0xFF; VAL_LED_G=MAS_PLAY[2]!=2?0x00:0xFF-MAS_PLAY[4]; break; // сектор автоперелива от голубого к синему (00FFFF -> 0000FF)
case 4: VAL_LED_G=0x00; VAL_LED_B=0xFF; VAL_LED_R=MAS_PLAY[2]!=2?0xFF: MAS_PLAY[4]; break; // сектор автоперелива от синего к фиолетовому (0000FF -> FF00FF)
case 5: VAL_LED_G=0x00; VAL_LED_R=0xFF; VAL_LED_B=MAS_PLAY[2]!=2?0x00:0xFF-MAS_PLAY[4]; break; // сектор автоперелива от фиолетового к красному (FF00FF -> FF0000)
}
if(MAS_PLAY[4]<0xFF){MAS_PLAY[4]++;}else{MAS_PLAY[4]=0; MAS_PLAY[3]++;} // увеличиваем шаг и сектор автоперелива цвета
if(MAS_PLAY[3]>=6){MAS_PLAY[3]=0;} // переходим от 5 к 0 сектору
if(MAS_PLAY[2]==1){MAS_PLAY[5]=MAS_PLAY[4]>127?map(MAS_PLAY[4],127,255,VAL_LIGHT,1):map(MAS_PLAY[4],0,127,1,VAL_LIGHT);} // затухание и возрастание
FLAG_RGB=1; // устанавливаем флаг указывающий о необходимости изменить значения ШИМ
}
}
Алгоритм работы:
В начале кода:
- подключается библиотека iarduino_IR;
- создаётся переменная IR с указанием цифрового вывода к которому подключён ИК-приёмник;
- создаются константы PIN_LED_ R/G/B с указанием выводов ШИМ к которым подключены ключи для каналов R/G/B;
- создаются переменные VAL_LED_ R/G/B с указанием начального значения ШИМ для каждого канала R/G/B;
- создаётся переменная VAL_LIGHT с указанием начальной яркости свечения
- создаётся массив MAS_PLAY для реализации функции автоперелива цвета
- флаги: FLAG_ON - вкл/выкл ленты и FLAG_RGB - требующий изменение ШИМ для каждого канала R/G/B.
В функции setup:
- выполняется только одна строка кода: IR.begin(); - инициирующая ИК-приёмник.
В функции loop:
- сначала проверяется наличие данных принятых с пульта, если данные есть, то оператором switch case определяем, какая кнопка нажата, по её коду и выполняем изменение переменных цвета, яркости, автоперелива и флагов;
- далее, если требуется включить автоперелив, то запускаем функцию Func_color();
- в конце устанавливаем новые значения ШИМ, если установлен флаг FLAG_RGB свидетельствующий о том, что были внесены изменения в переменные цвета или яркости.
В функции Func_color:
Меняем цвет и/или яркость по одному из трёх алгоритмов:
- MAS_PLAY[2]==3 => меняем цвет резко, без изменения яркости;
- MAS_PLAY[2]==2 => меняем цвет плавно, без изменения яркости;
- MAS_PLAY[2]==1 => меняем цвет плавно, с изменением яркости;
- MAS_PLAY[2]==0 => автоперелив отключён, при данном условии функция Func_color() не будет запускаться из функции loop.
Время перелива зависит от значения первого элемента массива MAS_PLAY[0] которое является задержкой в мс для изменения цвета на 1 деление ШИМ. Чем больше данное значение, тем дольше будет происходить перелив. По умолчанию значение равно 5мс, указывается в начале кода, при объявлении массива MAS_PLAY, данное значение можно изменять.


Обсуждение