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ó 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
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
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.