[Node-RED] Giao tiếp Server Node-RED với ESP8266 qua giao thức WebSocket

 

[Node-RED] Giao tiếp Server Node-RED với ESP8266 qua giao thức WebSocket


WebSocket là gì?


WebSocket là giao thức hỗ trợ giao tiếp hai chiều giữa client và server để tạo một kết nối trao đổi dữ liệu. Giao thức này không sử dụng HTTP mà thực hiện nó qua TCP. Mặc dù được thiết kế để chuyên sử dụng cho các ứng dụng web, lập trình viên vẫn có thể đưa chúng vào bất kì loại ứng dụng nào.

Ưu điểm

WebSocket cung cấp giao thức giao tiếp hai chiều mạnh mẽ. No có độ trễ thấp và dễ xử lý lỗi. Websocket thường được sử dụng cho những trường hợp yêu cầu real time như chat, hiển thị biểu đồ hay thông tin chứng khoán.

Ví dụ

Trong ví dụ này tôi sẽ dùng WebSoket Server ở trên Node-RED và giao tiếp với Client là ESP8266 để nhận dữ liệu và điều khiển. Giá trị nhiệt độ và độ ẩm là giá trị Random được tạo ra từ ESP8266 và gửi lên Server để hiển thị qua 2 Gauge Temp và Humi. Giao diện Server có 2 Button ON và OFF để điều khiển LED trên Kit ESP8266 (GPIO16).

Giao diện Server

[Node-RED] Giao tiếp Server Node-RED với ESP8266 qua giao thức WebSocket

Code Node-RED

/////////////////////////////////////////////////////////////////////////////
[
    {
        "id": "d5866d1207aa5d2f",
        "type": "websocket in",
        "z": "52f19c9632713971",
        "name": "",
        "server": "82bc284bb7df614c",
        "client": "",
        "x": 170,
        "y": 60,
        "wires": [
            [
                "f43a1c208d9e6608"
            ]
        ]
    },
    {
        "id": "66ec49514697d937",
        "type": "websocket out",
        "z": "52f19c9632713971",
        "name": "",
        "server": "82bc284bb7df614c",
        "client": "",
        "x": 400,
        "y": 260,
        "wires": []
    },
    {
        "id": "c096bf28eafdda70",
        "type": "debug",
        "z": "52f19c9632713971",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 570,
        "y": 60,
        "wires": []
    },
    {
        "id": "b3a684e0e8c6eb66",
        "type": "ui_gauge",
        "z": "52f19c9632713971",
        "name": "",
        "group": "fa8e8e5adeacfe66",
        "order": 0,
        "width": "6",
        "height": "6",
        "gtype": "gage",
        "title": "Temp",
        "label": "units",
        "format": "{{value}}",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 590,
        "y": 120,
        "wires": []
    },
    {
        "id": "bdd96f77a7d11e2d",
        "type": "ui_gauge",
        "z": "52f19c9632713971",
        "name": "",
        "group": "fa8e8e5adeacfe66",
        "order": 1,
        "width": "6",
        "height": "6",
        "gtype": "gage",
        "title": "Humi",
        "label": "units",
        "format": "{{value}}",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 590,
        "y": 160,
        "wires": []
    },
    {
        "id": "0889c40a785b05d9",
        "type": "function",
        "z": "52f19c9632713971",
        "name": "",
        "func": "var temp = msg.payload.temp;\nmsg.payload = temp;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 120,
        "wires": [
            [
                "b3a684e0e8c6eb66"
            ]
        ]
    },
    {
        "id": "f43a1c208d9e6608",
        "type": "json",
        "z": "52f19c9632713971",
        "name": "",
        "property": "payload",
        "action": "obj",
        "pretty": false,
        "x": 310,
        "y": 60,
        "wires": [
            [
                "0889c40a785b05d9",
                "6c654ec544fd11d0",
                "c096bf28eafdda70"
            ]
        ]
    },
    {
        "id": "6c654ec544fd11d0",
        "type": "function",
        "z": "52f19c9632713971",
        "name": "",
        "func": "var temp = msg.payload.humi;\nmsg.payload = temp;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 160,
        "wires": [
            [
                "bdd96f77a7d11e2d"
            ]
        ]
    },
    {
        "id": "78e0d83515d87525",
        "type": "ui_button",
        "z": "52f19c9632713971",
        "name": "",
        "group": "fa8e8e5adeacfe66",
        "order": 2,
        "width": "12",
        "height": "1",
        "passthru": false,
        "label": "ON",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "0",
        "payloadType": "num",
        "topic": "topic",
        "topicType": "msg",
        "x": 190,
        "y": 260,
        "wires": [
            [
                "66ec49514697d937"
            ]
        ]
    },
    {
        "id": "5f7a38f9e040dd42",
        "type": "ui_button",
        "z": "52f19c9632713971",
        "name": "",
        "group": "fa8e8e5adeacfe66",
        "order": 2,
        "width": "12",
        "height": "1",
        "passthru": false,
        "label": "OFF",
        "tooltip": "",
        "color": "",
        "bgcolor": "red",
        "className": "",
        "icon": "",
        "payload": "1",
        "payloadType": "num",
        "topic": "topic",
        "topicType": "msg",
        "x": 190,
        "y": 300,
        "wires": [
            [
                "66ec49514697d937"
            ]
        ]
    },
    {
        "id": "82bc284bb7df614c",
        "type": "websocket-listener",
        "path": "/esp8266",
        "wholemsg": "false"
    },
    {
        "id": "fa8e8e5adeacfe66",
        "type": "ui_group",
        "name": "Trang chủ",
        "tab": "5a46c0bda4183baf",
        "order": 1,
        "disp": true,
        "width": "12",
        "collapse": false,
        "className": ""
    },
    {
        "id": "5a46c0bda4183baf",
        "type": "ui_tab",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]
/////////////////////////////////////////////////////////////////////////////

Code ESP8266

/////////////////////////////////////////////////////////////////////////////
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <Hash.h>

#define LED 16

WebSocketsClient webSocket;

const char *ssid = "Phong 3";
const char *password = "0392071213";
const char *websocket_server = "192.168.1.20";
const int websocket_port = 1880;
const char *url = "/esp8266";

unsigned long last_time = 0;

void webSocketEvent(WStype_t type, uint8_t *payload, size_t length)
{

switch (type)
{
case WStype_DISCONNECTED:
Serial.printf("[WSc] Disconnected!\n");
break;
case WStype_CONNECTED:
{
Serial.printf("[WSc] Connected to url: %s\n", payload);
webSocket.sendTXT("Connected");
}
break;
case WStype_TEXT:
String message = "";
for (size_t i = 0; i < length; i++)
{
message += (char)payload[i];
}

if (message == "1")
{
digitalWrite(LED, HIGH);
}

if (message == "0")
{
digitalWrite(LED, LOW);
}

break;
}
}

void sendToServer()
{
if (millis() - last_time > 1000)
{
last_time = millis();
if (webSocket.isConnected())
{
int temp = random(50, 100);
int humi = random(80, 100);
String payload = "{\"temp\":";
payload += temp;
payload += ",\"humi\":";
payload += humi;
payload += "}";
webSocket.sendTXT(payload.c_str());
}
}
}

void setup()
{
Serial.begin(9600);
pinMode(LED, OUTPUT);

Serial.print("Connecting to Wifi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.print(".");
}
Serial.println("Connected to Wifi");
Serial.print("IP: ");
Serial.println(WiFi.localIP());

// server address, port and URL
webSocket.begin(websocket_server, websocket_port, url);

// event handler
webSocket.onEvent(webSocketEvent);

// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
}

void loop()
{
webSocket.loop();
sendToServer();
}
/////////////////////////////////////////////////////////////////////////////

Library WebSoket Arduino



Video hướng dẫn



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

No comments:

Post a Comment