Thứ Hai, Tháng Mười Một 30, 2020
Trang chủ DIY Node-Red MQTT với Raspberry Pi và WiFi Kit ESP8266 - Bài 3...

Node-Red MQTT với Raspberry Pi và WiFi Kit ESP8266 – Bài 3 Gửi Dữ Liệu Cảm Biến

Giới Thiệu

Trong bài trước mình đã hướng dẫn đóng ngắt bóng đèn 220V thông qua Module Relay. Trong bài viết này chúng ta sẽ học cách giám sát thông số môi trường trong nhà thông qua cảm biến. Mình sẽ sử dụng DHT11 để hướng dẫn vì đây là một cảm biến giá rẻ, thông dụng, có sẵn thư viện nên sẽ dễ dàng kết nối và lập trình

Chuẩn Bị

1. Phần cứng

2. Phần mềm

  • Raspberry Pi

Các bạn cần cài đặt server MQTT trên Raspberry. Nếu bạn chưa cài đặt bạn có thể tham khảo bài viết: Raspberry Pi giao tiếp với NodeMCU ESP8266 qua giao thức MQTT – Phần 1

  • 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

Lưu ý: Nếu bạn là người mới, hãy coi lại những bài trước để hiểu sơ lược về cách cài đặt cũng như source code vì mình sẽ bỏ qua những phần đã giải thích từ bài này và những bài sau nữa.

1. NodeMCU ESP8266 

  • Cài đặt thư viện DHT11
    • Các bạn tải thư viện DHT11 tại đây.
    • Cài đặt thư viện DHT11 vào Arduino

Node-Red MQTT với Raspberry Pi và WiFi Kit ESP8266 – Bài 3 Gửi Dữ Liệu Cảm Biến

  • Giải thích Source Code

Source Code

#include <DHT.h>
#define DHTPIN D0
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);


#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "Yournamewifi"; // Nhập tên WiFi 
const char* password = "Yourpasswifi"; // Nhập Mật khẩu WiFi 
const char* mqttServer = "IPAddressServer"; // Nhập địa chỉ của server MQTT
String clientId = "ClientESP8266";            // Client ID của mạch
const char* sensor_humi_topic = "Maker_sensor/humidity";      // Topic của Sensor đọc độ ẩm
const char* sensor_temp_topic = "Maker_sensor/temperature";      // Topic của Sensor đọc nhiet do
const char* sensor_topic = "Maker_sensor";      // Topic của Sensor

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

unsigned long last_time = 0;


void setup() {
  Serial.begin(115200);
  Serial.println("DHTxx test!");
  dht.begin();
  setup_wifi();
  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());
}

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();
}

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

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


  if (millis() - last_time > 1000)
  {
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (isnan(h) || isnan(t)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.println();
    static char temperatureTemp[7];
    dtostrf(t, 6, 2, temperatureTemp);
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    if (isTemp == false) {
      client.publish(sensor_temp_topic, temperatureTemp);
      isTemp = true;
    } else if (isTemp == true) {
      client.publish(sensor_humi_topic, humidityTemp);
      isTemp = false;
    }
    last_time = millis();
  }

}

Trong bài này chúng ta sẽ có vài lưu ý sau:

+ Tạo một topic sub, chia topic sub đó làm 2 để đọc nhiệt độ và đọc độ ẩm sau đó pub lên MQTT

const char* sensor_humi_topic = “Maker_sensor/humidity”; // Topic của Sensor đọc độ ẩm
const char* sensor_temp_topic = “Maker_sensor/temperature”; // Topic của Sensor đọc nhiet do
const char* sensor_topic = “Maker_sensor”; // Topic của Sensor

+ Khởi tạo cảm biến DHT11 trong setup()

dht.begin();

+ Đọc giá trị nhiệt độ 

float t = dht.readTemperature();

+ Đọc giá trị độ ẩm 

float h = dht.readHumidity();

+ Các bạn lưu ý phần này , vì giá trị nhiệt độ độ ẩm là kiểu dữ liệu float, mà khi pub dữ liệu lên yêu cầu là kiểu char. Các bạn sẽ cần chuyển đổi từ float qua char. Bạn có thể tham khảo cách sau:

static char temperatureTemp[7];
dtostrf(t, 6, 2, temperatureTemp);
static char humidityTemp[7];
dtostrf(h, 6, 2, humidityTemp);

+ Gửi dữ liệu lên topic nhiệt độ và độ ẩm:

client.publish(sensor_temp_topic, temperatureTemp);
client.publish(sensor_humi_topic, humidityTemp);

Tuy nhiên mình không pub một lúc cả hai cùng lúc, nên mình sẽ pub từng cái một lên, lần này pub nhiệt độ thì lần sau sẽ pub độ ẩm và ngược lại bẳng một biến kiểu boolean:
if (isTemp == false) {
client.publish(sensor_temp_topic, temperatureTemp);
isTemp = true;
} else if (isTemp == true) {
client.publish(sensor_humi_topic, humidityTemp);
isTemp = false; }

+ Cảm biến DHT khi đọc sẽ bị delay, liệu bạn có muốn chương trình của mình bị đứng lại trong 1 đến 2 giây không? Hãy thử hàm này nhé:
Đầu tiên bạn tạo một biến kiểu dữ liệu là unsigned long

unsigned long last_time = 0;

Ở trong vòng lặp loop các bạn chạy hàm sau:
if (millis() – last_time > 1000)
{
// Do some thing
last_time = millis();
}

Vậy đoạn chương trình trên chúng ta sẽ sử dụng để đọc cảm biến DHT cứ mỗi lần sau 1s mà không bị delay ( Trong chương trình mẫu DHT11 có delay)

Các bạn tiến hành nạp chương trình vào NodeMCU CP2102. Sau khi nạp mình sẽ tiến hành kết nối cảm biến nhiệt độ độ ẩm với NodeMCU như sau:

Kit RF Thu Phát Wifi ESP8266 NodeMCU Lua CP2102

Cảm Biến Độ Ẩm, Nhiệt Độ DHT11 Ra Chân

3.3V +
GND
D0  OUT

 

2. Node-Red Dashboard

Như đã nói ở phần trước, trong phần này mình sẽ hướng dẫn cách để Node-red Autostart tức là tự động chạy khi bạn khởi động hệ điều hành lên. Trước tiên các bạn truy cập vào board Raspberry Pi của bạn bật Terminal lên và gõ lệnh:

$ sudo systemctl enable nodered.service

Quá ư là easy, bây giờ bạn chỉ cần khởi động lại board RasPi của bạn bằng lệnh là xong

$ sudo reboot

OK vậy là từ giờ Node-red sẽ tự động khởi động cùng với OS. Các bạn sẽ không cần phải mở lên và gõ lệnh Node-red nữa. Chúng ta tiếp tục bài ngày hôm nay, các bạn mở trình duyệt web lên và truy cập vào trang cấu hình của node-red kéo ra mqtt-in
   + Topic humi : Maker_sensor/humiditiy
   + Topic temp : Maker_sensor/temperature

Trong Filter nodes dash board các bạn kéo ra “test” và cấu hình 

À quên trong phần “value formate” các bạn nhớ thêm “°C” cho nhiệt độ và “%” độ ẩm 

Kết quả đạt được như thế này

Chúng ta sẽ thêm Gauge cho sinh động.

Và kết quả của thêm Gauge, chúng ta có thêm 2 gauge hiển thị nhiệt độ độ ẩm

Phần này khá hay, node-red hỗ trợ sẵn cho các bạn biểu đồ chart hiển thị. Chúng ta cùng thử nào, hãy kéo ra chart từ filter nodes.

Và đây là kết quả cuối cùng. Chúng ta đã có một dashboard tuyệt đẹp hiển thị các thông số nhiệt độ và độ ẩm. Ngoài ra các bạn còn có thể theo dõi trên điện thoại

Tổng Kết

Vậy trong bài này chúng ta đã:
+ Tìm hiểu về text,gauge,chart
+ Đọc cảm biến DHT11 trên NodeMCU Cp2102
+ Hiển thị giao diện lên máy tính, điện thoại

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

1 BÌNH LUẬN

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Lê Khoa
Lê Khoa
07/06/2020 7:26 chiều

anh có cách nào chuyển kiểu double qua char không ạ

Most Popular

Hướng dẫn lắp ráp Khung Xe Robot Chasiss Black Cat Mecanum (P2)

Giới thiệu Chào các bạn, trong bài này mình sẽ hướng dẫn cách hàn dây motor, và cách đấu dây motor với driver cho đúng. Sỡ...

Hướng dẫn lắp ráp Khung Xe Robot Chasiss Black Cat Mecanum (P1)

Giới thiệu Chào các bạn, trong bài viết này mình sẽ giải thích sơ qua về bánh xe Mecanum, cũng như nguyên lý hoạt động...

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...

Recent Comments

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