Thứ Sáu, Tháng Chín 25, 2020
Trang chủ DIY Raspberry Pi giao tiếp với NodeMCU ESP8266 qua giao thức MQTT -...

Raspberry Pi giao tiếp với NodeMCU ESP8266 qua giao thức MQTT – Phần 1

Giới Thiệu

Đối với các bạn yêu thích RasPi(Raspberry Pi) và muốn xây dựng cho mình một hệ thống giám sát tại nhà là một ý tưởng rất hay! Tuy nhiên việc sử dụng RasPi(single board computer – microprocessor) để làm chức năng như một vi điều khiển(microcontroller) sẽ gây nguy hiểm cho RasPi bởi vì:

  • Mức logic của RasPi chỉ ở 3.3v , và không có thiết kế bảo vệ.
  • Dòng tối đa ở mỗi chân 16mA, tuy nhiên tổng dòng trên tất cả các chân xuất ra chỉ được dùng tới 50mA , nếu dùng hơn 50mA sẽ gây cháy mạch (dòng ~ 2 led đơn ). Tham khảo thêm tại trang chủ của hãng 
  • Các module hiện nay trên thị trường đa số chạy ở 5V và mức logic cũng thường là 5V.
  • Việc dùng một board microprocessor để chạy chức năng của microcontroller thì sẽ rất phí phạm.

Ví dụ: 

  • Bạn muốn làm một bóng đèn tự động bật tắt khi trời tối , hoặc tự động sáng khi có người đi lại…. bạn hãy chọn microcontroller (Arduino, ESP8266….) 
  • Bạn muốn theo dõi căn nhà của mình và thông báo khi có người tới , hẹn tắt giờ từ xa, kiểm tra các thông tin thời tiết , hệ thống tưới tiêu, làm một server tại gia …. bạn hãy chọn microprocessor(RasPi)

Vậy trong trường hợp bạn vừa muốn điều khiển vừa muốn theo dõi và kiểm soát từ xa chúng ta sẽ kết hợp hai ví dụ trên thành một hệ thống với Server là RasPi(microprocessor) và Client là NodeMCU ESP8266 (microcontroller). Ở đây mình dùng NodeMCU ESP8266 vì nó có thiết kế kết nối được với WiFi

Ngoài lề xíu : Dù sao dùng con RasPi làm server vẫn cảm thấy an toàn hơn vì phần điều khiển mình sử dụng NodeMCU ESP8266. Giả sử mình có lỡ tay đấu nhầm dây bóng đèn 220V vào nguồn 5V hay chạm chập gì đó thì cùng lắm đi đời con NodeMCU ESP8266 có đâu đó tầm 100k còn đỡ hơn là đi toi hơn triệu bạc 😛 😛 😛

  • MQTT là gì ?

MQTT = Message Queue Telemetry Transport là một giao thức được tạo ra với mục tiêu thu thập dữ liệu từ nhiều thiết bị khác nhau. Ưu điểm của nó là rất nhẹ , độ tin cậy cao cho các công việc giám sát từ xa phù hợp với những nơi băng thông mạng bị hạn chế.

  • MQTT làm việc thế nào ?

MQTT là một giao thức publish(xuất bản)/subcribe(theo dõi) cho phép các thiết bị publish dữ liệu lên một broker(có thể xem broker như một trung tâm , một bộ não). Mỗi thiết bị có thể subcrise,register theo các topic(chủ đề). Khi một thiết bị pub(publish) một dữ liệu về một topic đã đăng kí thì broker sẽ chuyển tiếp dữ liệu đó đến những thiết bị sub(subcribe) theo dõi topic đó.

Ở bài viết này mình chỉ nói sơ lược qua về MQTT, nếu các bạn muốn tìm hiểu rõ hơn có thể tìm hiểu thêm về MQTT trên Google.

Trong dự án này mình sẽ chia làm 3 phần 

  1. Tạo máy chủ MQTT trên Raspberry Pi – Cài đặt thư viện
  2. Cài đặt thư viện MQTT trên Arduino IDE để sử dụng với MQTT
  3. Gửi dữ liệu thời gian từ NodeMCU lên Server MQTT và đọc dữ liệu trên Terminal RasPi

Vậy chúng ta sẽ có một Server là RasPi và một clients là NodeMCU ESP8266

Chuẩn bị

1. Phần cứng

  • Kit RF Thu Phát Wifi ESP8266 NodeMCU Lua CP2102
  • Một board Raspberry Pi ( ở đây mình sử dụng Raspberry Pi 3 Model B) bạn có thể tham khảo mua tại đây . Bạn nên mua đủ nguồn , thẻ nhớ – ít nhất 16GB và vỏ case để bảo vệ tốt cho board RasPi của bạn!

2. Phần mềm

  • Raspberry Pi

Các bạn cần cài đặt hệ điều hành cho Raspberry Pi , ở đây mình sử dụng Raspbian.

  • Arduino IDE

Các bạn cần cài đặt sẵn Arduino IDE có tương thích với ESP8266. Nếu bạn chưa biết cách cài đặt có thể tham khảo bài viết sau: Hướng dẫn lập trình ESP8266 với Arduino IDE.

Hướng dẫn

1. Mosquitto MQTT RasPi

Đầu tiên các bạn cần update để tránh trường hợp cài đặt bị lỗi , quá trình này có thể kéo dài từ 5 – 30′ tùy thuộc vào tình trạng mạng và phiên bản hệ điều hành bạn đang sử dụng . Các bạn chạy theo thứ tự những lệnh sau:

sudo apt-get update
sudo apt-get upgrade
sudo reboot

Sau khi khởi động lại máy chúng ta cài đặt Mosquitto server

sudo apt install -y mosquitto mosquitto-clients 

Chạy lệnh để mosquitto mqtt  AutoRun khi khởi động

sudo systemctl enable mosquitto.service 

Vậy là xong , bây giờ chúng ta sẽ dùng command để check services 

systemctl status mosquitto.service

Đầu tiên tạo một sub với topic là “Makerlab”

mosquitto_sub -h localhost -t “Makerlab”

Raspberry Pi Nói chuyện với NodeMCU ESP8266 qua phiên dịch viên MQTT

Sau đó chúng ta sẽ thử pub message lên topic vừa tạo bằng cách mở một cửa sổ Terminal mới và nhập command

mosquitto_pub -h localhost -t “Makerlab” -m “Makerlab xin chao”

Raspberry Pi Nói chuyện với NodeMCU ESP8266 qua phiên dịch viên MQTT

Bạn sẽ thấy cửa sổ bên trái (sub) nhận được message “Makerlab xin chao“.Bạn cứ giữ nguyên của sổ để test đọc dữ liệu từ NodeMCU gửi lên ở phần sau…

Ngoài ra vì hiện tại RasPi của bạn đang chạy ở IP động(IP không cố định). Nếu bạn muốn truy cập và điều khiển từ xa thì sẽ khó kiểm soát và gặp một vài rắc rối xung đột IP vì thế mình sẽ hướng dẫn thêm một xíu về phần cấu hình IP tĩnh:

sudo nano /etc/dhcpcd.conf

Và thêm các dòng sau vào cuối trang , thay XXX = IP bạn cần set
interface wlan0
static ip_address=192.168.1.XXX/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

Vậy về cơ bản là chúng ta đã setup xong phần Driver trên RasPi rồi. Mình sẽ chuyển qua cấu hình và code cho NodeMCU ESP8266

2. NodeMCU ESP8266 

Bạn phải chắc chắn mình đã cài đặt được tool board NodeMCU cho Arduino IDE trước. Nếu không bạn sẽ không thực hiện được các bước sau, link hướng dẫn cài đặt tool board mình để ở trên mục Chuẩn Bị

Vấn đề ở đây là chúng ta cần đẩy dữ liệu và đọc dữ liệu từ Server, vậy thì chúng ta sẽ cần một thư viện để thực hiện điều đó. Mình sử dụng PubSubClient library. Các bạn tải thư viện này bằng cách vào Sketch -> Include Library -> Manage Libraries hoặc nhấn Ctrl+Shift+I

Raspberry Pi Nói chuyện với NodeMCU ESP8266 qua phiên dịch viên MQTT (2)
Các bạn tìm thư viện PubSubClient của Nick O’Leary và cài đặt.

Raspberry Pi Nói chuyện với NodeMCU ESP8266 qua phiên dịch viên MQTT (2)

Bây giờ chúng ta sẽ thử gửi thời gian lên Server thông qua topic “Makerlab” đã tạo ở trên

Source Code

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "NhaptenWiFi";                // Nhập tên WiFi
const char* password =  "Nhapmatkhau";           // Nhập Mật khẩu WiFi
const char* mqttServer = "IPADDRESS";            // Nhập địa chỉ của server MQTT
unsigned long b_time;
String clientId = "ClientESP8266";              // Client ID của mạch
const char* m_topic = "Makerlab";               // Topic mình đã tạo ở trên

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
  Serial.begin(115200);
  setup_wifi();
  /* Hàm start - read Callback client */
  client.setServer(mqttServer, 1883);     
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

/* Ham call back nhan lai du lieu */
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message read [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  xulidulieu(payload);

}
void xulidulieu(byte* data)
{
  /* Xử lí dữ liệu đọc về tại đây */
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      client.publish(m_topic, "Reconnect");               // Gửi dữ liệu
      client.subscribe(m_topic);                          // Theo dõi dữ liệu
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      // Doi 1s
      delay(1000);
    }
  }
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  /* Mỗi 1s gửi dữ liệu thời gian lên topic server*/
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    snprintf (msg, 50, "Makerlab Millis: %ld s", lastMsg/1000);
    Serial.print("Message send: ");
    Serial.println(msg);
    client.publish(m_topic, msg);
  }
}

Các bạn cần thay đổi các thông số sau:

const char* ssid = “NhaptenWiFi”; // Nhập tên WiFi
const char* password = “Nhapmatkhau”; // Nhập Mật khẩu WiFi
const char* mqttServer = “IPADDRESS”; // Nhập địa chỉ của server MQTT

Một số hàm quan trọng:

+ Khởi tạo client Server

client.setServer(mqttServer, 1883);
client.setCallback(callback); 

+ Call back nhận dữ liệu topic khi có thay đổi

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message read [“);
Serial.print(topic);
Serial.print(“] “);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
xulidulieu(payload);
}

+ Reconnect khi khởi chạy và kết nối lại , bạn sẽ subcribes các topic trong hàm này. Ví dụ subcribes topic: “Makerlab” để đọc lại dữ liệu gửi lên

void reconnect() {
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
if (client.connect(clientId.c_str())) {
Serial.println(“connected”);
client.publish(m_topic, “Reconnect”); // Gửi dữ liệu
client.subscribe(m_topic); // Theo dõi dữ liệu
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
// Doi 1s
delay(1000);
}
}

+ Gửi dữ liệu thời gian với khoảng cách 1s lên server

long now = millis();
if (now – lastMsg > 1000) {
lastMsg = now;
snprintf (msg, 50, “Makerlab Millis: %ld s”, lastMsg/1000);
Serial.print(“Message send: “);
Serial.println(msg);
client.publish(m_topic, msg);
}

Mình đã sơ lược qua về phần code , bây giờ chúng ta sẽ tiến hành nạp chương trình vào NodeMCU CP2102. Các bạn nhớ chọn tool board là NodeMCU 1.0 (ESP-12E)Raspberry Pi Nói chuyện với NodeMCU ESP8266 qua phiên dịch viên MQTT

Nếu nạp thành công kết quả sẽ như thế này:

Tổng Kết

Vậy trong bài này chúng ta đã:
+ Cài đặt xong MQTT Mosquitto trên Raspberry Pi 
+ Cài đặt PubSubClient trên Arduino IDE 
+ Gửi và đọc dữ liệu trên Raspberry Pi ( qua Terminal )
+ Gửi và đọc dữ liệu trên Server thông qua NodeMCU CP2102

Ở bài viết tới mình sẽ hướng dẫn các bạn cách điều khiển đèn led trên NodeMCU bằng Terminal của Raspberry Pi!

Chúc các bạn thành công với dự án của mình !

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Most Popular

Hướng dẫn sử dụng Mạch đóng ngắt tải không tiếp xúc chế tạo Thiết bị vệ sinh tự động

Từ ngày 03/08/2020 mạch chuyển sang phiên bản mới tuy nhiên kích thước, vị trí linh kiện và chức năng của mạch giống và...

Lưu trữ nhật ký dữ liệu Online với ESP32 và Google Spreadsheets

Giới Thiệu Chào các bạn, trong các dự án IoT nhỏ gọn thì việc lưu trữ  và kiểm soát dữ liệu trên đám mây cũng...

Đọc Cảm Biến DHT11/DHT21/DHT22 không bị DELAY chương trình

Giới Thiệu Chào các bạn, hôm nay mình giới thiệu và hướng dẫn cách đọc cảm biến các dòng DHT11/DHT21/DHT22 ở bài này mình sử...

Gỡ lỗi ESP8266/ESP32 với thư viện ArduinoTrace

Giới Thiệu Chào các bạn, thông thường khi các bạn debug chương trình các bạn thường sử dùng hàm Serial.print() tuy nhiên, hôm nay mình sẽ...

Recent Comments

0
Would love your thoughts, please comment.x
()
x