Chào mừng bạn đến với Điện Tử Viễn Thông SV! =>>Chúc Bạn Một Ngày Vui Vẻ....!

Thứ Năm, 15 tháng 6, 2017

Giao tiếp vi điều khiển với hồng ngoại điều khiển bằng remote

I.GIỚI THIỆU
1.REMOTE HỒNG NGOẠI
·Remote là một thiết bị phát sóng hồng ngoại, sử dụng trong các mục đích điều khiển từ xa (tầm 10m). Remote nhận lệnh điều khiển từ người điều khiển thông qua các phím bấm, sau đó xuất ra một khung dữ liệu ứng với phím được bấm.
·Có rất nhiều loại remote được sử dụng như: Sony, LG,… mỗi loại có 1 cách mã hóa phím bấm khác nhau (các bạn có thể tự tìm hiểu thêm).
·Trong project này mình sử dụng remote 3 kênh:


Khi 1 kênh được ấn, khung truyền dữ liệu có dạng như sau:
[​IMG]
Sau xung START, 8 bit 0, 8 bit 1 là mã của kênh được bấm.
>Bit 0 được định nghĩa: tín hiệu ở mức thấp trong 700us và ở mức cao trong 500us.
>Bit 1 được định nghĩa: tín hiệu ở mức thấp trong 700us và ở mức cao trong 1600us.

2.MẮT THU HỒNG NGOẠI.
·Mắt thu hồng ngoại gồm 3 chân: VCC, GND, DATA:
[​IMG]
·Mắt thu hồng ngoại có chức năng chuyển sóng hồng ngoại phát ra từ remote thành đúng dạng tín hiệu số ứng với phím được bấm, nhưng tín hiệu ra có pha ngược với tín hiệu từ remote.
·Khi không có sóng tới, tín hiệu ra trên chân DATA ở mức cao.

II.THỰC HÀNH PROJECT.
1.THIẾT KẾ PHẦN CỨNG.
Trong project này, có 2 khối các bạn cần thiết kế:
-Khối vi điều khiển Atmega 8 và mắt thu hồng ngoại:
[​IMG]
-Khối Relay để điều khiển thiết bị bên ngoài:
[​IMG]
2.LẬP TRÌNH PHẦN MỀM.
Đối với hồng ngoại, thuật toán của bạn đưa ra chỉ cần thỏa mãn 2 yêu cầu sau:
-Các kênh khác nhau cho mã lệnh khác nhau khi được ấn.
-Một kênh chỉ cho duy nhất một mã lệnh. 
(Mã nhận về không cần thiết phải giống mã của nhà sản xuất định sẵn cho các kênh).
Dựa vào khung truyền đã nói ở trên, mình sẽ có 2 hàm để xử lý cảm biến hồng ngoại:
-Hàm kiểm tra xung START: 
Mã:
// Ham check xung START
/* Xung START là xung co:
- tin hieu o muc thap (0) có do dai 9ms
- tin hieu o muc cao (1) có do dai 4ms
Chi kiem tra tin hieu o muc thap dung 9ms la dung xung START
*/
unsigned char check_start()
{
    unsigned char i;
    if(DATA_INFR==0)              // Neu co canh xuong cua tin hieu
    {
          delay_us(500);          // Delay de chong nhieu
          if(DATA_INFR==0)        // Neu dung la co canh xuong cua tin hieu
          {
              for(i=0;i<40;i++)  // Chia nho xung START thanh 40 doan, moi doan dai 200us
              {
                    delay_us(200);
                    if(DATA_INFR==1) return 0;    // Neu tin hieu len muc cao (1) --> khong phai xung START
              }
              while(DATA_INFR==1);   
              return 1;          // Dung la xung start
          }
 
    }
}  
-Hàm nhận về mã của kênh remote:
// ===============================================================
//  Ham doc ma cua cac kenh
unsigned long int infr_sensor()
{
    unsigned char i;
    unsigned int Data_Infr;
    Data_Infr=0;
    if(check_start())                  // Neu dung xung START
    {
          while(DATA_INFR==1);          // Cho het bit 1 tiep theo
          while(DATA_INFR==0);          // Cho het bit 0 tiep theo
          for(i=0;i<24;i++)            // Lay 24 bit du lieu (bao gom 8 bit 0 va 8 bit 1 dau tien sau xung start)
          {
              //while(DATA_INFR==0);
              delay_us(750);          // Delay 750us de kiem tra bit
              if(DATA_INFR==0) Data_Infr=Data_Infr*2 + 1;
              if(DATA_INFR==1) Data_Infr=Data_Infr*2;
              while(DATA_INFR==1);    // cho canh len
              while(DATA_INFR==0);    // cho canh len
          }
          delay_ms(600);                // Cho het tin hieu (chong nhieu)
    }
    return Data_Infr;                  // Gia tri ma kenh tra ve
}
Trước khi dùng phục vụ mục đích điều khiển, các bạn nên cho hiển thị mã của các kênh trên remote lên LCD1602 để lưu lại giá trị mã của từng kênh.
Các bạn có thể tham khảo code mẫu dưới đây
Mã:Gi
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program
 
Project : DIEU KHIEN QUAT DIEN SU DUNG REMOTE HONG NGOAI 20 KENH.
Version : V1.0.0
Comments: Su dung 2 Relay dieu khien ON/OFF quat va che do quay quat
 
Chip type              : ATmega8
Program type            : Application
AVR Core Clock frequency: 1.000000 MHz
Memory model            : Small
External RAM size      : 0
Data Stack size        : 256
*****************************************************/
 
#include <main.h>
 
void main(void)
{
 
unsigned char Lcd_Buffer[20];           
unsigned long int Data;      // Ma cac kenh cua remote               
// Declare your local variables here
 
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x10;
DDRB=0x00;
 
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0xff;
DDRC=0xff;
 
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x0f;
 
// Alphanumeric LCD initialization
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 1
// RD - PORTB Bit 2
// EN - PORTB Bit 3
// D4 - PORTC Bit 2
// D5 - PORTC Bit 3
// D6 - PORTC Bit 4
// D7 - PORTC Bit 5
// Characters/line: 16
RELAY1 = RELAY2 = 1;
/*
lcd_init(16);                // Ham khoi tao LCD1602
lcd_clear();                  // Ham xoa LCD1602
lcd_gotoxy(0,0);              // Di chuyen con tro den vi tri (0,0)
lcd_putsf("MINHHAGROUP.COM");
*/
while (1)
      {
          Data = infr_sensor();    // Gan ma cua kenh vao bien Data 
/*
Ham hien thi gia tri ma cua cac kenh len LCD1602
    if(Data!=0)
    {
          lcd_gotoxy(0,1)
          sprintf(Lcd_Buffer,"Ma Kenh: %lu",Data);
          lcd_puts(Lcd_Buffer);
    }
*/
 
// Ham dieu khien RELAY ========================================================   
          if(Data!=0)              // Neu co kenh tren remote duoc an   
          { 
              if(Data == OF_QUAT) // Thuc hien lenh dieu khien ung voi moi phim
              {   
                    RELAY1 =~RELAY1;       
              } 
                if((Data == QUAY_QUAT)|(Data == QUAY_QUAT1))
              {         
                  RELAY2 =~RELAY2;
              }
             
          } 
         
      }
}
 
//---------------END OF FILE-----------------/
//--------------------------------------------/