Cách tự "hack" điều khiển thiết bị điện trong nhà chỉ với 30 phút

Mô tả dự án: 

Một thiết bị điện thông minh hiện đại là phải "có thể lập trình được" để có thể làm theo ý mình. Với cuộc cách mạng công nghiệp 4.0, những sản phẩm IoT hiện này đã rất phổ biến. Những ý tưởng tưởng chừng như "điên rồ" trước đây thì nay đã trở thành hiện thực. Hãy cùng tôi "hack" vào cái công tắc điện trong nhà và dùng những tấm thẻ RFID để bật tắt điện trong nhà nhé.

Chúng ta sẽ làm gì hôm nay

Với một mạch iNut - Nút nhấn (1 thiết bị) mình mua từ MySmarthome với chức năng bật tắt và hẹn giờ qua Internet và Wifi nội bộ. Ngoài ra, đây cũng là một thiết bị trong hệ thống iNut Platform. Vì vậy, thiết bị này hỗ trợ REST API và có thể lập trình điều khiển được. Thế là bắt tay ngay vào việc suy nghĩ cho ngày "mùng name" Tết Mậu Tuất 2018 của mình. Và, kịch bản sẽ là:

  • Đưa một thẻ RFID nào đó để bật đèn
  • Một thẻ nữa là để tắt đèn.
  • Với sự góp ý của bạn Nguyễn Bảo Sang, mình thêm một thẻ RFID nữa để đổi trạng thái (Toggle) luôn cái thiết bị đó.

Thế là với 3 thẻ RFID mình sẽ thử điều khiển cái bóng điện của mình.

Các bạn có thể sáng tạo để có thể mở cửa cuốn, mở cửa nhà từ xa nữa nha,... bạn có thể làm tất cả mọi thứ với iNut Platform.

Bạn cần chuẩn bị những gì để bắt đầu

Bạn cần bao lâu để làm bài hướng dẫn này

  • Thời gian lắp mạch iNut vào mạch điện và cài đặt qua App iNut: 10 - 20 phút.
  • Thời gian lắp mạch RFID: 5 - 10 phút.
  • Thời gian lấy địa chỉ RFID từ thẻ RFID: 5 - 10 phút.
  • Sửa chữa code, nạp code vào NodeMCU để điều khiển thử nghiệm: 10 phút.

Vậy, bạn chỉ cần 30 phút là có thể hoàn thành bài hướng dẫn này rồi. Hãy lựa chọn thời điểm thích hợp trong tuần sau Tết để chiến đấu nghen ^_^.

Mắc và cài đặt thiết bị iNut vào mạch điện

Bước 1: Nối điện iNút

Bước 2: Cài đặt mạng (Password: inut12345)

 

Bước 3: Điều khiển thiết bị

Một chạm điều khiển thiết bị

 

Mắc mạch RFID và lấy thông tin 03 thẻ thiết bị

Các bạn hãy mắc mạch như sau vào module RFID và NodeMCU nhé. Bỏ cái đèn LED đi, trong bài này, chúng ta không dùng đến đèn LED này. Các bạn tải về các thư viện còn thiếu (thư viện RFID, thư viện ArduinoJson và thư viện Socket.IO-client) ở đây nhé.

Các bạn nạp code đoạn code sau vào NodeMCU nha: 

 

#include <SPI.h>
#include <MFRC522.h>
#include <ArduinoJson.h>
#include <SocketIOClient.h>

#define RST_PIN         D1          // Chân RST
#define SS_PIN          D2          // Chân SS hoặc một số mạch là SDA

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
 // delay(5000);
  Serial.begin(9600);   // Khởi tạo serial với baudrate 9600
  
  Serial.println("setup()");
  
  SPI.begin();      //
  Serial.println("Khoi tao SPI");
  mfrc522.PCD_Init();   // Init MFRC522
  Serial.println("Khoi dong module RFID");
  mfrc522.PCD_DumpVersionToSerial();  // In ra thông tin của module (version)
  Serial.println("Luot the RFID de co thong tin");
}

void loop() {
  
  
  // Chờ xem phải thẻ RFID mới ko?
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Chọn một thẻ
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  unsigned long uidDec = 0;

  // Hien thi so UID cua the
  Serial.print("Card UID: ");
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    unsigned long uidDecTemp = mfrc522.uid.uidByte[i];
    uidDec = uidDec*256+uidDecTemp;
  } 

  Serial.println(uidDec);

  Serial.print("Size: ");
  Serial.println(mfrc522.uid.size);
}

Ví dụ, khi ta để một thẻ RFID lên phía rên module RFID nó hiện ra đoạn mã 3236458659. Số này, chính là mã của thẻ RFID, tùy vào chương trình của bạn mà nó sẽ ra một số khác nhé.

Bạn lặp lại quy trình với 02 thẻ còn lại. Mình có 03 danh sách thẻ RFID như sau:

unsigned long turnOnCardId = 3878428834UL;
unsigned long turnOffCardId = 3071341165UL;
unsigned long toggleCardId = 3236458659UL;

Tại sao lại có chữ UL ở dưới. Vì để đánh dấu đây là hằng số nguyên dương mang kiểu unsigned long.

Nào ta cùng "hack"

Các bạn thay thế giá trị vào các biến:

  • ssid: tên mạng wifi nhà bạn
  • password: mật khẩu nhà bạn
  • turnOnCardId:
  • turnOffCardId
  • toggleCardId
  • nodeJson1mã uuid, node_id, token của thiết bị, bạn có thể xem video hướng dẫn lấy mã này ở ngay video dưới.

//Thư viện để dùng module RFID
#include <SPI.h>
#include <MFRC522.h>

//Thư viện để giải mã chuỗi JSON cho dễ code
#include <ArduinoJson.h>

//Thư viện để dùng kết nối vào Wifi và socket
#include <ESP8266WiFi.h>
#include <SocketIOClient.h>

//Thư viện để tạo http request nhằm điều khiển thiết bị
#include <ESP8266HTTPClient.h>

#define RST_PIN         D1          // Chân RST
#define SS_PIN          D2          // Chân SS hoặc một số mạch là SDA

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

SocketIOClient client;
const char* ssid = "linksys";          //Tên mạng Wifi mà Socket server của bạn đang kết nối
const char* password = "khanhdeptrai";  //Pass mạng wifi ahihi, anh em rãnh thì share pass cho mình với.
 
char host[] = "socket.mysmarthome.vn";  //Địa chỉ IP dịch vụ, hãy thay đổi nó theo địa chỉ IP Socket server của bạn.
int port = 80;                  //Cổng dịch vụ socket server do chúng ta tạo!

//từ khóa extern: dùng để #include các biến toàn cục ở một số thư viện khác. Trong thư viện SocketIOClient có hai biến toàn cục
// mà chúng ta cần quan tâm đó là
// RID: Tên hàm (tên sự kiện
// Rfull: Danh sách biến (được đóng gói lại là chuối JSON)
extern String RID;
extern String Rfull;

unsigned long turnOnCardId = 3878428834UL;
unsigned long turnOffCardId = 3071341165UL;
unsigned long toggleCardId = 3236458659UL;

//token, uuid, node_id
String nodeJson1 = "{\"node_id\":\"r1O92dtSz\",\"uuid\":\"52JRJHs3jcdqH6pC8R3f130ETnJ3\",\"token\":\"b1baa1421c29e7b6451074024fb3bfaa830715216097\"}";


//hàm đăng ký một node vào socket client
void registerNode(String json) {
  // debug
  StaticJsonBuffer<300> jsonBuffer;
  JsonObject &node = jsonBuffer.parseObject(json.c_str());
  String uuid = node.get<const char *>("uuid");
  String node_id = node.get<const char *>("node_id");
  String token = node.get<const char *>("token");
  Serial.println("Dang ky node: ");
  Serial.print("uuid: ");
  Serial.println(uuid);
  Serial.print("node_id: ");
  Serial.println(node_id);
  Serial.print("token: ");
  Serial.println(token);

  //bước đăngký
  client.send("register_node", json);
}




void setup() {
 // delay(5000);
  Serial.begin(9600);   // Khởi tạo serial với baudrate 9600
  
  Serial.println("setup()");
  
  
  Serial.print("Ket noi vao Wifi: ");
  Serial.println(ssid);
  Serial.print("Mat khau: ");
  Serial.println(password);
  WiFi.begin(ssid, password);
  
  //Chờ đến khi đã được kết nối
  while (WiFi.status() != WL_CONNECTED) { //Thoát ra khỏi vòng 
      delay(500);
      Serial.print('.');
  }

  Serial.println();
  Serial.println(F("Da ket noi WiFi"));
  Serial.println(F("Di chi IP cua ESP8266 (Socket Client ESP8266): "));
  Serial.println(WiFi.localIP());

  if (!client.connect(host, port)) {
      Serial.println(F("Ket noi den socket server that bai!"));
      return;
  }

  //Khi đã kết nối thành công
  if (client.connected()) {
      //Thì gửi sự kiện ("connection") đến Socket server ahihi.
      Serial.println("Ket noi thanh cong");
      registerNode(nodeJson1);
  }

  SPI.begin();      //
  Serial.println("Khoi tao SPI");
  mfrc522.PCD_Init();   // Init MFRC522
  Serial.println("Khoi dong module RFID");
  mfrc522.PCD_DumpVersionToSerial();  // In ra thông tin của module (version)
  Serial.println("Luot the RFID de co thong tin");
}

void loop() {
  
  static unsigned long prevUidDec = 0;
  // Chờ xem phải thẻ RFID mới ko?
  if (mfrc522.PICC_IsNewCardPresent()) {
    
    // Chọn một thẻ
    if (mfrc522.PICC_ReadCardSerial()) {
      unsigned long uidDec = 0;
      

      // Hien thi so UID cua the
      
      for (byte i = 0; i < mfrc522.uid.size; i++) {
        unsigned long uidDecTemp = mfrc522.uid.uidByte[i];
        uidDec = uidDec*256+uidDecTemp;
      } 
      if (prevUidDec != uidDec) {
        Serial.print("Card UID: ");
        Serial.println(uidDec);
      
        Serial.print("Size: ");
        Serial.println(mfrc522.uid.size);


        prevUidDec = uidDec;
        if (uidDec == turnOnCardId) {
          sendPostRequestJSONtoINutDevice(nodeJson1, 0, "ON");
        } else if (uidDec == turnOffCardId) {
          sendPostRequestJSONtoINutDevice(nodeJson1, 0, "OFF");
        } else if (uidDec == toggleCardId) {
          sendPostRequestJSONtoINutDevice(nodeJson1, 0, "TOGGLE");
        }
      }
    }
  }

  static unsigned long timer = 0;
  //Sau 3 giây kể từ lần cuối nhận được thẻ thì cho phép dùng lại)
  if (prevUidDec > 0 && millis() - timer > 3000UL) { 
    prevUidDec = 0;
    timer = millis();
  } else if (prevUidDec == 0) {
    timer = millis();
  }

  

  

  //Khi bắt được bất kỳ sự kiện nào thì chúng ta có hai tham số:
  //  +RID: Tên sự kiện
  //  +RFull: Danh sách tham số được nén thành chuỗi JSON!
  if (client.monitor()) {
      Serial.println(RID);
      Serial.println(Rfull);
      if (RID == "please_login") {
        //yêu cầu đăng nhập nên ta sẽ gửi thông tin token, uuid,..., nói chung sau khi đã có lệnh please_login thì ta gửi đăng ký thêm lúc nào cũng được
        registerNode(nodeJson1);
      }
  }

  //Kết nối lại!
  if (!client.connected()) {
    Serial.println("Ket noi lai");
    client.reconnect(host, port);
  }
}

//hàm sinh ra lệnh tắt bật đèn
String getAPIUrl(String json) {
  
  StaticJsonBuffer<300> jsonBuffer;
  JsonObject &node = jsonBuffer.parseObject(json.c_str());
  String uuid = node.get<const char *>("uuid");
  String node_id = node.get<const char *>("node_id");
  String token = node.get<const char *>("token");
  
  String res = "http://connect.mysmarthome.vn/api/1.0/request/";
  res += uuid;
  res += "/";
  res += node_id;
  res += "/";
  res += token;
  return res;
}

//hàm gửi lệnh cho API req_device_toggle
void sendPostRequestJSONtoINutDevice(String json, int id, String command) {
  StaticJsonBuffer<300> JSONbuffer;
  JsonObject& root = JSONbuffer.createObject(); 

  root["id"] = id;
  root["command"] = command.c_str();
  
  char JSONmessageBuffer[300];
  root.prettyPrintTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
  Serial.println(JSONmessageBuffer);

  HTTPClient http;    //Declare object of class HTTPClient

  http.begin(getAPIUrl(json) + "/req_device_toggle");      //Specify request destination
  http.addHeader("Content-Type", "application/json");  //Specify content-type header

  int httpCode = http.POST(JSONmessageBuffer);   //Send the request
  String payload = http.getString();                                        //Get the response payload

  Serial.println(httpCode);   //Print HTTP return code
  Serial.println(payload);    //Print request response payload

  http.end();  //Close connection
}

Ý tưởng của chương trình trên:

  • Chương trình sẽ kết nối vào Wifi sau đó cài đặt các đoạn code cần thiết để dùng được module RFID-RC522.
  • Sau đó, kết nối vào Socket API của iNut Platform với mục đích là khi có data mới (ví dụ người dùng nhấp trong app hay nhấn ngoài thiết bị iNut thì mình biết được).
  • Sau đó cài đặt chương trình nếu nhận đúng thẻ RFID đã cài đặt thì dùng REST API để điều khiển thiết bi.

Code hết sức là đơn giản luôn. Chúc các bạn thành công!

lên
4 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Bộ điều khiển PID - ứng dụng phần 2 - xe dò line dùng thuật toán PID

Tiép nối bài viết về xe dò line cảm ơn Đỗ Hữu Toàn đã viết hộ mình phần 4. hôm nay mình sẽ làm cho chiếc xe dò line đi mượt và có hồn hơn 

lên
34 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

Tạo một quy trình công nghiệp với các bước bằng Arduino

Như đã nói ở vấn đề trước Xử lý nhiều tiến trình cùng một lúc trên Arduino - Có thể hay không?, chúng ta có thể xử lý nhiều tiến trình trên Arduino theo cơ chế bất đồng bộ. Tuy nhiên, một vấn đề khá hay mà từ các bình luận ở bài viết đó, mình mới ngộ ra được, đó là làm thế nào để xây dựng một quy trình công việc thực sự trên một board mạch Arduino. Thiết nghĩ, điều đó, hoàn toàn có thể thực hiện được, và xin chia sẻ với mọi người qua bài viết này nhằm giúp tất cả chúng ta có một thư viện chuẩn để làm những công việc phức tạp hơn.

lên
12 thành viên đã đánh giá bài viết này hữu ích.

iNut platform là gì?

Nhắc tới dòng mạch iNut dùng để lập trình, cái đầu tiên mà người ta thường nói tới chính là dòng iNut Cảm biến – một trong các mạch cho việc lập trình IoT. Hiện dòng mạch này đã phát triển tới thế hệ thứ 2 (iNut Sensor R2). Bạn sẽ bắt đầu đến với nền tảng iNut Platform thông qua mạch này. Bạn có thể dùng firmware iNut cảm biến cũng được nhưng bạn nên dùng bo mạch iNut Sensor R2 vì nó rất gọn và tương thức với Arduino Uno và Arduino Mega.

lên
4 thành viên đã đánh giá bài viết này hữu ích.
Từ khóa: