• IR Remote Controlled Home Automation using PIC Microcontroller - Tự động hóa ngôi nhà được điều khiển từ xa bằng IR sử dụng Vi điều khiển PIC

QC

IR Remote Controlled Home Automation using PIC Microcontroller - Tự động hóa ngôi nhà được điều khiển từ xa bằng IR sử dụng Vi điều khiển PIC

 


Trong dự án này, chúng tôi sẽ sử dụng vi điều khiển PIC để điều khiển từ xa một số tải AC bằng cách chỉ sử dụng điều khiển từ xa IR. Một dự án tương tự Tự động hóa nhà điều khiển từ xa bằng IR cũng đã được thực hiện với Arduino, nhưng ở đây chúng tôi đã thiết kế nó trên PCB bằng cách sử dụng trình mô phỏng và thiết kế PCB trực tuyến của EasyEDA, đồng thời sử dụng các dịch vụ thiết kế PCB của họ để đặt hàng các bảng PCB như được hiển thị trong phần tiếp theo của bài báo.


Khi kết thúc dự án này, bạn sẽ có thể bật / tắt (BẬT / TẮT) bất kỳ tải AC nào bằng Điều khiển từ xa thông thường từ sự thoải mái của Ghế / Giường của bạn. Để làm cho dự án này thú vị hơn, chúng tôi cũng đã kích hoạt tính năng điều khiển tốc độ của quạt với sự trợ giúp của Triac. Tất cả những điều này có thể được thực hiện bằng những cú nhấp chuột đơn giản trên điều khiển từ xa IR của bạn. Bạn có thể sử dụng bất kỳ điều khiển từ xa TV / DVD / MP3 nào cho dự án này. Các tín hiệu IR khác nhau từ điều khiển từ xa được nhận bởi bộ vi điều khiển, sau đó sẽ điều khiển các rơ le tương ứng thông qua một mạch điều khiển rơ le. Các rơ le này được sử dụng để kết nối và ngắt kết nối các Tải AC (Đèn / Quạt).

Working Explanation:

The working of this project is fairly simple to understand. When a button is pressed on the IR Remote it sends a sequence of code in form of encoded pulses using 38Khz modulating frequency. These pulses are received by the TSOP1738 sensor and then read by the Controller. The Controller then decodes the received train of the pulses into a hex value and compares it with the predefined hex values ​​in our program.

If any match occurs then the controller performs a relative operation by triggering the respective Relay/Triac and the corresponding result is also indicated by on-board LEDs. Here in this project, we have used 4 bulbs (small bulbs) of different colors as lighting loads and another bulb (bigger bulb) is considered to be a fan for demonstration purpose.

We have selected key 1 to toggle the relay1, 2 to toggle the relay2, 3 to toggle the relay3, 4 to toggle the relay4, and Vol+ to increase fan speed and Vol- to decrease speed of the fan.

Note: Here we have used 100watt bulb instead of a fan.

There are many types of IR Remotes available for different devices, but most of them work around 38KHz Frequency. Here in this project, we control home appliances using IR TV remote and for detecting the IR signals, we use a TSOP1738 IR Receiver. This TSOP1738 sensor can sense 38Khz Frequency signal. The working of IR remote and the TSOP1738 is covered in detail in this article: IR Transmitter and Receiver

Our PIC microcontroller operates at +5V and the Relays operate at +12V, Hence we use a transformer to step down the 220V AC and rectify it using a full bridge rectifier. This rectified DC voltage is then regulated to +12V and +5V by using the regulator ICs 7812 and 7805 respectively.

To trigger the relay we make use of transistors like BC547 which can act as an electronic switch to turn ON/OFF the relays based on the signal from the PIC microcontroller.Further to control the speed of the fan we are using a TRIAC. TRIAC is a power semiconductor which is capable of controlling the output voltage; this capability is used to control the speed of the fan.

We have also used a Triac Driver to control the Triac using our PIC microcontroller. This driver is used to give a firing angle pulse to Triac, so that the output power can be controlled. Here we have used 6 levels of speed control. When the level is 0 then the fan will be off. When level will be 1 then speed will be 1/5th of full speed. When level will be 2 then speed will be 2/5th of full speed and respectively for others. The current level of the speed can be monitored using the on-board 7-segment display.

The block diagram of the project is shown below.



Components

The components required to build this project is given below:


  • PIC18f2520 Microcontroller           -1
  • TSOP1738                                       -1
  • IR TV/DVD Remote                      -1
  • Transistor BC547                            -4
  • Relays 12 volt                                 -4
  • Bulb with holder                             -5
  • Connecting wires                            -
  • EasyEda PCB                                 -1                    
  • 16x2 LCD
  • Power supply 12v
  • Terminal connector 2 pin     `           -8
  • Terminal Connector 3 pin                -1
  • Transformer 12-0-12                       -1                                             -
  • Voltage Regulator 7805                  -1
  • Voltage Regulator 7812                  -1
  • Capacitor 1000uf                            -1
  • Capacitor     10uf                             -1
  • Capacitor     0.1uf                            -1
  • Capacitor 0.01uf 400V       `           -1
  • 10k                                                  -5
  • 1k                                                    -5
  • 100ohm                                           -7
  • Common cathode segment -1
  • 1n4007 diode                                  -10
  • BT136 triac                                     -1
  • Male/female header             -
  • LEDs                                               -6
  • Opto-coupler moc3021                   -1
  • Opto-coupler mtc2e or 4n35           -1
  • 20Mhz crystal                                  -1
  • 33pf capacitor                                 -2
  • 5.1v zener diode                              -1
  • 47 ohm 2 watt resistor                     -1


Tất cả các thành phần này đều được sử dụng phổ biến và có thể dễ dàng mua được. Tuy nhiên, nếu bạn đang tìm kiếm cách mua hàng trực tuyến tốt nhất thì chúng tôi khuyên bạn nên sử dụng LCSC.


LCSC là một cửa hàng trực tuyến tuyệt vời để mua các linh kiện điện tử của bạn cho tất cả các loại dự án. Họ có khoảng 25.000 loại linh kiện và điều tốt nhất là họ bán các mặt hàng số lượng ít cho các dự án nhỏ và họ cũng có Vận chuyển toàn cầu.


Giải mã điều khiển từ xa IR:


Như đã nói trước đó, bạn có thể sử dụng bất kỳ loại điều khiển từ xa nào cho dự án của mình. Nhưng chúng ta phải biết loại tín hiệu được tạo ra từ điều khiển từ xa cụ thể đó. Đối với mỗi khóa riêng lẻ trên điều khiển từ xa sẽ có một giá trị HEX tương đương cho khóa đó. Sử dụng giá trị HEX này, chúng tôi có thể phân biệt giữa từng khóa ở phía bộ vi điều khiển của chúng tôi. Vì vậy, trước khi quyết định sử dụng một điều khiển từ xa, chúng ta nên biết giá trị HEX cho các phím được cài đặt trước trong điều khiển từ xa cụ thể đó. Trong dự án này, chúng tôi đã sử dụng điều khiển từ xa NEC. Các giá trị HEX cho các khóa trên điều khiển từ xa NEC được đưa ra bên dưới.




Như bạn có thể nhận thấy giá trị HEX có 7 ký tự, trong đó chỉ có hai ký tự cuối cùng khác nhau, do đó chúng ta chỉ có thể xem xét hai chữ số cuối cùng để phân biệt giữa mỗi khóa.




Circuit Diagram:

The schematic for the project is shown below.



Programming:

Chương trình cho dự án này được thực hiện bằng MPLABX, mã cũng khá đơn giản và dễ hiểu. Mã hoàn chỉnh sẽ được đưa ra ở cuối hướng dẫn này, một số phần quan trọng khác của chương trình được giải thích bên dưới.


Trong phần đầu của mã, chúng ta nên bao gồm các thư viện bắt buộc, xác định các chân và khai báo các biến.

#include <xc.h>
#include<string.h>
#include<stdlib.h>
#include "config.h"

#define tric RB1
#define ir RB2

#define relay1 RC2
#define relay2 RC3
#define relay3 RC4
#define relay4 RC5

#define rly1LED RB3
#define rly2LED RB4
#define rly3LED RB5
#define rly4LED RC1
#define fanLED RC0

int flag=0;
int cmd=0;
int speed=5;
unsigned int dat[100];
int i=0;
char result[10];
int j=0;

Sau đó, chúng ta đã tạo một hàm trì hoãn đơn giản bằng cách sử dụng vòng lặp “for”.


void delay(int time)
{
    for(int i=0;i<time;i++)
        for(int j=0;j<800;j++);
}

Sau đó, chúng tôi đã khởi tạo bộ đếm thời gian bằng cách sử dụng chức năng sau

void timer()           // 10 -> 1us
{
   T0PS0=0;
   T0PS1=0;
   T0PS2=0;
   PSA=0;      //Timer Clock Source is from Prescaler
   T0CS=0;     //Prescaler gets clock from FCPU (5MHz)
   T08BIT=0;   //16 BIT MODE
   TMR0IE=1;   //Enable TIMER0 Interrupt
   PEIE=1;     //Enable Peripheral Interrupt
   GIE=1;      //Enable INTs globally
   TMR0ON=1;      //Now start the timer!
}


Bây giờ trong chức năng chính, chúng ta đã đưa ra hướng cho các chân đã chọn và khởi tạo bộ định thời và ngắt bên ngoài int0 để phát hiện giao nhau bằng không.


  ADCON1=0b00001111;
   TRISB1=0;
   TRISB2=1;
   TRISB3=0;
   TRISB4=0;
   TRISB5=0;
   TRISC=0x00;
   TRISA=0x00;
   PORTA=0xc0;            
   TRISB6=0;
   RB6=1;
    relay1=0;
    relay2=0;
    relay3=0;
    relay4=0;
    rly1LED=0;
    rly3LED=0;
    rly2LED=0;
    rly4LED=0;
    fanLED=0;
        i=0;
    ir=0;
    tric=0;
    timer();
    INTEDG0 = 0; // Interrupt on falling edge
    INT0IE = 1; // Enable the INT0 external interrupt (RB0)
    INT0IF = 0; // Clears INT0 External Interrupt Flag bit
    PEIE=1;     //Enable Peripheral Interrupt
    GIE=1;      //Enable INTs globally


Bây giờ, ở đây chúng tôi không sử dụng bất kỳ chế độ ngắt hoặc chụp và so sánh nào để phát hiện tín hiệu IR. Ở đây chúng ta vừa sử dụng chốt kỹ thuật số để đọc dữ liệu giống như đọc nút nhấn. Bất cứ khi nào tín hiệu tăng cao hoặc thấp, chúng tôi chỉ cần đặt phương pháp gỡ lỗi và chạy bộ đếm thời gian. Bất cứ khi nào pin thay đổi trạng thái của nó sang trạng thái khác thì các giá trị thời gian sẽ được lưu trong một mảng.


IR từ xa gửi logic 0 là 562,5us và logic 1 là 2250us. Bất cứ khi nào bộ đếm thời gian đọc khoảng 562,5us thì chúng tôi giả sử nó là 0 và khi bộ đếm thời gian đọc khoảng 2250us thì chúng tôi giả định nó là 1. Sau đó, chúng tôi chuyển đổi nó thành hex.


Tín hiệu đến từ điều khiển từ xa chứa 34 bit. Chúng tôi lưu trữ tất cả các byte trong mảng và sau đó giải mã byte cuối cùng để sử dụng.


   while(ir == 1);
       INT0IE = 0;
       while(ir == 0);
       TMR0=0;
       while(ir == 1);
       i++;
       dat[i]=TMR0;

       if(dat[1] > 5000 && dat[1]<12000)
       {
       }
       else
       {
           i=0;
           INT0IE = 1;
       }

       if(i>=33)
       {
        GIE=0;
        delay(50);
        cmd=0;
        for(j=26;j<34;j++)
        {
            if(dat[j]>1000 && dat[j]<2000)
                cmd<<=1;

            else if(dat[j]>3500 && dat[j]<4500)
            {
                cmd|=0x01;
                cmd<<=1;
            }
        }
        cmd>>=1;

Đoạn mã trên nhận và giải mã tín hiệu IR bằng cách sử dụng ngắt bộ định thời và lưu giá trị HEX tương ứng trong biến cmd. Bây giờ chúng ta có thể so sánh giá trị HEX này (biến cmd) với các giá trị HEX được xác định trước của chúng ta và chuyển đổi rơ le như hình dưới đây


if(cmd == 0xAF)
         {
             relay1=~relay1;
             rly1LED=~rly1LED;
         }

         else if(cmd == 0x27)
         {
             relay2=~relay2;
             rly2LED=~rly2LED;
         }
        
         else if(cmd == 0x07)
         {
             relay3=~relay3;
             rly3LED=~rly3LED;
         }
         else if(cmd == 0xCF)
         {
             relay4=~relay4;
             rly4LED=~rly4LED;
         }
         else if(cmd == 0x5f)
         {
             speed++;
             if(speed>5)
             {
                 speed=5;
             }
         }

         else if(cmd == 0x9f)
         {
             speed--;
             if(speed<=0)
             {
                 speed=0;
             }
         }

Bây giờ để biết quạt của chúng ta hiện đang hoạt động, chúng ta nên sử dụng màn hình 7 đoạn. Các dòng sau đây được sử dụng để hướng dẫn các chân của màn hình 7 đoạn.


if(speed == 5)        // turned off  5x2= 10ms triger    //speed 0
        {
            PORTA=0xC0;           // display 0
            RB6=1;
            fanLED=0;            
        }      

        else if(speed == 4 )    //  8 ms trigger    //speed 1
        {
            PORTA=0xfc;        // displaying 1
            RB6=1;
            fanLED=1;
        }
       
        else if(speed == 3)   //   6 ms trigger       // speed 2
        {
            PORTA=0xE4;       // displaying 2                   
            RB6=0;
            fanLED=1;
        }
       
        else if(speed == 2)   // 4ms trigger  // speed 3
        {
            PORTA=0xF0;       // displaying 3
            RB6=0;
            fanLED=1;
        }
       
        else if(speed == 1)    // 2ms trigger  // speed 4
        {
            PORTA=0xD9;          // displaying 4
            RB6=0;
            fanLED=1;
        }
    
        else if(speed == 0)        // 0ms trigger  // speed 5  full power
        {
           PORTA=0xD2;            // displaying 5
           RB6=0;
           fanLED=1;
        }

Hàm dưới đây dành cho ngắt ngoài và tràn thời gian. Chức năng này có nhiệm vụ phát hiện đường cắt ngang và lái xe Triac.

void interrupt isr()
{
    if(INT0IF)
    {
        delay(speed);
        tric=1;
        for(int t=0;t<100;t++);
        tric=0;
        INT0IF=0;
    }
  
   if(TMR0IF)  //Check if it is TMR0 Overflow ISR  
   {
      TMR0IF=0;
   }
}




CODE 

#include <xc.h>
#include<string.h>
#include<stdlib.h>
#include "config.h"

#define tric RB1
#define ir RB2

#define relay1 RC2
#define relay2 RC3
#define relay3 RC4
#define relay4 RC5

#define rly1LED RB3
#define rly2LED RB4
#define rly3LED RB5
#define rly4LED RC1
#define fanLED RC0

int flag=0;
int cmd=0;
int speed=5;
unsigned int dat[100];
int i=0;
char result[10];
int j=0;
   
void delay(int time)
{
    for(int i=0;i<time;i++)
        for(int j=0;j<800;j++);
}

void timer()           // 10 -> 1us
{
   T0PS0=0; 
   T0PS1=0;
   T0PS2=0;
   PSA=0;      //Timer Clock Source is from Prescaler
   T0CS=0;     //Prescaler gets clock from FCPU (5MHz)
   T08BIT=0;   //16 BIT MODE
   TMR0IE=1;   //Enable TIMER0 Interrupt
   PEIE=1;     //Enable Peripheral Interrupt
   GIE=1;      //Enable INTs globally
   TMR0ON=1;      //Now start the timer!
}

void main(void) 
{
   ADCON1=0b00001111;
   TRISB1=0;
   TRISB2=1;
   TRISB3=0;
   TRISB4=0;
   TRISB5=0;
   TRISC=0x00;
   TRISA=0x00;
   PORTA=0xc0;             
   TRISB6=0;
   RB6=1;
    relay1=0;
    relay2=0;
    relay3=0;
    relay4=0;
    rly1LED=0;
    rly3LED=0;
    rly2LED=0;
    rly4LED=0;
    fanLED=0;
        i=0;
    ir=0;
    tric=0;
    timer();
    INTEDG0 = 0; // Interrupt on falling edge
    INT0IE = 1; // Enable the INT0 external interrupt (RB0) 
    INT0IF = 0; // Clears INT0 External Interrupt Flag bit
    PEIE=1;     //Enable Peripheral Interrupt
    GIE=1;      //Enable INTs globally

   while(1)
   {   
       while(ir == 1);
       INT0IE = 0;
       while(ir == 0);
       TMR0=0;
       while(ir == 1);
       i++;
       dat[i]=TMR0;
       
       if(dat[1] > 5000 && dat[1]<12000)
       {
       }
       else
       {
           i=0;
           INT0IE = 1;
       }

       if(i>=33)
       {
        GIE=0;
        delay(50);
        cmd=0;
        for(j=26;j<34;j++)
        {
            if(dat[j]>1000 && dat[j]<2000)
                cmd<<=1;

            else if(dat[j]>3500 && dat[j]<4500)
            {
                cmd|=0x01;
                cmd<<=1;
            }
        }
        cmd>>=1;
         
         if(cmd == 0xAF)
         {
             relay1=~relay1;
             rly1LED=~rly1LED;
         }
         
         else if(cmd == 0x27)
         {
             relay2=~relay2;
             rly2LED=~rly2LED;
         }
         
         else if(cmd == 0x07)
         {
             relay3=~relay3;
             rly3LED=~rly3LED;
         }
         
         else if(cmd == 0xCF)
         {
             relay4=~relay4;
             rly4LED=~rly4LED;
         }
         
         else if(cmd == 0x5f)
         {
             speed++;
             if(speed>5)
             {
                 speed=5; 
             }
         }
         
         else if(cmd == 0x9f)
         {
             speed--;
             if(speed<=0)
             {
                 speed=0; 
             }
         }
         
        if(speed == 5)        // turned off  5x2= 10ms triger    //speed 0
        {
            PORTA=0xC0;           // display 0
            RB6=1;
            fanLED=0;             
        }
        
        else if(speed == 4 )    //  8 ms trigger    //speed 1
        { 
            PORTA=0xfc;        // displaying 1
            RB6=1;
            fanLED=1;
        }
        
        else if(speed == 3)   //   6 ms trigger     // speed 2
        {
            PORTA=0xE4;       // displaying 2                    
            RB6=0;
            fanLED=1;
        }
        
        else if(speed == 2)   // 4ms trigger  // speed 3
        {
            PORTA=0xF0;       // displaying 3
            RB6=0;
            fanLED=1;
        }
        
        else if(speed == 1)    // 2ms trigger  // speed 4
        {
            PORTA=0xD9;          // displaying 4
            RB6=0;
            fanLED=1;
        }
        
        else if(speed == 0)        // 0ms trigger  // speed 5  full power
        {
           PORTA=0xD2;            // displaying 5
           RB6=0;
           fanLED=1;
        }
        
        else
        {
            RB6=1;
            PORTA=0xff;         // display off
            fanLED=0;
        }
        
        i=0;
        INT0IE = 1;
        GIE=1;
       }
}
}

void interrupt isr()
{
    if(INT0IF)
    {
        delay(speed);
        tric=1;
        for(int t=0;t<100;t++);
        tric=0;
        INT0IF=0;
    }
    
   if(TMR0IF)  //Check if it is TMR0 Overflow ISR   
   {
      TMR0IF=0;
   }
    
}







Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...