среда, 1 января 2014 г.

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

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


Вот об этом пульте будет идти речь в статье


Подобные пульты передают информацию включая и выключая достаточно яркий инфракрасный светодиод. Человеки не видят ИК излучение, поэтому мигание этого светодиода никого не раздражает. Однако, в данном конкретном пульте этот недостаток устранен установкой дополнительного красного светодиода.

Для приема сигналов ИК пультов созданы специальные микросхемы. Называются они TSOP. Основной их характеристикой является частота принимаемого сигнала. Наиболее распространены TSOP на 36 кГц и 38 кГц. Рассматриваемый пульт мигает светодиодом с частотой 38 кГц.

Для ардуино существует немало модулей предназначенных для приема сигналов ИК пультов


У таких модулей одинаковое количество выводов. Три. Назначение выводов также не сильно отличается. Земля (GND). Питание (VCC). И выход (OUT). Правда порядок расположения выводов может быть различным у разных модулей. Будьте внимательны.

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

Единица выглядит так


 Ноль выглядит так


Светодиод включается на 13 микросекунд. Затем светодиод отключается на 13 микросекунд. Так повторяется десять раз. После этого светодиод не светит 1786 микросекунд или 776 микросекунд. От продолжительности этой паузы зависит единица или ноль передается пультом.

Получая эти сигналы TSOP создает на выходе изображенные ниже колебания.

Единица


Ноль


Увидев мигания инфракрасного светодиода TSOP устанавливает на выходе низкий логический уровень. Такой логический уровень удерживается до тех пор пока мигает инфракрасный светодиод пульта. И даже немного дольше. В общем это длится 322 микросекунды. Затем на выходе снова устанавливается высокий логический уровень. Если высокий логический уровень присутствует на выходе 1724 микросекунды, значит принята единица. А если высокий логический уровень присутствует на выходе 714 микросекунд, значит принят ноль.

При нажатии любой кнопки пульта передается 16 бит (2 байта). Старший байт представляет собой код пульта. Он одинаков у всех кнопок. Младший байт это код нажатой кнопки пульта. У каждой кнопки он свой. Передача данных заканчивается завершающим битом. Его значение не важно. Да и определить это весьма проблематично. За всем этим следует пауза длительностью около 24 миллисекунд. После этой паузы все повторяется. И так до тех пор пока кнопка не будет отпущена.

Чтобы было проще осмыслить написанное выше я изобразил как выглядит код кнопки пульта mouse up на выходе TSOP


Ниже приводится таблица кодов всех кнопок пульта

Key Bin Hex Dec
Power 0b1110001011100100 0xe2e4 58084
E-mail 0b1110001001100100 0xe264 57956
Internet 0b1110001010100100 0xe2a4 58020
Close 0b1110001000100100 0xe224 57892
Hotkey A 0b1110001011000100 0xe2c4 58052
Hotkey B 0b1110001001000100 0xe244 57924
Hotkey C 0b1110001010000100 0xe284 57988
Hotkey D 0b1110001000000100 0xe204 57860
Mouse up 0b1110001010000000 0xe280 57984
Mouse left 0b1110001010110000 0xe2b0 58032
Mouse right 0b1110001000110000 0xe230 57904
Mouse down 0b1110001001000000 0xe240 57920
Mouse left key 0b1110001010010000 0xe290 58000
Move window 0b1110001010010100 0xe294 58004
Mouse right key 0b1110001000100000 0xe220 57888
Previous 0b1110001000111000 0xe238 57912
Play/Pause 0b1110001010011000 0xe298 58008
Next 0b1110001000101000 0xe228 57896
Backward 0b1110001010111000 0xe2b8 58040
Stop 0b1110001010001000 0xe288 57992
Forward 0b1110001010101000 0xe2a8 58024
Vol + 0b1110001010100000 0xe2a0 58016
Vol - 0b1110001001010000 0xe250 57936
Full screen 0b1110001001011000 0xe258 57944
Page up 0b1110001000000000 0xe200 57856
Page down 0b1110001001100000 0xe260 57952
Mute 0b1110001001001000 0xe248 57928
My PC 0b1110001011110000 0xe2f0 58096
Backspace 0b1110001011000000 0xe2c0 58048
Tab 0b1110001011011000 0xe2d8 58072
Up arrow 0b1110001011001000 0xe2c8 58056
Start 0b1110001011010000 0xe2d0 58064
Left arrow 0b1110001000011000 0xe218 57880
Enter 0b1110001000001000 0xe208 57864
Right arrow 0b1110001000010000 0xe210 57872
Open 0b1110001001111000 0xe278 57976
Down arrow 0b1110001001101000 0xe268 57960
Esc 0b1110001001110000 0xe270 57968
Numlock 0b1110001011111000 0xe2f8 58104
Switch window 0b1110001011101000 0xe2e8 58088
Desktop 0b1110001011100000 0xe2e0 58080

Этого достаточно для написания программы

////////////////////////
//
// Arduino UNO
//
////////////////////////
//
// Sketch: IR RC
//

const unsigned char LED1 = 13;
const unsigned char LED2 = 12;

const unsigned int LED1_1 = 0xE2C4; // Hotkey A
const unsigned int LED1_0 = 0xE244; // Hotkey B
const unsigned int LED2_1 = 0xE284; // Hotkey C
const unsigned int LED2_0 = 0xE204; // Hotkey D

volatile unsigned int data = 0;
volatile unsigned long int time1 = 0;
volatile unsigned long int time2 = 0;
volatile unsigned long int period = 0;

void setup()
{
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);

    attachInterrupt(0, tsop, FALLING);
}

void loop()
{
    if ( data == LED1_1 ) digitalWrite(LED1, HIGH);
    if ( data == LED1_0 ) digitalWrite(LED1, LOW);
    if ( data == LED2_1 ) digitalWrite(LED2, HIGH);
    if ( data == LED2_0 ) digitalWrite(LED2, LOW);
}

void tsop()
{
    time1 = micros();
    period = time1 - time2;
    time2 = time1;

    data <<= 1;

    if ( period > 1500 ) data |= 1;
    if ( period > 15000 ) data = 0;
}

//
// End
//
////////////////////////

Несколько пояснений по железу. Выход ИК приемника подключается к цифровому выводу 2 ардуино. Светодиоды подключаются к цифровым выводам 13 и 12.