iNut cảm biến - Bài 2: Tự tạo webapp điều khiển thiết bị IoT

10/04/2021
inut-cam-bien-bai-2-tu-tao-webapp-dieu-khien-thiet-bi-iot

I. Chuẩn bị thiết bị client

    Như bài 1, các bạn cũng cần một số mạch, linh kiện sau:

  • iNut cảm biến
  • Arduino (Mình dùng Arduino Mega)
  • Cảm biến vật cản hồng ngoại
  • Vài con led
  • Cảm biến ánh sáng (Hoặc quang trở)
  • Breadboard, dây cắm, điện trở,...

    Sau đó các bạn nối dây theo sơ đồ sau:

    Code dành cho Arduino, toàn bộ code này không có gì mới so với bài số 1, nếu các bạn đọc không hiểu thì hãy xem lại bài 1 nha :D. Trong ví dụ này mình sẽ sử dụng luồng số 0 để theo dõi cảm biến chống trộm, luồng số 1 để điều khiển 2 led và luồng số 2 để theo dõi cảm biến ánh sáng:

 

 
  1. #include <iNut.h>
  2.  
  3. iNut inut;// Khởi tạo đối tượng iNut
  4.  
  5. const int SO_LED = 2;
  6. int led[SO_LED] = {8, 9}; //2 bóng led được nối với chân 8,9
  7.  
  8. int chanCamBienVatCan = 2;
  9. boolean trangThaiVatCanTruoc = LOW;
  10.  
  11. void setup() {
  12. ​// Thiết lập chế độ OUTPUT cho 2 chân nối với le
  13. ​pinMode(led[0], OUTPUT)
  14. ​pinMode(led[1], OUTPUT)
  15.  
  16. ​// Thiết lập chế độ INPUT cho chân nối với cảm biế
  17. ​pinMode(chanCamBienVatCan, INPUT)
  18.  
  19. ​// Trạng thái ban đầu của các led là tắ
  20. ​digitalWrite(led[0], LOW)
  21. ​digitalWrite(led[1], LOW)
  22.  
  23. ​// Lệnh thiết lập kết nối Arduino với iNut cảm biến
  24. ​// trong đó 8 là số luồng dữ liệu của iNut cảm biế
  25. ​inut.setup(8)
  26.  
  27. ​// Bắt buộc phải có bước này: Đặt giá trị ban đầu cho 8 luồng khi mới kết nố
  28. ​for (int i = 0; i < 8; i++)
  29. ​// Lệnh đặt giá trị dữ liệu cho luồng thứ
  30. ​// Ban đầu thì cứ cho cả 8 luồng nhận giá trị là
  31. ​inut.setValue(i, 0)
  32.  
  33. ​// Khai báo cho iNut cảm biến: Khi nhận được lệnh "ON" thì chạy hàm onLe
  34. ​inut.addCommand("ON", onLed)
  35. ​// Khai báo cho iNut cảm biến: Khi nhận được lệnh "OFF" thì chạy hàm offLe
  36. ​inut.addCommand("OFF", offLed)
  37. }
  38.  
  39. void loop() {
  40. ​capNhatTrangThaiLed()
  41. ​capNhatTrangThaiAnhSang()
  42. ​kiemTraChongTrom()
  43.  
  44. ​// Cần chạy câu lệnh này trong hàm loo
  45. ​inut.loop()
  46. }
  47.  
  48. void onLed() {
  49. ​char *thamSo = inut.next();// Lấy tham s
  50. ​int giaTri = atoi(thamSo);// Lệnh atoi sẽ chuyển 1 chuỗi thành số nguyê
  51. ​int thuTuLed = giaTri - 216;// Theo bảng tra vị trí digital thì vị trí 0,1 luồng 1 là 216,21
  52. ​digitalWrite(led[thuTuLed], HIGH)
  53. }
  54.  
  55. void offLed() {
  56. ​char *thamSo = inut.next();// Lấy tham s
  57. ​int giaTri = atoi(thamSo);// Lệnh atoi sẽ chuyển 1 chuỗi thành số nguyê
  58. ​int thuTuLed = giaTri - 216;// Theo bảng tra vị trí digital thì vị trí 0,1 luồng 1 là 216,21
  59. ​digitalWrite(led[thuTuLed], LOW)
  60. }
  61.  
  62. void kiemTraChongTrom() {
  63. ​boolean trangThaiVatCan = digitalRead(chanCamBienVatCan);// Đọc giá trị cảm biế
  64. ​if (trangThaiVatCan != trangThaiVatCanTruoc)
  65. ​if (trangThaiVatCan == HIGH) { // Nếu không có vật cản - Trạng thái cảm biến là HIG
  66. ​// Lệnh đặt giá trị 1 (trạng thái HIGH) cho vị trí digital thứ 0 của luồng số
  67. ​inut.turnOn(0, 0);// turnOn(<luồng>, <vị trí digital>)
  68. ​} else { // Ngược lại nếu có vật cả
  69. ​// Lệnh đặt giá trị 0 (trạng thái LOW) cho vị trí digital thứ 0 của luồng số
  70. ​inut.turnOff(0, 0);// turnOff(<luồng>, <vị trí digital>)
  71. ​inut.alarm(0);// Gửi báo động đến máy chủ với mã báo động là
  72. ​trangThaiVatCanTruoc = trangThaiVatCan
  73. }
  74.  
  75. void capNhatTrangThaiLed() {
  76. ​// cập nhật dữ liệu cho các vị trí digital tương ứng với nút nhấn - Trạng thái các le
  77. ​for (int i = 0; i < SO_LED; i++)
  78. ​/* Có thể dùng lệnh digitalRead để đọc trạng thá
  79. ​của một chân cho dù chân này ở trạng thái OUTPU
  80. ​*
  81. ​boolean trangThaiLed = digitalRead(led[i])
  82. ​if (trangThaiLed == HIGH) { // Nếu Led sán
  83. ​// Lệnh đặt giá trị 1 (trạng thái HIGH) cho vị trí digital thứ i của luồng số
  84. ​inut.turnOn(1, i);// turnOn(<luồng>, <vị trí digital>)
  85. ​} else { // Nếu Led tắ
  86. ​// Lệnh đặt giá trị 0 (trạng thái LOW) cho vị trí digital thứ i của luồng số
  87. ​inut.turnOff(1, i);// turnOff(<luồng>, <vị trí digital>)
  88. }
  89.  
  90. void capNhatTrangThaiAnhSang() {
  91. ​int val = analogRead(A5);// Đọc giá trị quang tr
  92. ​inut.setValue(2, val);// Đặt giá trị dữ liệu cho luồng số 2 là giá trị quang tr
  93. }

 

    Sau đó mở app iNut và thiết lập trình thuật sĩ để chắc chắn rằng client đã hoạt động ok.

Trong ví dụ này chúng ta sử dụng 2 led, 1 cảm biến digital, 1 cảm biến analog

    Tắt bật lại app, mở bảng điều khiển, quan sát sẽ thấy luồng 0 và 1 không đúng với chức năng mà mình đã yêu cầu ở trên: Luồng 0 => báo trộm, luồng 1 => điều khiển Led. Vì vậy chúng ta cần chỉnh sửa lại chức năng của luồng trong app bằng cách vào mục cài đặt => Chọn thiết bị iNut cảm biến => Chọn luồng muốn sửa chức năng.

    Sau đó chọn Kiểu dữ liệu

    Các kiểu dữ liệu tương ứng với các chức năng:

  • Input (bit_in): Theo dõi dữ liệu, cảm biến digital
  • Output (bit_out): Điều khiển trạng thái digital của các thiết bị ở client
  • Số thực (float): Thu thập, theo dõi dữ liệu ở kiểu số thực (Ví dụ: Nhiệt độ 27.5°C)
  • Số nguyên (float): Thu thập, theo dõi dữ liệu ở kiểu nguyên (Ví dụ: Giá trị analog cảm biến ánh sáng)

Với cảm biến hồng ngoại thì chọn Input (bit_in)

    Sau đó các bạn chọn mục Số bit - Đây là nơi thiết lập số vị trí digital của luồng được sử dụng, ở đây chúng ta chỉ sử dụng 1 vị trí cho cảm biến hồng ngoại nên sửa số bit lại thành 1 nhé!

    Các bạn thiết lập tương tự cho luồng số 1: Output (bit_out) và Số bit là 2 (Vì ở đây dùng 2 led).

    Sau khi client hoạt động ổn rồi thì ta sang tiếp bước chính của bài hôm nay - Tạo webapp.

    À trong phần cài đặt cho luồng còn rất nhiều mục tùy chỉnh thú vị khác, các bạn tự khám phá nha :D

II. MQTT là gì?

    MQTT (Message Queuing Telemetry Transport) là một giao thức gửi dữ liệu (Bằng chuỗi ký tự) thông qua hình thức Gửi - Đăng ký nhận dữ liệu về một Chủ đề nào đó.

Mô hình hoạt động của MQTT

    Trong đó:

  • Có 1 máy chủ (gọi là MQTT broker) và nhiều thiết bị kết nối vào máy chủ (gọi là MQTT client, gọi tắt là client) (Trong hình xanh lá là broker, xanh dương là client)

  • Client được chia làm 2 nhóm: Nhóm gửi dữ liệu gọi là publisher, hành động gửi dữ liệu gọi là publish và nhóm nhận dữ liệu gọi là subscriber, hành động đăng ký nhận dữ liệu từ broker gọi là subscribe (Trong ảnh, publisher là cảm biến nhiệt độ, còn điện thoại và máy tính là 2 subscriber).

  • Chủ đề hay topic chính là thứ giúp publisher và subscriber nhận ra nhau để có thể gửi/nhận dữ liệu với nhau. Ví dụ Arduino gắn cảm biến ánh sáng gửi dữ liệu đến broker với topic “Độ sáng phòng khách” và app iNut cần biết độ sáng trong phòng khách nên sẽ đăng ký nhận dữ liệu từ topic “Độ sáng phòng khách” của broker.

  • Broker có chức năng là nhận dữ liệu từ các publisher, phân loại dữ liệu theo topic và phân phối dữ liệu đến các subscriber theo các topic đó.

    Để dễ hình dung, các bạn cứ tưởng tượng youtube là Broker, người làm video và người xem là Client. Giả sử kênh video là “Bà Tân Vlog”, thì “Bà Tân Vlog” chính là Topic, còn người làm video ví dụ bà Tân đóng vai trò là một Publisher. Còn người xem khi subscribe Topic “Bà Tân Vlog” và bật chuông thông báo thì họ đã trở thành một subscriber của Topic “Bà Tân Vlog”. Khi bà Tân đăng video mới lên youtube thì người xem đã đăng ký và nhấn chuông sẽ nhận được thông báo về video mới này. Tương ứng với việc Publisher đã Publish dữ liệu vào Topic “Bà Tân Vlog” trên Broker, khi đó Broker sẽ gửi dữ liệu đến tất cả các subscriber của Topic này.

    Ưu điểm của MQTT là khả năng được sử dụng trong mạng lưới không ổn định với băng thông thấp và độ tin cậy cao.

    Một số lưu ý:

  • Một client chỉ có thể là subscriber hoặc là publisher đối với một topic. Do đó khi một client vừa cần gửi dữ liệu vừa cần nhận dữ liệu từ một client khác thì nó phải tương tác với 2 topic khác nhau.
  • Cấu trúc của topic có thể gồm các trường topic cách nhau bởi dấu “/”, mục đích của các trường này là giúp phân nhóm dữ liệu dễ dàng hơn. Ví dụ: “phongkhach/nhietdo”, “phongkhach/anhsang”, “phongngu/nhietdo”, “phongngu/anhsang”,.....

III. NodeRed là gì?

    NodeRed là một công cụ dựa trên NodeJS nhằm giúp tạo nên 1 webserver mà bạn có thể cấu hình tùy chỉnh các chức năng bằng cách kéo thả các khối lệnh trên trình duyệt web. Một ứng dụng NodeRed hoạt động theo mô hình “luồng” dữ liệu (flow), một “luồng” bao gồm các khối lệnh (gọi là các Node) liên kết với nhau theo dạng Input (Dữ liệu vào) => Operation (Xử lý) => Output (Trả kết quả).

Mô hình đơn giản của “luồng” liên kết các khối lệnh trong NodeRed

    Có thể hiểu đơn giản như sau: “Luồng” chính là 1 dây chuyền sản xuất, đầu “luồng” là dữ liệu vào Input tương ứng với nguyên liệu đưa vào dây chuyền, sau đó nguyên liệu sẽ trải qua hàng loạt khâu chế biến và trả ra thành phẩm ở cuối dây chuyền. Tương tự như vậy, dữ liệu vào sẽ trải qua hàng loạt Node xử lý và cuối cùng trả ra kết quả (như xuất ra màn hình, gửi thông báo, gửi lệnh điều khiển,...).

    Người dùng có thể sử dụng các Node có sẵn hoặc tự tạo Node bằng cách lập trình bằng ngôn ngữ Javascript.

    Hướng dẫn cài đặt NodeRed:

    Vì nó dựa trên NodeJS nên trước tiên ta cần cài đặt NodeJS nhé, xem hướng dẫn tại đây

    Sau đó để cài đặt NodeRed, các bạn mở cửa sổ Command Line ra (Nhấn tổ hợp phím Window + R => Nhập cmd => Enter). Sau đó bạn gõ lần lượt từng lệnh sau:

npm install -g --unsafe-perm node-red
​​npm install -g node-red-dashboard

    Tiếp theo, chúng ta sẽ khởi động NodeRed bằng cách gõ vào Command Line lệnh: node-red. Sau khi gõ lệnh, các bạn chờ một tí để NodeRed khởi động đến khi xuất hiện dòng "Server now running at http://127.0.0.1:1880" là được. Đừng tắt Command line nha, nếu không NodeRed sẽ bị tắt theo đó.

    Để mở NodeRed, các bạn dùng trình duyệt web truy cập địa chỉ: 127.0.0.1:1880

Màn hình làm việc chính của NodeRed

 Như vậy chúng ta đã vừa kết thúc bài số 2, qua đây các bạn đã có thể tự tạo cho mình một webapp rồi! Hãy tìm hiểu thêm chức năng của các Node khác trong NodeRed (cái này trên Google nhiều lắm hehe :D) và tự sáng tạo cho mình 1 cái webapp thật bá đạo nha (Tự vọc vạch phần Edit của Tab và Group đi, các bạn sẽ khám phá ra được cách sắp xếp các đối tượng giao diện trên webapp nhanh thôi, dễ lắm hehe).

    Vì NodeRed được cài trên máy tính của bạn, nên webapp này chỉ hoạt động trong mạng nội bộ nhà bạn thôi. Nếu bạn muốn điều khiển ở ngoài internet thì cần NAT Port 1880 mạng nhà bạn hoặc cài đặt và làm việc với NodeRed trên VPS cho nhanh (Có nhiều dịch vụ cho thử VPS tới tận 1 năm luôn, tha hồ xài free :3)

    Nếu có bất kỳ thắc mắc nào, hãy comment ngay bên dưới để mình và mọi người giải đáp giúp bạn. Tạm biệt!

 

Bình luận
Nội dung này chưa có bình luận, hãy gửi bình luận đầu tiên của bạn.
VIẾT BÌNH LUẬN CỦA BẠN