11:37 AM
0

Điều khiển bằng hồng ngoại với Arduino

Xin chào các bạn, hôm nay mình sẽ giới thiệu về cách sử dụng Remote TV để điều khiển các thiết bị điện tử với sự giúp đỡ của Arduino.

NỘI DUNG CHÍNH

  • Đọc tín hiệu từ Remote.
  • Điều khiển TV với Arduino.

PHẦN CỨNG

  1. 1 board Arduino UNO x1.
  2. IR LED (hay còn gọi là LED hồng ngoại) x1. 
  3. Điện trở 30 ôm x1.
  4. IR receiver x1.
  5. Remote TV x1.
  6. Nút bấm x4.
  7. Dây cắm breadboard
  8. Breadboard

GIỚI THIỆU

Hầu hết chúng ta đã sử dụng remote hồng ngoại để điều khiển TV, quạt, máy điều hòa,....nhưng không phải ai cũng biết remote làm việc ra sao. Tín hiệu hồng ngoại là 1 chùm sóng ánh sáng không thể nhìn thấy bằng mắt thường, do đó, bạn không thể thấy ánh sáng khi nhìn vào cái đèn LED nhỏ ở đầu của remote.
Trên remote có 1 hoặc nhiều LEDs hồng ngoại được sử dụng để truyền tín hiệu hồng ngoại. Tín hiệu này sẽ được nhận bởi 1 bộ thu hồng ngoại đặc biệt và chuyển thành dạng xung điện, sau đó các xung điện này được chuyển đổi thành dữ liệu được sử dụng cho các thiết bị điện tử.
Nếu bạn tò mò muốn biết ánh sáng hồng ngoại nó như thế nào, hãy nhấn 1 nút bất kỳ trên remote rồi nhìn vào cái đèn LED ở đầu remote thông qua 1 chiếc camera nhé!

IR RECEIVER

Trong bài viết này mình sử dụng IR receiver loại 36Khz. Vì mỗi loại IR receiver có sơ đồ chân khác nhau nên các bạn nên tham khảo datasheet của nó hoặc là hỏi người bán để biết thêm chi tiết.

IR LED (LED hồng ngoại)

Nhìn bên ngoài thì IR LED giống hệt LED thường, nhưng vì nó phát ra ánh sáng hồng ngoại nên bạn không thể thấy được ánh sáng của nó bằng mắt thường.

REMOTE

Trong bài này mình sử dụng remote Sony RM-869, remote nào cũng như nhau cả, các bạn chỉ cần 1 cái remote còn dùng được là ok!
Chúng ta sẽ làm quen với IR receiver và remote ngay bây giờ.

LẮP MẠCH

LẬP TRÌNH
Đoạn mã này dùng để đọc tín hiệu từ remote. Các bạn vào link sau để tải thư viện hỗ trợ IR remote nhé:  www.giaiphaptt.vn
Sau khi tải thư viện về, bạn mở cửa sổ Arduino, chọn Sketch--->Import Library...---> Add Library....sau đó chọn file .zip mà bạn vừa tải về để có thể sử dụng thư viện.
#include <IRremote.h> // thư viện hỗ trợ IR remote

const int receiverPin = 8; // chân digital 8 dùng để đọc tín hiệu
IRrecv irrecv(receiverPin); // tạo đối tượng IRrecv mới
decode_results results;// lưu giữ kết quả giải mã tín hiệu
void setup()
{
  Serial.begin(9600);// serial baudrate 9600
  irrecv.enableIRIn(); // start the IR receiver
}
void loop()
{
  if (irrecv.decode(&results)) // nếu nhận được tín hiệu
  {
    Serial.println(results.value, HEX); // in ra Serial Monitor
    delay(200);
    irrecv.resume(); // nhận giá trị tiếp theo
  }
}
Sau khi upload đoạn code trên, các bạn mở cửa sổ Serial và bấm các nút của remote, tùy loại remote sẽ có giá trị trả về khác nhau, remote Sony của mình sẽ như thế này:
Đây là các giá trị HEX của tín hiệu được gửi từ remote, thử tất cả các nút của remote các bạn sẽ biết được IR codes của nó. Chẳng hạn như của mình, nút 1 là 0x10, nút 2 là 0x810, nút Power là 0xA90, nút Mute là 0x290,.....
Tiếp theo, chúng ta sẽ sử dụng remote để bật tắt LED.
#include <IRremote.h> // thư viện hỗ trợ IR remote

const int receiverPin = 8; // chân digital 8 dùng để đọc tín hiệu
IRrecv irrecv(receiverPin); // tạo đối tượng IRrecv mới
decode_results results;// lưu giữ kết quả giải mã tín hiệu

const int RED = 7;// LED đỏ
const int YELLOW = 6;// LED vàng
const int GREEN = 5;// LED xanh
/* trạng thái của các LEDs*/
boolean stateRED = false;
boolean stateYELLOW = false;
boolean stateGREEN = false;
void setup()
{
  Serial.begin(9600);// serial 
  irrecv.enableIRIn(); // start the IR receiver
  pinMode(RED, OUTPUT);
  pinMode(YELLOW, OUTPUT);
  pinMode(GREEN, OUTPUT);
}
// translate IR signals
void translateIR()
{
  switch(results.value)
  {
    case 0x10:  stateRED = !stateRED; 
                digitalWrite(RED, stateRED); 
                break;
    case 0x810: stateYELLOW = !stateYELLOW; 
                digitalWrite(YELLOW, stateYELLOW); 
                break;
    case 0x410: stateGREEN = !stateGREEN; 
                digitalWrite(GREEN, stateGREEN);  
                break;
    case 0xA90: stateRED = stateYELLOW = stateGREEN = false;
                digitalWrite(RED, 0);
                digitalWrite(YELLOW, 0);
                digitalWrite(GREEN, 0);
  }
}
void loop()
{
  if (irrecv.decode(&results)) // nếu nhận được tín hiệu
  {
    translateIR();
    Serial.println(results.value, HEX);
    delay(200);
    irrecv.resume(); // nhận giá trị tiếp theo
  }
}

GIẢI THÍCH

  • Với đoạn mã trên, khi nhấn các nút 1, 2, 3 trên remote, các LED đỏ, vàng, xanh sẽ lần lượt on-off, khi nhấn nút Power thì toàn bộ LEDs sẽ tắt.
  • Các keywords của thư viện như: 
    • IRrecv irrecv(receiverPin);: tạo đối tượng IRrecv mới có tên là irrecv sử dụng tham số là receiverPin. 
    • decode_results results; : lưu kết quả giải mã được
    • irrecv.enableIRIn(); : bắt đầu giải mã tín hiệu IR
    • irrecv.decode(&results);: trả về true nếu có tín hiệu đến
    • irrecv.resume; : đợi tín hiệu IR tiếp theo. 
Kết hợp IR remote với điều khiển động cơ DC bằng transistor, các bạn có thể tự chế cho mình 1 cái quạt mini thật cool đó!^^

Còn bây giờ, mình sẽ hướng dẫn các bạn cách sử dụng Arduino như 1 chiếc remote TV.

Đầu tiên, các bạn hãy lấy chiếc remote TV nhà mình và sử dụng đoạn code ở trên để biết được IR codes của nó.

LẮP MẠCH

LẬP TRÌNH

#include <IRremote.h>
IRsend irsend;// gửi tín hiệu hồng hoại
const int CH1 = 7;// nút số 1
const int CH2 = 8;// nút số 2
const int CH3 = 9;// nút số 3
const int POWER = 10;// nút Power
void setup()
{
  Serial.begin(9600);
  /* điện trở nội kéo lên cho tất cả nút bấm*/
  pinMode(CH1, INPUT_PULLUP);
  pinMode(CH2, INPUT_PULLUP);
  pinMode(CH3, INPUT_PULLUP);
  pinMode(POWER, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(CH1) == 0)// khi nút RED được nhấn
    irsend.sendSony(0x10, 12);// gửi tín hiệu HEX 0x10, 12 bits
  else if (digitalRead(CH2) == 0)// khi nút YELLOW được nhấn
    irsend.sendSony(0x810, 12);// gửi tín hiệu HEX 0x810, 12 bits
  else if (digitalRead(CH3) == 0)// khi nút GREEN được nhấn
    irsend.sendSony(0x410, 12);// gửi tín hiệu HEX 0x410, 12 bits
  else if (digitalRead(POWER) == 0)// khi nút POWER được nhấn
    irsend.sendSony(0xA90, 12);// gửi tín hiệu HEX 0xA90, 12 bits
  delay(50);
}

GIẢI THÍCH

  • Mặc định, IRsend sử dụng pin 3 PWM để phát tín hiệu, chúng ta không thể sử dụng pin khác thay cho pin 3 vì thư viện đã quy định như thế.
  • Hàm sendSony() sẽ gửi tín hiệu dạng HEX có độ dài 12 bits thông qua IR LED.
  • Bộ thu IR trong TV của bạn sẽ nhận và giải mã tín hiệu IR được phát từ IR LED.
==> mạch của bạn lúc này có chức năng tương đương với cái remote ( nếu bạn làm đầy đủ nút như remote thật). Và đặc biệt là bạn sẽ không còn ngán ai dám giành remote TV của bạn khi đang cày cuốc phim Hàn Quốc.

LỜI KẾT

Cảm ơn các bạn đã đọc bài viết của mình. Mọi sai sót hay thắc mắc các bạn cứ comment nhé!
Chúc các bạn thành công và vui vẻ với project!
Comment:
   Mình cũng ms bị lỗi này..Các bạn phải xóa file của thư viện tải về : libraries\RobotIRremote\IRremoteTools.cpp và libraries\RobotIRremote\IRremoteTools.h 
Dùng được luôn ^^
         Máy mình cũng bị như vậy và mình đã làm theo lời bạn xóa 2 files này. Sau đó chạy ok.
  PS: 2 files này xóa trong đường dẫn C:\Program Files (x86)\ Arduino\ libraries\ RobotIRremote
Thanks

        Cho mình hỏi khi điều khiển trên 10 led, nghĩa là khi bấm remote phải bấm 2 nút, vd led 14 = nút 1 + nút 4 thì phần code phải viết như thế nào ?
      if ((digitalRead(CH1) == 0) && (digitalRead(CH2) == 0)) { blah blah blah }
     Đại loại thế. Nhớ delay trong code vì trên thực tế, bạn sẽ bấm 1 trong 2 nút trước nút còn lại.
        Bạn cứ gửi như bình thường. Ở module nhận, bạn tạo một mảng đệm buffer. Cứ một nút ms đc gửi đến thì thêm nó vào cúi buffer. Sau một giây hoặc vài trăm milli giây (tùy bạn) kể từ lần nhận cuối cùng, thì bạn đọc buffer và xuất ra led. HOW?

const unsigned int MAX_BUFFER = 4; //Giới hạn số nút, ví dụ là 4 nút tối đa
const unsigned int MAX_DELAY_TIME = 600; // chờ tối đa 600ms
long buffer[MAX_BUFFER]; // Mảng tạm
unsigned int buffer_n; // số lượng biến trong buffer
unsigned long milli = 0;
void loop() {
        if (irrecv.decode(&results)) // nếu nhận được tín hiệu
        {
                buffer[buffer_n++] = results.value;
                milli = millis();
        }
        if (n == MAX_BUFFER || ((n > 0) && (millis() - milli >= MAX_DELAY_TIME))) {
                //Bạn đọc giá trị rồi tính toán để xuất led thôi, cái này dựa vào bạn
                n = 0;//Nạp lại buffer
                buffer = {0};
               
        }
}

0 comments:

Post a Comment

 

Lập trình

-

Arduino Hải Phòng

,