Електроніка

Зчитування кодів ІЧ-пульта за допомогою TSOP4836 на мікроконтролері PIC18F2520

Мабуть, багато хто з тих, хто захоплюється розробкою на мікроконтролерах, хоча б кілька разів замислювався над можливістю керувати пристроєм за допомогою звичайного ІЧ-пульта від телевізора. Особливо приваблює те, що для підключення ІЧ-приймача TSOP4836 потрібні лише один вільний вивід і два резистори! Колись і я спробував такий варіант.

схема підключення TSOP4836 до мікроконтролера PIC18F2520

Розташування виводів 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»

Пульт телевізора 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»

ІЧ-пульт 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

ІЧ-пульт 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:

ІЧ-пульт до плати відеозахоплення 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

Обговорення 2

  1. When specific buttons are pressed, you can use the incoming values to do something else in your code, for example turn on and off a motor or LED.

Залишити коментар

Вашу електронну адресу не буде оприлюднено. Обов’язкові поля позначено *