Như ở bài viết trước mình đã có đề cập tới một số cách để cập nhật firmware từ xa hay còn gọi là update OTA cho ESP8266, vì những cách này khá khó khăn khi không thông qua một server nào cả, nên hôm nay mình sẽ có thêm bài cập nhật để các bạn có thể update firmware được thông qua một server nodejs tự build. Bài viết về các cách cũ ta có thể tham khảo ở link dưới đây

Cập nhật firmware từ xa cho ESP8266 | Học ARM
Làm thế nào để cập nhật từ xa cho ESP8266 ? Hẳn là các bạn có biết một cách để nạp firmware cho ESP8266 cần có kết nối với máy tính qua cổng USB, vậy nếu bạn thấy quá trình trên phải sử dụng dây nối rườm rà quá, ESP8266 có wifi mà sao không tận dụng kết nối wifi để nạp luôn firmware cho chip mà chưa…

Có 3 phương pháp để nạp firmware mới cho ESP8266:

  • Sử dụng Arduino IDE: phương pháp này cần phải sử dụng phần mềm Arduino IDE để nạp. Nó không được linh động cho lắm và chỉ nên dùng khi đang phát triển phần mềm.
  • Sử dụng Web Browser: phương pháp này dùng ESP8266 làm server sau đó ta truy cập vào ip của ESP upload firmware mới lên và ESP8266 sẽ tự động nạp vào bộ nhớ flash của nó.
  • Sử dụng HTTP Server: phương pháp này ESP8266 tự kết nối với server, kiểm tra có firmware mới không, nếu có thì  tự tải file firmware mới đó về và cập nhật mới.

Trong bài viết này mình sẽ tập trung và o cách thứ 3 nha anh em

HTTP Server

Với 2 phương pháp kể trên, bạn dễ dàng cập nhật Firmware thông qua mạng WiFi nội bộ. Tuy nhiên, khi triển khai ứng dụng thực tế, chúng ta sẽ cần cập nhật Firmware từ xa thông qua Internet, và cần 1 Server để lưu trữ firmware, quản lý các phiên bản.

Thông thường nhất:

  • Khi ESP8266 khởi động (khoảng sau 1 khoảng thời gian - ví dụ như 1 ngày), nó sẽ kết nối đến Server, cung cấp thông tin phiên bản hiện có của nó
  • Server khi nhận thấy phiên bản hiện tại cần phải được nâng cấp, nó sẽ trả về firmware mới
  • Nếu phiên bản hiện tại của ESP8266 không cần phải cập nhật, nó sẽ trả về mã 304.

Để thực hiện được điều này, chúng ta cần thực hiện trên cả ESP8266 và trên Server side. Ở đây chúng ta sẽ dùng Node.js làm server. Bạn hoàn toàn có thể quăng code này lên Server bất kỳ và gán cho nó domain để có thể truy cập từ bất kỳ đâu.

ESP8266 ESPhttpUpdate

Bằng cách thực thi ESPhttpUpdate.update("your-domain.com", 3000, "/fimrware.bin");, ESP8266 sẽ tự động kết nối tới server ở địa chỉ your-domain.com:3000/fimrware.bin để tải phiên bản firmware mới về.

Với HTTP Status Code:

  • Code 200: Nếu tồn tại firmware mới, và nội dung file sẽ được gởi kèm sau đó
  • Code 304: Thông báo là không có bản update mới.

Chương trình

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
const char* ssid = "SCKT";
const char* password = "Ahuhu@123";
const char *currentVersion = "1.0";
const char *serverUrl = "http://192.168.1.150:3000/firmware.bin";
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  Serial.print("ESP8266 http update, current version: ");
  Serial.println(currentVersion);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  t_httpUpdate_return ret = ESPhttpUpdate.update(serverUrl, currentVersion);
  switch (ret) {
    case HTTP_UPDATE_FAILED:
      Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(),
                    ESPhttpUpdate.getLastErrorString().c_str());
      break;
    case HTTP_UPDATE_NO_UPDATES:
      Serial.println("HTTP_UPDATE_NO_UPDATES");
      break;
    case HTTP_UPDATE_OK:
      Serial.println("HTTP_UPDATE_OK");
      break;
  }
}
void loop() {
}

Có 2 chỗ cần lưu ý:

  • Phiên bản firmware của bạn, trên server sẽ có 2 phiên bản esp8266-firmware-2.0.bin là firmware bản mới 2.0, firmware.bin là phiên bản cũ, chương trình chỉ khác nhau ở đoạn code const char *currentVersion = "1.0";
  • Đường dẫn đến firmware của bạn, là địa chỉ web, ip, hay domain, ở đây IP của mình là 192.168.1.150 và port server là 3000

Vậy là xong cho ESP8266, giờ ta qua build server

Node.js OTA Server

Khi ESP8266 kết nối tới Web Server, thì nó sẽ cung cấp các thông tin Header để Server căn cứ vào đó đánh giá firmware có cần phải cập nhật hay không.

Ví dụ về các header

[HTTP_USER_AGENT] => ESP8266-http-Update
[HTTP_X_ESP8266_STA_MAC] => 18:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_AP_MAC] => 1A:FE:AA:AA:AA:AA
[HTTP_X_ESP8266_FREE_SPACE] => 671744
[HTTP_X_ESP8266_SKETCH_SIZE] => 373940
[HTTP_X_ESP8266_SKETCH_MD5] => a56f8ef78a0bebd812f62067daf1408a
[HTTP_X_ESP8266_CHIP_SIZE] => 4194304
[HTTP_X_ESP8266_SDK_VERSION] => 1.3.0
[HTTP_X_ESP8266_VERSION] => 1.0

Dựa trên kiến thức phần xây dựng Server với Nodejs trong 2 bài WebSocket và MQTT

Toàn tập Web Socket với ESP8266 | Học ARM
Trong bài viết này chúng ta sẽ tìm hiểu về WebSocket, cách để biến ESP8266 thành WebSocket Server và WebSocket Client. Việc sử dụng giao thức websocket sẽ có nhiều lợi ích cho các kết nối 2 chiều, luôn được duy trì và có độ trễ thấp. Chúng ta cùng tìm hiểu thôi WebSocket Server là gì? WebSoket là c…
Toàn tập về MQTT Server và MQTT Client | Học ARM
Như chúng ta đã tìm hiểu ở phần trước về MQTT và thực hành cơ bản, ta đã biết được MQTT là gì, cách để sử dụng MQTT và dùng ESP8266 trong MQTT như thế nào, giờ thì mình sẽ đi cụ thể hơn về 2 thành phần của MQTT là MQTT Client và MQTT Broker với một số loại chính cũng như là cách để chúng ta có thể s…

Chúng ta xây dựng 1 OTA Server dùng Node.js như sau

var fs = require('fs');
var url = require('url');
var http = require('http');
var querystring = require('querystring');
var crypto = require('crypto');
// function gửi yêu cầu(response) từ phía server hoặc nhận yêu cầu (request) của client gửi lên
function requestHandler(request, response) {
    // Giả sử địa chỉ yêu cầu firmware http://192.168.1.7:8000/firmware.bin
    var uriData = url.parse(request.url);
    var pathname = uriData.pathname; // /firmware.bin
    if (pathname == '/firmware.bin') {
        var ver = request.headers['x-esp8266-version'];
        console.log('Client request update, version ', ver);
        if (ver == '1.0') {
            console.log('Send firmware 2.0 to client');
            fs.readFile('./esp8266-firmware-2.0.bin', function(error, content) {
                response.writeHead(200, {
                    'Content-Type': 'binary/octet-stream',
                    'Content-Length': Buffer.byteLength(content),
                    'x-MD5': crypto.createHash('md5').update(content).digest("hex")
                });
                response.end(content);
            });
        } else {
            response.statusCode = 304;
            response.end();
        }
    }
}
var server = http.createServer(requestHandler);
server.listen(3000);
console.log('Server listening on port 3000');

Ta gọi lệnh sau để start server

nodemon server.js

Lưu ý:

  • Luôn phải đảm bảo khi gởi về client cần có đầy đủ thông tin header Content-Length và x-MD5.
  • File esp8266-firware-2.0.bin sau khi build ra từ ArduinoIDE, ta phải copy đưa nó cùng thư mục với file server.js
  • Để tìm đường dẫn output file bin, chọn File > Preference > Show verbose output during compilation

Kết quả

Chương trình bạn có thể tham khảo tại

hocarm/nodejs-socketio-tutorial
Contribute to hocarm/nodejs-socketio-tutorial development by creating an account on GitHub.

Tạm kết

Vậy là chúng ta đã tìm hiểu xong các cách update firmware OTA cho ESP8266, cách để dựng server update firmware từ xa với server NodeJS. Ta đã có thể cập nhật Firmware từ xa thông qua Internet, có Server để lưu trữ firmware, quản lý các phiên bản.