ldmt gửi vào
- 12014 lượt xem
Chào các bạn ở bài trước mình đã hướng dẫn các bạn cách setup 1 MQTT-Broker trên Raspberry cũng như các gửi data từ iNut-Node-RED-IDE lên MQTT-Broker để xem nó hoạt động như thế nào. Hôm nay mình sẽ tiếp tục hướng dẫn các bạn sử dụng iNut cảm biến kết nối với MQTT-Local để xuất dữ liệu lên Node Red từ đó điều khiển bật tắt 1 đèn led đơn giản. Ok, bắt tay vào làm thôi.
I. Chuẩn bị.
- Raspberry-Pi (mình xài model 3B+)
- Setup sẵn như bài trước tại đây
- Máy tính cài sẵn iNut-Node-RED-IDE. Các bạn có thể xem tại đây luôn nha
- Nguồn ổn định cho raspbery-Pi
II. Bắt đầu setup.
Bước 1 Khởi động iNut-Node-RED-IDE
Các bạn mở Command Prompt ( phím Windows + R) nhâp “cmd”
Sau đó bạn nhập lệnh:
cd iNut-Node-RED-IDE (sau đó Enter và nhập tiếp lệnh bên dưới vào) npm start
Bước 2 Setup thông số cho các khối trên iNut-Node-RED-IDE:
Các bạn truy cập vào địa chỉ http://localhost:1880/
Sau đó các bạn thay đổi địa chỉ MQTT của ngõ vào [MQTT_IN]XXX (XXX là tên thiết bị iNut cảm biến của bạn; ở đây mình đã sửa thành khối lệnh có tên là IN_MQTT_Raspberry ) như sau:
Ở đây đang hiển thị địa chỉ mặc định của thiết bị kết nối tới MQTT của MySmartHome
Sau đó bạn click vào ô có hình màu đỏ như bên dưới để thay đổi cài đặt MQTT mặc định
Ở phần Server các bạn thay địa chỉ “mqtt.mysmarthome.vn” thành địa chỉ của Raspberry nhé
Các bạn có thể truy cập vào Terminal của Pi nhập “ip a” để xem địa chỉ IP hoặc thu nhỏ cửa sổ Remote Control nhìn góc trên bên trái sẽ có hiển thị địa chỉ của Pi.
Đây, mình đã sửa xong địa chỉ thành địa chỉ của Raspberry rồi
Sau đó bạn chọn sang Tab Security
Các bạn nhập Username và Password của MQTT-Broker mà các bạn đã tạo. Sau đó bạn nhớ bấm vào Update nhé
Tiếp theo các bạn sẽ Set Topic cho Raspberry như hình bên dưới này nhé.
Để tìm được địa chỉ Topic của thiết bị iNut cảm biến, bạn truy cập vào App iNut vào thiết bị của bạn kéo xuống tìm dòng chữ “Mã thiết bị” và nhập vào ô Topic nhé.
Lưu ý: Trong app iNut bạn vào mục "Thông số kỹ thuật" của thiết bị và điền vào các thông tin còn thiếu như hình phía bên dưới nha
Hoặc bạn có thể truy cập vào địa chir để có được giao diện như mình bên trên nha.
Tiếp theo bạn kéo 1 khối debug ra để debug kiểm tra khối lệnh IN_MQTT_Raspberry sau khi hiệu chỉnh các thông số nhé
Đầu tiên bạn bấm vào ô vuông màu xanh phía sau khối debug(số 1), tiếp theo bạn chọn sang Tab debug (số 2), cuối cùng là quan sát cửa sổ lệnh debug (số 3) chạy như thế nào nhé.
Sau khi debug xong các bạn kết nối các khối trên lại với nhau và chọn Deploy nha
Đây là code Node-Red nha :
[ { "id": "36cf6cf2.8b1414", "type": "subflow", "name": "Lấy dữ từ iNut", "info": "", "in": [ { "x": 50, "y": 30, "wires": [ { "id": "51957e77.05539" } ] } ], "out": [ { "x": 859.0000343322754, "y": 98.00000190734863, "wires": [ { "id": "5c0be9b8.8ca268", "port": 0 } ] }, { "x": 968.0000343322754, "y": 102.00000286102295, "wires": [ { "id": "5c0be9b8.8ca268", "port": 1 } ] }, { "x": 1048.9999732971191, "y": 101.00000381469727, "wires": [ { "id": "5c0be9b8.8ca268", "port": 2 } ] }, { "x": 1059, "y": 253, "wires": [ { "id": "5c0be9b8.8ca268", "port": 3 } ] }, { "x": 1102, "y": 318, "wires": [ { "id": "5c0be9b8.8ca268", "port": 4 } ] }, { "x": 1116, "y": 399, "wires": [ { "id": "5c0be9b8.8ca268", "port": 5 } ] }, { "x": 1108, "y": 444, "wires": [ { "id": "5c0be9b8.8ca268", "port": 6 } ] }, { "x": 1006, "y": 489, "wires": [ { "id": "5c0be9b8.8ca268", "port": 7 } ] } ], "inputLabels": [ "Nhận đầu vào MQTT IN từ iNut cảm biến" ], "outputLabels": [ "Luồng cảm biến 1", "Luồng cảm biến 2", "Luồng cảm biến 3", "Luồng cảm biến 4", "Luồng cảm biến 5", "Luồng cảm biến 6", "Luồng cảm biến 7", "Luồng cảm biến 8" ] }, { "id": "51957e77.05539", "type": "json", "z": "36cf6cf2.8b1414", "name": "", "property": "payload", "action": "str", "pretty": false, "x": 165, "y": 84, "wires": [ [ "f5e709f0.fd4ac8" ] ] }, { "id": "5c0be9b8.8ca268", "type": "switch", "z": "36cf6cf2.8b1414", "name": "Phân luồn", "property": "", "propertyType": "msg", "rules": [ { "t": "eq", "v": "0", "vt": "num" }, { "t": "eq", "v": "1", "vt": "str" }, { "t": "eq", "v": "2", "vt": "str" }, { "t": "eq", "v": "3", "vt": "str" }, { "t": "eq", "v": "4", "vt": "str" }, { "t": "eq", "v": "5", "vt": "str" }, { "t": "eq", "v": "6", "vt": "str" }, { "t": "eq", "v": "7", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 8, "x": 825.9869575500488, "y": 288.1562738418579, "wires": [ [], [], [], [], [], [], [], [] ] }, { "id": "f5e709f0.fd4ac8", "type": "function", "z": "36cf6cf2.8b1414", "name": "Lặp", "func": "if (!msg.states) {\n msg.states = msg.payload\n msg.i = 0\n return msg;\n} else {\n if (msg.states[msg.i])\n return msg;\n}\n", "outputs": 1, "noerr": 0, "x": 327.89060974121094, "y": 83.33600330352783, "wires": [ [ "171d797e.cc7e67" ] ] }, { "id": "171d797e.cc7e67", "type": "function", "z": "36cf6cf2.8b1414", "name": "Lấy trạng thái thiết bị", "func": "msg.relayId = msg.i\nreturn msg;", "outputs": 1, "noerr": 0, "x": 477.89060974121094, "y": 183.33600330352783, "wires": [ [ "f5e709f0.fd4ac8", "5c0be9b8.8ca268" ] ] }, { "id": "77252d23.ef9384", "type": "debug", "z": "160a8256.91137e", "name": "in ra màn hình để debug thông tin", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "x": 980, "y": 260, "wires": [] }, { "id": "7be55555.967bdc", "type": "function", "z": "160a8256.91137e", "name": "Chuẩn bị lệnh trước khi gửi đến iNut cảm biến", "func": "var json = {\"id\": 0, \"command\": msg.payload};\nmsg.payload = json;\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 620, "y": 220, "wires": [ [ "77252d23.ef9384", "bc0db1a4.dc6ce" ] ] }, { "id": "2a08fa4e.66ff86", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "8cc674a4.10e3f8", "order": 2, "width": "3", "height": "3", "gtype": "gage", "title": "Data 1", "label": "", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1170, "y": 440, "wires": [] }, { "id": "f1471541.63de28", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "8cc674a4.10e3f8", "order": 1, "width": "3", "height": "3", "gtype": "gage", "title": "Data 0", "label": "mưa", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1170, "y": 400, "wires": [] }, { "id": "5e3ed30b.84645c", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "8cc674a4.10e3f8", "order": 4, "width": "3", "height": "3", "gtype": "gage", "title": "Data 3", "label": "", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1169, "y": 522.8333129882812, "wires": [] }, { "id": "eda77085.d01b5", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "8cc674a4.10e3f8", "order": 3, "width": "3", "height": "3", "gtype": "gage", "title": "Data 2", "label": "mưa", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1168.09126663208, "y": 482.124960899353, "wires": [] }, { "id": "e2aa7aa2.845738", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "a532b78d.8303b8", "order": 2, "width": "3", "height": "3", "gtype": "gage", "title": "Data 5", "label": "", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1167, "y": 607.8333129882812, "wires": [] }, { "id": "88f2c510.769e58", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "a532b78d.8303b8", "order": 1, "width": "3", "height": "3", "gtype": "gage", "title": "Data 4", "label": "mưa", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1166.09126663208, "y": 567.124960899353, "wires": [] }, { "id": "312b32b7.b644ee", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "a532b78d.8303b8", "order": 4, "width": "3", "height": "3", "gtype": "gage", "title": "Data 7", "label": "", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1166, "y": 690.6666259765625, "wires": [] }, { "id": "4f03abee.64fdb4", "type": "ui_gauge", "z": "160a8256.91137e", "name": "", "group": "a532b78d.8303b8", "order": 3, "width": "3", "height": "3", "gtype": "gage", "title": "Data 6", "label": "mưa", "format": "{{value}}", "min": 0, "max": "10000", "colors": [ "#1f964f", "#e6e600", "#ca3838" ], "seg1": "", "seg2": "", "x": 1165.09126663208, "y": 649.9582738876343, "wires": [] }, { "id": "261ffcb1.4895d4", "type": "ui_text_input", "z": "160a8256.91137e", "name": "", "label": "Gửi lệnh xuống iNut cảm biến", "group": "8cc674a4.10e3f8", "order": 5, "width": "4", "height": "1", "passthru": true, "mode": "text", "delay": "0", "topic": "", "x": 270, "y": 220, "wires": [ [ "7be55555.967bdc", "ec9f4fc8.ffefc", "67b093c3.792bac" ] ] }, { "id": "2ef6f090.a62fb", "type": "ui_text", "z": "160a8256.91137e", "group": "a532b78d.8303b8", "order": 5, "width": 0, "height": 0, "name": "", "label": "Đã gửi lệnh", "format": "{{msg.payload}}", "layout": "row-spread", "x": 910, "y": 120, "wires": [] }, { "id": "ec9f4fc8.ffefc", "type": "function", "z": "160a8256.91137e", "name": "Lấy độ dài chuỗi", "func": "\nmsg.payload = msg.payload.length;\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 520, "y": 280, "wires": [ [ "6a5ff151.01fe4" ] ] }, { "id": "6a5ff151.01fe4", "type": "ui_numeric", "z": "160a8256.91137e", "name": "Độ dài chuỗi", "label": "", "tooltip": "", "group": "8cc674a4.10e3f8", "order": 6, "width": "2", "height": "1", "wrap": false, "passthru": true, "topic": "", "format": "{{value}}", "min": 0, "max": "32", "step": 1, "x": 730, "y": 300, "wires": [ [] ] }, { "id": "67b093c3.792bac", "type": "function", "z": "160a8256.91137e", "name": "Lấy đoạn chuỗi mà Arduino nhận được", "func": "\nmsg.payload = msg.payload.substr(0, 32);\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 600, "y": 160, "wires": [ [ "2ef6f090.a62fb" ] ] }, { "id": "9f12809.32a7b8", "type": "subflow:36cf6cf2.8b1414", "z": "160a8256.91137e", "name": "", "x": 920, "y": 480, "wires": [ [ "f1471541.63de28" ], [ "2a08fa4e.66ff86" ], [ "eda77085.d01b5" ], [ "5e3ed30b.84645c" ], [ "88f2c510.769e58" ], [ "e2aa7aa2.845738" ], [ "4f03abee.64fdb4" ], [ "312b32b7.b644ee" ] ] }, { "id": "bc0db1a4.dc6ce", "type": "http request", "z": "160a8256.91137e", "name": "[REST][POST]Xưởng cơ khí", "method": "POST", "ret": "txt", "url": "https://connect.mysmarthome.vn/api/1.0/request/Vx0PgGAzezNgJ7GZJgqi6HDe0mh1/LPefBPo03/12d2279cfa87aa91edbf1e9b1e0f1401290413650767/req_device_toggle", "tls": "", "x": 960, "y": 180, "wires": [ [] ] }, { "id": "35985b01.939894", "type": "mqtt in", "z": "160a8256.91137e", "name": "IN_MQTT_Raspberry", "topic": "/LPefBPo03/read", "qos": "0", "broker": "bcd4bc94.7e8be", "x": 260, "y": 420, "wires": [ [ "fb721e44.f0f04" ] ] }, { "id": "ec9c18ca.26d138", "type": "change", "z": "160a8256.91137e", "name": "", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "payload.devices", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 580, "y": 440, "wires": [ [ "7bedd8d8.8bbd58", "18a0c620.89265a" ] ] }, { "id": "fb721e44.f0f04", "type": "json", "z": "160a8256.91137e", "name": "", "property": "payload", "action": "obj", "pretty": false, "x": 430, "y": 420, "wires": [ [ "ec9c18ca.26d138" ] ] }, { "id": "7bedd8d8.8bbd58", "type": "json", "z": "160a8256.91137e", "name": "", "property": "payload", "action": "obj", "pretty": false, "x": 750, "y": 440, "wires": [ [ "9f12809.32a7b8" ] ] }, { "id": "859f2a0a.7bba58", "type": "inject", "z": "160a8256.91137e", "name": "", "topic": "", "payload": "LED OFF", "payloadType": "str", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 600, "y": 580, "wires": [ [ "8087a485.021878" ] ] }, { "id": "5342e35b.0d9a3c", "type": "inject", "z": "160a8256.91137e", "name": "", "topic": "", "payload": "LED BLINK", "payloadType": "str", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 600, "y": 620, "wires": [ [ "8087a485.021878" ] ] }, { "id": "9184768f.2224c8", "type": "inject", "z": "160a8256.91137e", "name": "", "topic": "", "payload": "LED BLINK_OFF", "payloadType": "str", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 580, "y": 660, "wires": [ [ "8087a485.021878" ] ] }, { "id": "8087a485.021878", "type": "mqtt out", "z": "160a8256.91137e", "name": "OUT_MQTT_Raspberry", "topic": "/LPefBPo03/write", "qos": "2", "retain": "false", "broker": "bcd4bc94.7e8be", "x": 850, "y": 600, "wires": [] }, { "id": "2acf0078.6ee6b", "type": "mqtt out", "z": "160a8256.91137e", "name": "OUT_MQTT_Raspberry", "topic": "mqtt/thientest", "qos": "2", "retain": "false", "broker": "bcd4bc94.7e8be", "x": 850, "y": 760, "wires": [] }, { "id": "9c496c6c.66f1f", "type": "inject", "z": "160a8256.91137e", "name": "", "topic": "", "payload": "\"Hello world\"", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 630, "y": 760, "wires": [ [ "2acf0078.6ee6b" ] ] }, { "id": "8b39427b.f3b0c", "type": "inject", "z": "160a8256.91137e", "name": "", "topic": "", "payload": "LED ON", "payloadType": "str", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 600, "y": 540, "wires": [ [ "8087a485.021878" ] ] }, { "id": "18a0c620.89265a", "type": "debug", "z": "160a8256.91137e", "name": "Debug_Raspberry", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "x": 790, "y": 400, "wires": [] }, { "id": "8cc674a4.10e3f8", "type": "ui_group", "z": "", "name": "Thứ nhất", "tab": "5956cdc1.91d694", "order": 1, "disp": true, "width": "6", "collapse": true }, { "id": "a532b78d.8303b8", "type": "ui_group", "z": "", "name": "Thứ 2", "tab": "5956cdc1.91d694", "order": 2, "disp": true, "width": "6", "collapse": true }, { "id": "bcd4bc94.7e8be", "type": "mqtt-broker", "z": "", "name": "", "broker": "192.168.137.202", "port": "1883", "clientid": "", "usetls": false, "compatmode": true, "keepalive": "60", "cleansession": true, "willTopic": "", "willQos": "0", "willPayload": "", "birthTopic": "", "birthQos": "0", "birthPayload": "" }, { "id": "5956cdc1.91d694", "type": "ui_tab", "z": "", "name": "Kiểm thử iNut cảm biến", "icon": "dashboard", "order": 1 } ]
Đây là code Arduino nha :
#include <iNut.h> iNut sensor; static bool blink_flag = false; #define LED 5 //chân 13 là chân LED void setup() { Serial.begin(9600); //bật baudrate ở mức 9600 Serial.println("San sang nhan lenh"); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); //Bật đèn LED sáng //Khai báo số lượng luồn cảm biến sensor.setup(8); //Sẽ có 08 luồn cảm biến sensor.addCommand("LED", ledFunction); sensor.setDefaultHandler(defaultHandler); } void loop() { #define Blink_INIT 0 #define Blink_ON 1 #define Blink_Wating 2 #define Blink_OFF 3 static int Blink_LED = Blink_INIT; static unsigned long Blink_timer = 0; sensor.setValue(0, digitalRead(LED)); //đọc giá trị của đèn LED //giá trị cho các luồn từ 1-7 là giá trị random ///Tại sao lại sử dụng random? Vì đây là thử nghiệm, bạn có thể thay thế giá trị random bằng một giá trị cảm biến hoặc trị số mà bạn mong muốn đồng bộ lên Internet! for (byte i = 1; i <= 7; i++) { unsigned long value = random() % 10000; //trả về giá trị random - "hên xui" - tự do sensor.setValue(i, value); //gán giá trị trên vào luồn } if (blink_flag) { static unsigned long timer = 0; if (millis() - timer > 100UL) { timer = millis(); digitalWrite(LED, !digitalRead(LED)); } } sensor.loop(); } //thực hiện khi nhận lệnh LED //gửi từ node RED xuống chú ý "LED", ví dụ muốn đèn sáng phải gửi lệnh là LED ON không phải mỗi ON không, chú ý viết hoa viết thường. void ledFunction() { char *arg = sensor.next(); Serial.print("trạng thái arg: "); Serial.println(arg); if (*arg == NULL) return; if (strcmp(arg, "ON") == 0) { //nếu tham số 1 là ON. LED ON. Thì đèn sáng digitalWrite(LED, HIGH); Serial.println("Bat den"); } else if (strcmp(arg, "OFF") == 0) { // LED OFF. Đèn tắt digitalWrite(LED, LOW); Serial.println("Tat den"); } else if (strcmp(arg, "TOGGLE") == 0) { //Đảo trạng thái của LED digitalWrite(LED, !digitalRead(LED)); Serial.println("Doi trang thai den"); } else if (strcmp (arg, "BLINK") == 0) { blink_flag = true; } else if (strcmp(arg, "BLINK_OFF") == 0) { blink_flag = false; } else { Serial.println("Khong nam trong tap hop lenh"); } } //Nếu nhận được lệnh không phải từ những lệnh được đăng ký trước thì sẽ ghi ra ở đây void defaultHandler(const char *command) { Serial.print(F("---Not found handler: ")); Serial.println(command); //Đoạn chương trình dưới chỉ dùng để debug, để các bạn biết chương trình của mình ở lỗi ở đâu để khắc phục, cũng không cần hiểu nha. int idx = 0; char *arg; while ((arg = sensor.next()) != NULL) { //còn tham số nào thì in ra Serial.print("-----> Gia tri thu #"); Serial.print(idx); Serial.print(": "); Serial.println(arg); idx++; } }
Bước 3: Kết nối wifi và truy cập từ xa với từ máy tính vào Raspberry-Pi.
Ở đây mình sử dụng cách kết nối thông qua Remote Desktop Connection như những bài trước , các bạn có thể sử dụng những cách khác nha, miễn sao truy cập được từ xa với Raspberry-Pi để tiện cho quá trình cài đặt.
Bước 4: Khởi động broker trên Raspberry
mosquitto_sub -d -u MOSQUITTO_USERNAME -P MOSQUITTO_PASSWORD -t mqtt/test
Nếu chưa rõ thì bạn có thể xem lại bài hướng dẫn ở đây nhé
Bước 5: Chạy thử và kiểm tra hoạt động của chương trình
Ở phẩn “Gửi lệnh xuống iNut cảm biến” bạn có thể nhập “LED ON” để bật đèn, “LED OFF” để tắt đèn, “LED BLINK” để điều khiển đèn nhấp nháy, “LED BLINK_OFF” để tắt trạng thái nhấp nháy của đèn. Sau khi nhập xong bạn nhớ Enter để thực hiện lệnh nhé.
Ngoài ra bạn có thể điều khiển led bằng cách click vào các ô vuông phía trước các ô lệnh nữa nha .
Nếu đèn sáng theo đúng lệnh của bạn điều khiển thì bạn đã thành công rồi nhé. Nếu xem bài viết bạn thấy khó khăn thì hãy xem video này nhé
III Tổng kết
Đơn giản quá đúng không nào. Chỉ với một vài thao tác bên trên bạn đã tự làm cho mình 1 webapp có khả năng đáp ứng và thay thế được cho app iNut rồi. Chúc bạn thành công và đừng quên chia sẻ những kiến thức bổ ích trên đến với bạn bè của bạn nhé.