Наверное многие из любителей разработок на микроконтроллерах хоть пару раз но задумывались над возможностью управления устройством при помощи обычного ИК-пульта от телевизора. Особо подкупает то, что для подключения ИК-датчика TSOP4836 требуется всего навсего один свободный пин и два резистора! Когда-то и я пробовал такой вариант.
Распиновка TSOP4836
Я собрал простую схему на 18F2520 и разобрался как декодировать сигналы и написал код, при помощи которого получил сигнатуры для всех доступных мне на тот момент ИК-пультов.
Далее приведу исходники, при помощи которых можно получать 32-битные сигнатуры для разных кнопок пульта:
#include <18f2520.h> #define FCONST OSC_8MHZ // эту частоту будем устанавливать программно (используя PLL) #define FREQ 8000000 // используемая частота #pragma config WDT = OFF #pragma config LVP = OFF #fuses INTRC_IO #use delay (clock=FREQ) #use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3) #define LED PIN_A0 INT1 Received=false; long t; int8 i; // настройка прерывания на нужный фронт импульса #define LH_Edge 0 #define HL_Edge 1 int8 edge; // показывает на какой фронт импульса мы настроили прерывание 0 - L_to_H, 1 - H_to_L void setEdge(int1 e) { edge=e; if (e==LH_Edge) { ext_int_edge(0, L_TO_H); } else { ext_int_edge(0, H_TO_L); } } int32 t0,t1; // для сохранения длительности 0 и 1 int32 code; // расшифрованный код с пульта ДУ int8 timerov; // количество переполнений таймера int8 cnt=0xFF; // количество принятых импульсов (если FF то счет не идет, это знак сброса) #define MIN_LEAD_IN 1000 // 4 ms #define MAX_LEAD_IN 1500 // 6 ms #define MIN_TIME 60 // 0.24 ms #define MID_TIME 200 // 0.8 ms #define MAX_TIME 800 // 3.2 ms #int_EXT EXT_isr() { if (!received) { // если код уже считан, но не обработан основной программой - ничего не делаем if (edge==HL_Edge) { // если словили 1->0 t1=(0x10000*timerov+get_timer0()); // запоминаем сколько длилась 1 } else { // если словили 0->1 t0=(0x10000*timerov+get_timer0()); // запоминаем сколько длился 0 if (cnt==0xFF) { if ((t1>MIN_LEAD_IN)&&(t1<MAX_LEAD_IN)) { // словили сигнал начала передачи cnt=0; code=0; } } else { // приняли очередную пару 0->1 if ((t1<MAX_TIME)&&(t1>MIN_TIME)&&(t0>MIN_TIME)&&(t0<MAX_TIME)) { // параметры сигнала в норме, анализируем if ((t1<MID_TIME)&&(t0<MID_TIME)) { // это 0 } else { // это 1 bit_set(code,cnt); } cnt++; } else { // параметры вышли за границу, делаем сброс cnt=0xFF; } } if (cnt==23) { // приняли все 23 бит received=TRUE; cnt=0xFF; } } } setEdge(!edge); // теперь будем ловить другой фронт импульса timerov=0; set_timer0(0); } #int_TIMER0 // происходит по переполнению 16 бит таймера TIMER0_isr() { if (timerov<255) timerov++; } void main() { setup_oscillator(FCONST); delay_ms(5000); printf("initr"); setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_spi(FALSE); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_timer_3(T3_DISABLED|T3_DIV_BY_1); enable_interrupts(INT_EXT); enable_interrupts(GLOBAL); enable_interrupts(INT_TIMER0); setEdge(HL_Edge); set_timer0(0); delay_ms(10); t=get_timer0(); printf("%Lu",t); printf("00 tick/sec"); printf("gor"); DO { IF (received) { disable_interrupts(GLOBAL); printf("%lx ",code); printf("r"); enable_interrupts(GLOBAL); received=false; } } WHILE (true); }
Далее приведу таблицы ИК-кодов для исследованных мной пультов. Коды в таблице визуально располагаются в соответствии с расположением кнопок на пультах.
Таблица кодов пульта “TOSHIBA CT-90119”
0016bf40 | 0012bf40 | ||
0013bf40 | 0017bf40 | 0010bf40 | |
0001bf40 | 0002bf40 | 0003bf40 | |
0004bf40 | 0005bf40 | 0006bf40 | |
0007bf40 | 0008bf40 | 0009bf40 | |
000bbf40 | 0000bf40 | 0014bf40 | |
001bbf40 | |||
001ebf40 | 001abf40 | ||
001fbf40 | |||
005bbf40 | 0018bf40 | 001cbf40 | |
0053bf40 | 0054bf40 | 000dbf40 | |
0048bf40 | 0015bf40 | 004bbf40 | |
0049bf40 | 004abf40 |
Таблица кодов пульта “Twinhan-DVB”
004dff00 | 0016ff00 | ||
0003ff00 | 0001ff00 | 0006ff00 | |
0009ff00 | 001dff00 | 001fff00 | |
000dff00 | 0019ff00 | 001bff00 | |
0011ff00 | 0015ff00 | 0017ff00 | |
0040ff00 | 0005ff00 | 0012ff00 | |
000aff00 | 0014ff00 | 001eff00 | |
000eff00 | 0002ff00 | 001aff00 | |
004cff00 | 0010ff00 | 000cff00 | |
0054ff00 | 0048ff00 | 001cff00 | |
0004ff00 | 0000ff00 | 000fff00 |
Таблица кодов для пульта ORION-DVD
0054bf40 | 005bbf40 | |||
0014bf40 | 0057bf40 | 0041bf40 | 0046bf40 | |
0009bf40 | 001dbf40 | 001fbf40 | 000dbf40 | |
0019bf40 | 001bbf40 | 0011bf40 | 0015bf40 | |
0017bf40 | 0012bf40 | 0059bf40 | 0008bf40 | |
0050bf40 | 0055bf40 | 0048bf40 | 004abf40 | |
005ebf40 | 0006bf40 | 0005bf40 | 0003bf40 | |
0047bf40 | 0007bf40 | 0040bf40 | 0002bf40 | |
0018bf40 | 0044bf40 | 000fbf40 | 0051bf40 | |
000abf40 | 001ebf40 | 000ebf40 | 001abf40 | |
0053bf40 | 0052bf40 | 0001bf40 | 0045bf40 |
Таблица кодов для ИК-пульта AVerMedia:
0001fd02 | 0002fd02 | 0003fd02 | 0000fd02 | |
0005fd02 | 0006fd02 | 0007fd02 | 0004fd02 | |
0009fd02 | 000afd02 | 000bfd02 | 0008fd02 | |
000dfd02 | 000efd02 | 000ffd02 | 000cfd02 | |
0011fd02 | 0012fd02 | 0013fd02 | 0010fd02 | |
0015fd02 | 0016fd02 | 0017fd02 | 0014fd02 | |
0019fd02 | 001afd02 | 001bfd02 | 0018fd02 | |
001dfd02 | 001efd02 | 001ffd02 | 001cfd02 | |
0001fc03 | 0002fc03 | 0003fc03 | 0000fc03 |