Управление arduino (микроконтролером) с помощью ИК-пульта
Автор: SysaninФев 10
В статье описываю как можно подружить arduino (да и собственно любой микроконтроллер) с ИК пультом от телевизора, плеера и т.д. Так же приведу получившийся плагин для arduino для работы с пультом от тюнера Behold TV и небольшое тестовое устройство, которое по нажатию кнопок пульта может зажигать один из двух светодиодов или гасить их.

Кодирование команд пультом:
Сначало расскажу про принцип кодирования команд для нашего пульта (у меня был от тюнера Behold TV, хотя такой принцип используется многими производителям).
Сначало идет еденичный импульс длительностью около 9 мс (из-за разных помех и разброса параметров может несколько изменяться). Он является самым длиным, поэтому его можно определять из условия того что он длинее 8 мс (делаем небольшой запас, что б точно определить сигнал).
Далее передается 32 бита с кодом клавиши. Биты кодируются временным методом: отправляется опорные импульсы (порядка 500 мкс) и в зависимости от времени между опорными импульсами будет 1 или 0. 0 соответствует время около 500 мкс, а 1 - 1600 мкс. Если кнопка продолжается оставаться нажатой, то после кода клавиши непрерывно формируются импульсы аналогичные начальному (длительностью около 9 мс).
Распознование команд arduino от пульта:
Я решил оформить часть, которая распознает команды, для удоабства в виде плагина. В рамках данной заметки мы не будем рассматриваться премудрости написания плагинов для ардуино, так что остановлюсь на самом алгоритме.
Он состоит из двух функций одна (getCode) предназначена для того что б получить 32х битный код любой клавиши. Служит для распознования кнопок, на случай, если используется пульт отличный от моего или вовсе другой, но с таким же методом шифрования.
Вторая функция (waitPressKey) ожидает нажатия клавиши на пульте, ее следует запускать из цикла. Правда функиця отслеживает только одинарное нажатие, при удержании кнопок, возможны какие-то проблемы.
Следует учесть что я использовал применик с инверсным выходом.
Разберем принцип работы функции waitPressKey (у getCode аналогичный принцип)
int time = pulseIn(_pin, LOW);
int code[32];
//ждем начальный длинный сигнал (который около 9 мс)
if (time > 8000) {
//пришел начальный сигнал, начинаем считывать код
int i = 0;
while(true) {
time = pulseIn(_pin, HIGH);
//читаем 32 бита, но если чтение было
//вызвано долгим удержанием кнопки, то прерываем чтение
if (time > 2000) {
return 0;
}
if (i > 31) {
break;
}
//исходя из длительности паузы определяем 0 или 1
code[i] = time > 900 ? 1 : 0;
i++;
}
//делаем задержку в 200 мс, что б у пользователя было время
//отпустить кнопку, это время не читаем команды
delay(200);
//ищем какую кнопку нажал пользователь и возращаем
//ее номер (часть команд пропущено)
if (IRB::isThisCommand(code, "01100001110101100011100011000111")) {
return IRB_FUNCTION;
}
if (IRB::isThisCommand(code, "01100001110101100100100010110111")) {
return IRB_POWER;
}
//...
if (IRB::isThisCommand(code, "01100001110101101100100000110111")) {
return IRB_MUTE;
}
}
return 0;
}
//служебная функция сравнивает два массива
//со считанной командой и записаными командами
boolean IRB::isThisCommand(int check[], char command[]) {
for (int i=0; i < 32; i++) {
int code = command[i] == 49 ? 1 : 0;
if (check[i] != code){
return false;
}
}
return true;
}
Железная часть:
Для приема и усиления сигнала был взят ИК приемник из серии TSOP (впринципе можно брать любой, хотя лучше что б частота несущая в приемнике была такая же как и у пульта).
Для индикации нажатых кнопок взял два сверхярких светодиода разных цветов.
Для питания используется 6В свинцовый акумулятор.
ИК-приемник можно подключать сразу с арудино, т.к. он снабжен всем необходимым (демодулятором, усилителем). Питиание для приемника я взял с выходов 5V и GND, а передавать данные можно в любой цифровой порт (я брал 8). Светодиоды я подключал напрямую к свободным портам (10 и 11) и к земле (GND), хотя, если они будут гореть долгое время, то лучше поставить на каждый последовательно резистор Ом на 100 (зависит от светодиодов).
Программа управления:
Для тестирования ИК-приемника напишем небольшую программу, которая сделает так что при нажатии на кнопку function пульта будет загораться один светодиод, при нажатии на ok другой, а при нажатии на power отключаться оба светодиода:
#include
//объявляем переменные с номерами кнопок
#define IRB_FUNCTION 1
#define IRB_POWER 2
#define IRB_OK 24
//инициализируем плагин на 8 порт (тут слушаем ИК-приемник)
IRB IRB(8);
void setup() {
//на этих портах светодиоды
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}
void loop() {
//получаем номер нажатой кнопки
int code = IRB.waitPressKey();
if (code != 0) {
switch (code) {
case IRB_FUNCTION :
digitalWrite(11, HIGH);
break;
case IRB_POWER :
digitalWrite(11, LOW);
digitalWrite(12, LOW);
break;
case IRB_OK :
digitalWrite(12, HIGH);
break;
}
}
}
Вот так будет работать устройство:
Скачать плагин можно отсюдо.


Нет комментариев