Truyền tín hiệu với module radio frequence 433Mhz

Xin chào các bạn, bài viết hôm nay của mình sẽ giới thiệu về cách truyền dữ liệu không dây bằng modules RF (radio frequence) 433Mhz.

PHẦN CỨNG

  1. Board Arduino x2 ( mình sử dụng Arduino UNO R3 và Arduino Leonardo).
  2. Module RF 433 Mhz ( gồm 1 transmitter module và 1 receiver module) hoặc 315MHz.
  3. Breadboard x2.
  4. LED xanh, vàng, đỏ.
  5. Điện trở (220 - 560 ôm)
  6. pin 9V x2.
  7. Dây dẫn.

GIỚI THIỆU

MODULE RF 433Mhz: đây là 1 module giá rẻ, dùng sóng radio để truyền tín hiệu giữa bộ phát (transmitter module) và bộ thu (receiver module). 

Mẹo: Để tăng hiệu quả và khoảng cách khi sử dụng module RF, các bạn có thể chế 2 cái ăngten bằng dây đồng cuốn thành lò xo rồi gắn vào ăngten của transmitter và receiver.

như module của mình:

 

- Transmitter module: là cái module nhỏ hơn đó, gồm 3 chân: từ trái qua phải: DATA (hoặc ATAD), VCC, GND. 

Transmitter module Arduino
DATA digital Pin
VCC 5V
GND GND

 

- Receiver module: là cái to hơn, gồm 4 chân: từ trái qua phải: GND, DATA, DATA, VCC. (chúng ta chỉ dùng 1 trong 2 chân DATA này)

Transmitter module Arduino
DATA digital Pin
VCC 5V
GND GND

Để hiểu rõ hơn về sóng radio, các bạn có thể tham khảo tại bài viết sau: http://arduino.vn/bai-viet/277-song-vo-tuyen-la-gi-va-nhung-suc-manh-cua-no-khi-ket-hop-voi-arduino

Chúng ta sẽ tìm hiểu cách truyền dữ liệu với RF module ngay bây giờ.

LẮP MẠCH

Trong Transmitter module, mình sử dụng pin 8 để phát tín hiệu.

Trong Receiver module, mình cũng sử dụng pin 8 để để nhận tín hiệu.

LẬP TRÌNH

Để sử dụng RF module 1 cách dễ dàng hơn, chúng ta sẽ download thư viện VirtualWire tại link sau: http://www.airspayce.com/mikem/arduino/VirtualWire/VirtualWire-1.27.zip

Sau đó, các bạn mở Arduino IDE, chọn Sketch/ Import Library.../ Add Library...  và chọn vào file .zip vừa tải về để cài đặt thư viện.

Ở Transmitter module, mình sẽ nhận dữ liệu từ cổng Serial, sau đó gửi sang Receiver module.

Transmitter:

#include <VirtualWire.h> // khai báo thư viện VirtualWire

void setup()
{
  Serial.begin(9600);// giao tiếp Serial với baudrate 9600
  Serial.println("Ready.........");
  vw_set_ptt_inverted(true);// yêu cầu cho RF link modules
  vw_setup(1024);// cài đặt tốc độ truyền tín hiệu
  vw_set_tx_pin(8);// cài đặt chân digital để phát tín hiệu
}

void loop()
{
  char text[20] = "";// khai báo string dạng array
  byte i = 0;
  while (Serial.available() == 0)
  {
    // nothing
  }
  while (Serial.available() > 0)
  {
    char ch = Serial.read();
    text[i] = ch;
    i++;
    delay(5);
  }
  Serial.print("sent: ");
  Serial.println(text);
  vw_send((byte *)text, sizeof(text));// gửi tín hiệu đi
  vw_wait_tx();
  delay(100);
}

Receiver:

#include <VirtualWire.h> // khai báo thư viện VirtualWire

byte msg[VW_MAX_MESSAGE_LEN];// biến lưu dữ liệu nhận được
byte msgLen = VW_MAX_MESSAGE_LEN;

void setup()
{
  Serial.begin(9600);
  Serial.println("READY..........");
  vw_setup(1024); // cài đặt tốc độ truyền tín hiệu
  vw_set_rx_pin(8);// cài đặt chân digital để nhận tín hiệu
  vw_rx_start();// bắt đầu nhận tín hiệu
}

void loop()
{
  if (vw_get_message(msg, &msgLen)) // nếu có tín hiệu được truyền đến
  {
    Serial.print("got: ");
    for (int i = 0; i < msgLen; i++)
    {
      Serial.write(msg[i]);// in ký tự ra màn hình
    }
    Serial.println();
  }
}

Chú ý: Khi upload 2 đoạn code trên lên 2 boards Arduino, các bạn cần bật 2 cửa sổ Arduino IDE riêng biệt (tức là phải 2 lần double click vào biểu tượng Arduino IDE), vì mỗi board sẽ có 1 cổng COM riêng, nên các bạn chú ý vào Tools / Serial Port... để chọn đúng cổng COM cho board.

Sau khi upload code lên 2 boards Arduino, các bạn mở 2 cửa sổ Serial của 2 boards, rồi nhập vài ký tự vào cửa sổ Serial của Transmitter, KQ sẽ tương tự thế này:

GIẢI THÍCH

- Transmitter sẽ nhận dữ liệu từ Bàn phím qua cổng Serial, sau đó Transmitter sẽ gửi dữ liệu này đến Receiver bằng sóng radio, khi Receiver nhận được tín hiệu, nó sẽ giải mã và in ra cửa sổ Serial. 

- Theo mặc định, thư viện VirtualWire chọn pin 12 để phát tín hiệu, pin 11 để nhận tín hiệu. Các bạn có thể tùy chọn 1 chân digital bất kỳ để gửi và nhận tín hiệu với dòng lệnh: vw_set_tx_pin(pin) đối với transmitter và vw_set_rx_pin(pin) đối với Receiver.

- Các keywords:

  • vw_set_ptt_inverted(true): cần phải có đối với RF link modules, có thể không cần thiết đối với các loại modules khác.
  • vw_setup(speed): thiết lập tốc độ truyền dữ liệu giữa Transmitter và Receiver, đơn vị: bits/s. Chú ý: tốc độ của Transmitter và Receiver phải bằng nhau.
  • vw_set_tx_pin(pin): thiết lập chân phát tín hiệu.
  • vw_set_rx_pin(pin): thiết lập chân nhận tín hiệu.
  • vw_rx_start(): bắt đầu nhận tín hiệu.
  • vw_send((byte *)data, sizeof(data)): hàm gửi tín hiệu đi, gồm 2 tham số là:
  1. (byte *)data: biến con trỏ (byte *)data, trong đó: data là biến chứa dữ liệu cần được truyền đi, biến data cần được khai báo là biến mảng. Cụ thể ở ví dụ trên là biến text[20].
  2. sizeof(data): kích thước của dữ liệu được truyền đi, tính theo byte. Chú ý: nếu bạn khai báo string kiểu con trỏ, VD: const char *text = "hello"; lúc này bạn sẽ phải dùng strlen(text) thay vì sizeof(text).
  • vw_get_message(msg, &msgLen): hàm nhận tín hiệu, sẽ trả về giá trị true khi có tín hiệu được gửi tới, gồm 2 tham số là:
  1. msg: biến con trỏ msg, trong đó: msg là biến chứa dữ liệu vừa nhận được, biến msg cần được khai báo là biến mảng. Ở ví dụ trên là biến msg[VW_MAX_MASSAGE_LEN].
  2. &msgLen: địa chỉ của biến msgLen, biến msgLen chứ kích thước của dữ liệu nhận được.
  • vw_wait_tx(): đợi trước khi truyền tín hiệu tiếp theo.
  • VW_MAX_MASSAGE_LEN: thư viện VirtualWire đã define sẵn kích thước tối đa của dữ liệu là 30 bytes.

Bây giờ, mình sẽ sử dụng sóng radio để điều khiển các thiết bị điện tử. 

LẮP MẠCH 

Transmitter

Receiver

 

LẬP TRÌNH 

Mình sẽ gửi lệnh từ Transmitter đến Receiver để điều khiển bật/tắt các LED.

Lệnh sẽ có cú pháp: "number STATE"

VD: 1 ON ===> led đỏ sáng, 2 OFF ===> led xanh tắt, 3 ON ===> led vàng sáng, A ON ===> bật tất cả led, A OFF ===> tắt tất cả led,...

Transmitter (tương tự như ví dụ trên):

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);
  Serial.println("Ready.........");
  vw_set_ptt_inverted(true);
  vw_setup(1024);
  vw_set_tx_pin(8);
}

void loop()
{
  char text[20] = "";
  byte i = 0;
  while (Serial.available() == 0)
  {
    // nothing
  }
  while (Serial.available() > 0)
  {
    char ch = Serial.read();
    text[i] = ch;
    i++;
    delay(5);
  }
  Serial.print("sent: ");
  Serial.println(text);
  vw_send((byte *)text, sizeof(text));
  vw_wait_tx();
  delay(100);
  
}

Receiver:

#include <VirtualWire.h>

byte msg[VW_MAX_MESSAGE_LEN];
byte msgLen = VW_MAX_MESSAGE_LEN;
const int RED = 7; // led đỏ
const int GREEN = 6; // led xanh
const int YELLOW = 5; // led vàng
String text = ""; // biến String lưu dữ liệu 
void setup()
{
  Serial.begin(9600);
  Serial.println("READY..........");
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(YELLOW, OUTPUT);
  vw_setup(1024);
  vw_set_rx_pin(8);
  vw_rx_start();
}
/* select */
void select(byte number, byte name)
{ 
  // lệnh có dạng "number STATE", VD: 1 ON, 2 OFF, 3 ON...
  // i bắt đầu tại 2 để bỏ qua "number" và "khoang trang"
  // bắt đầu kiểm tra được "STATE" luôn
  for (int i = 2; i < msgLen; i++) 
  {
    text += char(msg[i]);
  }
  Serial.print("got: "); // in kết quả ra cửa sổ Serial
  Serial.print(number);
  Serial.print("-");
  Serial.println(text);
  /* nếu "STATE" = ON ==> bật, nếu "STATE" = OFF ==> tắt*/
  if (text == "ON")
  {
    digitalWrite(name, 1);
  }
  else if (text == "OFF")
  {
    digitalWrite(name, 0);
  }
}
/* select All*/
void selectAll()
{
  for (int i = 2; i < msgLen; i++)
  {
    text += char(msg[i]);
  }
  Serial.print("got: ALL");
  Serial.print("-");
  Serial.println(text);
  if (text == "ON")
  {
    digitalWrite(RED, 1);
    digitalWrite(GREEN, 1);
    digitalWrite(YELLOW, 1);
  }
  else if (text == "OFF")
  {
    digitalWrite(RED, 0);
    digitalWrite(GREEN, 0);
    digitalWrite(YELLOW, 0);
  }
}
void loop()
{
  
  if (vw_get_message(msg, &msgLen))
  {
    if (msg[0] == '1')
    {
      select(1, RED);
    }
    else if (msg[0] == '2')
    {
      select(2, GREEN);
    }
    else if (msg[0] == '3')
    {
      select(3, YELLOW); 
    }
    else if (msg[0] == 'A')
    {
      selectAll();
    }
  }
  text = ""; // reset biến text
}

Sau khi upload thành công và test thử, chúng ta sẽ có cửa sổ Serial như sau:

Đây là 1 số hình ảnh về project của mình

LỜI KẾT

Kết hợp với rơle, các bạn hoàn toàn có thể điều khiển từ xa các thiết bị điện trong gia đình thông qua máy vi tính. 

Chúc các bạn thành công!

Mọi thắc mắc và sai sót các bạn cứ comment nhé!^^

lên
16 thành viên đã đánh giá bài viết này hữu ích.
Hướng dẫn sử dụng các loại module

Nếu bạn đang muốn thực hiện hóa ý tưởng của mình mà không biết dùng loại module nào? Hãy tham khảo các module trong danh sách sau

Các dự án được truyền cảm hứng

Select any filter and click on Apply to see results

Các bài viết cùng tác giả

Debounce cho nút nhấn bằng tụ điện

Xin chào, bài đăng của mình sẽ nói về kỹ thuật DEBOUNCE cho nút bấm. Đây là kỹ thuật rất đơn giản và hiệu quả.

lên
12 thành viên đã đánh giá bài viết này hữu ích.

Bài 1: Điều chỉnh độ sáng của LED qua giao tiếp Serial

Xin chào, bài đăng của mình sẽ liên quan đến 2 chủ để mà admin đã đề cập đến, đó là: xung PWM và giao tiếp Serial.

lên
5 thành viên đã đánh giá bài viết này hữu ích.
Từ khóa: