ESP8266 – Các chế độ cấu hình WiFi
Thông thường, khi bắt đầu kết nối wifi cho ESP8266, ta phải cấu hình cho thiết bị các thông số của Access Point cũng như SSID và password nếu mạng wifi được thiết lập các bảo mật như WEP/WPA/WPA2. Tuy nhiên, các ứng dụng nhúng sử dụng Wi-fi thường ít chú trọng đến giao diện người dùng (user interface), không có bàn phím hay touchscreen,.. để giao tiếp. Vì thế, mỗi khi muốn kết nối thiết bị ESP với một Access Point nào đó, bạn cần phải có một máy tính đã cài đặt sẵn phần mềm biên dịch, tiếp theo là viết code cấu hình lại thông số wifi cho thiết bị, sau đó nạp code cho thiết bị thông qua một cable USB.
Điều này làm cho việc kết nối wifi trở nên khá bất tiện và phức tạp. Do vậy ESP8266 cung cấp các phương pháp thay thế khác giúp đơn giản hóa việc kết nối trạm ESP (chế độ Station) với một điểm truy cập. Đó là kết nối bằng SmartConfig
, WPS
hay Wifi Manager
.
Smartconfig
Kiến thức
SmartConfig là một giao thức được tạo ra nhằm cấu hình cho các thiết bị kết nối với mạng WiFi một cách dễ dàng nhất bằng smart phone. Nói một cách đơn giản, để kết nối WiFi cho thiết bị ESP8266, ta chỉ cần cung cấp thông tin mạng wifi (bao gồm SSID và password) cho ESP thông qua 1 ứng dụng trên smart phone.
Chúng ta nên biết rằng, khi 1 điện thoại thông minh đã kết nối vào mạng WiFi có mật khẩu, thì toàn bộ dữ liệu trao đổi giữa Điện thoại và đầu mối khác trong mạng sẽ được mã hóa. Nghĩa là các thiết bị chưa được kết nối mạng và không có mật khẩu thì không thể giải mã được dữ liệu. Vậy làm thế nào để Ứng dụng trên điện thoại gởi thông tin kết nối này đến 1 thiết bị khác chưa hề kết nối mạng. Để làm được điều này, thì nhờ vào 2 đặc điểm sau:
-
ESP8266 có khả năng
lắng nghe
tất cả các gói tin không dây WiFi xung quanh nó, bao gồm cả các gói tin đã được mã hóa. -
Các gói tin gởi trong mạng WiFi được mã hóa và không thể đọc được nội dung, tuy nhiên độ dài gói tin là một hằng số. Ví dụ, gói tin A chưa mã hóa có chiều dài là
x
, khi mã hóa gói tin A thành gói tin B, thì gói tin B sẽ có chiều dài làx + n
, thì n là hằng số.
Cách thức để giao thức ESPTOUCH thực hiện việc gởi thông tin SSID và mật khầu cho thiết bị như sau:
-
ESP8266 sẽ vào chế độ lắng nghe, lần lượt từng kênh.
-
Điện thoại phải kết nối vào mạng WiFi được mã hóa.
-
Ứng dụng trên điện thoại sẽ tiến hành gởi các gói tin với nội dung bất kỳ, nhưng có độ dài
n
theo từng ký tự củaSSID
và mật khẩu. Ví dụ, ssid của mạng làmynetwork
thì sẽ có ký tựm
, với ký tự ascii = 109, Ứng dụng sẽ gởi gói tin có độ dài 109 với nội dung bất kỳ, và lặp lại cho đến hết ký tựk
, cũng như mật khẩu, và các ký tự khác như CRC. -
Có thể giao thức ESPTOUCH sẽ mã hóa cả các thông số gởi đi, nhưng vẫn giữ nguyên tắc như trên.
-
ESP8266 sẽ phát hiện ra các gói tin với độ dài thay đổi này và ghép nối lại thành
SSID
vàpassword
để kêt nối vào mạng. -
Khi ESP8266 kết nối thành công đến mạng, ESP8266 sẽ kết nối đến IP của Điện thoại, được cung cấp thông qua ESPTOUCH, và gởi thông tin kết nối thành công đến ứng dụng trên điện thoại.
Lưu ý:
-
Khoảng cách giữa thiết bị và router càng xa thì thời gian kết nối sẽ càng lâu.
-
Nếu thiết bị không thể kết nối với router trong khoảng thời gian quy định thì ứng dụng sẽ trả về thông báo cấu hình thất bại. Người dùng có thể cài đặt thời gian timeout này thông qua lệnh esptouch_set_timeout(uint8 time_s)
-
Trong quá trình cấu hình kết nối thiết bị bằng SmartConfig, thiết bị phải được cài đặt ở chế độ Station.
-
Người dùng có thể cấu hình cho nhiều thiết bị kết nối chung vào một router cùng lúc.
-
ESP Touch hiện nay hỗ trợ đối với Access Point chuẩn 802.11n 2.4Ghz
Thực hiện SmartConfig với ESP8266
Trong ví dụ dưới đây, chúng ta sẽ tiến hành kết nối wifi cho board ESP8266 bằng SmartConfig. Sử dụng ứng dụng ESP8266 SmartConfig (Android). Bạn có thể dễ dàng tìm thấy ứng dụng này cũng như các ứng dụng tương tự trên Play Store (Android) hay iTunes (iOS) để thực hiện việc kết nối bằng SmartConfig này.
Trước tiên, ta sẽ nạp chương trình cho ESP8266. Điểm mấu chốt trong chương trình này chính là hàm WiFi.beginSmartConfig()
được cung cấp trong thư viện ESP8266WiFi. Hàm này cho phép thiết bị khởi động chế độ SmartConfig, thu thập các thông tin từ các gói tin và giải mã chúng để có thể kết nối vào mạng Wifi.
Sau khi nạp xong chương trình, ta nhấn giữ button (GPIO0) trong 3s để thiết bị đi vào chế độ smartconfig. (Lúc này bạn sẽ thấy led trên board nhấp nháy nhanh hơn). Dùng smart phone của bạn truy cập vào wifi muốn kết nối, sau đó mở ứng dụng smartconfig và nhập các thông tin SSID và PASSWORD (nếu có) của wifi. Nhấn CONFIRM để xác nhận.
Code
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Ticker.h>
#include <time.h>
#define PIN_LED 16
#define PIN_BUTTON 0
#define LED_ON() digitalWrite(PIN_LED, HIGH)
#define LED_OFF() digitalWrite(PIN_LED, LOW)
#define LED_TOGGLE() digitalWrite(PIN_LED, digitalRead(PIN_LED) ^ 0x01)
Ticker ticker;
/* Hàm kiểm tra trạng thái của button*/
bool longPress()
{
static int lastPress = 0;
if (millis() - lastPress > 3000 && digitalRead(PIN_BUTTON) == 0) { // Nếu button được nhấn và giữ trong 3s thì
return true;
} else if (digitalRead(PIN_BUTTON) == 1) { // Nếu button không được nhấn và giữ đủ 3s thì
lastPress = millis(); // gán biến lastPress bằng thời điểm khi gọi hàm
}
return false;
}
void tick()
{
int state = digitalRead(PIN_LED); // Lấy trạng thái hiện tại của LED (GPIO16)
digitalWrite(PIN_LED, !state); // Đảo trạng thái LED.
}
bool in_smartconfig = false; // Biến trạng thái kiểm tra thiết bị có đang trong chế độ smartconfig hay không.
/* Vào chế độ Smartconfig*/
void enter_smartconfig()
{
if (in_smartconfig == false) { // Kiểm tra tra biến trạng thái, nếu không ở chế độ smartconfig thì
in_smartconfig = true; // Gán biến trạng thái bằng "true", nghĩa là đang trong smartconfig
ticker.attach(0.1, tick); // Nhấp nháy led chu kì 0.1s.
WiFi.mode(WIFI_STA); // Thiết lập kết nối cho thiết bị ở chế độ Station mode
WiFi.beginSmartConfig(); // Bắt đầu chế độ smartconfig
Serial.println("Enter smartconfig"); // In thông báo "Enter smartconfig" ra màn hình
}
}
/* Thoát chế độ smartconfig*/
void exit_smart()
{
ticker.detach(); // Ngừng nháy led
LED_ON(); // Bật LED
in_smartconfig = false; // Gán biến trạng thái trở về ban đầu.
Serial.println("Connected, Exit smartconfig"); // In thông báo ra màn hình.
}
/* Cài đặt các thông số ban đầu*/
void setup() {
Serial.begin(115200); // Tốc độ baud = 115200
Serial.setDebugOutput(true); // hiển thị các thông tin debug hệ thống lên màn hình qua serial
pinMode(PIN_LED, OUTPUT); // Cấu hình GPIO cho các chân LED và button
pinMode(PIN_BUTTON, INPUT); // Chớp tắt led chu kì 1s
Serial.println("Setup done"); // In thông báo đã cài đặt xong
}
/* Chương trình chính*/
void loop() {
if (longPress()) { // Gọi hàm longPress kiểm tra trạng thái button
enter_smartconfig(); // Nếu button được nhấn giữ trong 3s thì vào trạng thái smartconfig
}
if (WiFi.status() == WL_CONNECTED && in_smartconfig && WiFi.smartConfigDone()) { //Kiểm tra trạng thái kết nối wifi,
// các thông số cấu hình cũng như trạng thái smartconfig
exit_smart(); // khi thiết bị đã hết nối wifi thành công, thoát chế độ smartconfig
}
if (WiFi.status() == WL_CONNECTED) {
//Chương trình của bạn khi thiết bị đã được kết nối wifi
}
}
Nạp chương trình cho board NodeMCU.
WPS
WPS là gì?
Nếu đã từng cấu hình cho một router wifi, sẽ gặp qua các thuật ngữ WPS trong các menu cấu hình của router. Hoặc từng nhìn thấy một nút nhấn trên các router với chữ viết bên cạnh WPS. Vậy WPS là gì ? Quá trình thực hiện kết nối như thế nào ? Cũng như thực hiện WPS với ESP8266, là những những nội dung sẽ được nói đến ở phần này.
WPS là từ viết tắc của Wifi Protected Setup, một phương thức giúp việc kết nối với mạng không dây giữa router và thiết bị kết nối không dây một cách nhanh chóng và dễ dàng, thay vì làm một cách thủ công: tìm mạng wifi cần kết nối và nhập mật khẩu để vào mạng wifi. WPS chỉ hoạt động khi cả hai thiết bị là router và thiết bị cần kết nối đến router có hổ trợ chuẩn bảo mật cá nhân WPA/WPA2.
WPS có ba chế độ hoạt động : chế độ kết nối với mã PIN, chế độ kết nối bằng nút nhấn, và chế độ kết nối NFC – Near Field Communication (chưa phổ biến). Một trong những chế độ phổ biến và sẽ thực hiện trong phần này là chế độ kết nối bằng nút nhấn.
Ở chế độ kết nối bằng nút nhấn, điều trước tiên cần thực hiện :
-
Nhấn nút WPS trên router, để giúp router vào chế độ bảo mật đặc biệt, ở chế độ này router sẽ cho phép các yêu cầu kết nối đến router từ các thiết bị WPS (các thiết bị có hổ trợ WPS).
-
Tiếp theo là nhấn nút nhấn ở thiết bị WPS. Nút nhấn này giúp thiết bị WPS kết nối đến router, việc kết nối này có thể thất bại nếu quá thời gian. Thời gian này được nhà sản xuất các thiết bị hổ trợ chế độ này quy đinh, khoảng từ 1 phút đến 5 phút.
Thực hiện WPS với ESP8266
ESP8266 hổ trợ hàm WiFi.beginWPSConfig()
trong thư viện ESP8266WiFi. Với hàm này giúp ESP8266 vào chế độ cấu hình với WPS và kết nối đến mạng wifi của router. Ví dụ này ESP8266 sẽ được đưa sẳn vào chế độ WPS, mà không cần thêm nút nhấn nào.
- WPS chỉ có thể thực hiện khi ESP8266 ở chế độ STA (Station) - Router phải ở trong chế độ WPS trước
Code
#include <ESP8266WiFi.h>
void setup()
{
// Cài đặt các thông số ban đầu
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Kết nối với AP cũ đã vào trước đó, SSID và password được lưu trong bộ nhớ flash của thiết bị
WiFi.begin("", "");
delay(4000);
// Kiểm tra xem wifi đã được kết nối chưa, nếu chưa, bắt đầu kết nối bằng WPS
// Lưu ý, cần phải đảm bảo rằng Router của bạn đang ở trong trạng thái WPS.
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("\nAttempting connection ...");
WiFi.beginWPSConfig();
delay(6000);
}
// Khi kết nối thành công, in thông báo ra màn hình cùng với các thông số của Wifi vừa kết nối.
Serial.println("\nConnection already established.");
Serial.println(WiFi.localIP());
Serial.println(WiFi.SSID());
Serial.println(WiFi.macAddress());
}
void loop()
{
// chương trình chính
}
Nạp chương trình cho board NodeMCU.
Wifi Manager
WifiManager là một thư viện cấu hình ESP8266 kết nối vào mạng WiFi cục bộ sử dụng giao diện Web. Bằng cách khởi động 1 mạng WiFi riêng với Captive Portal, ESP8266 sẽ cho phép các thiết bị khác như máy tính, điện thoại thông minh kết nối vào, đồng thời chuyển hướng mọi kết nối đến giao diện Web do ESP8266 tạo nên. Trên giao diện này, sẽ cung cấp các trường để người dùng có thể dễ dàng quét mạng xung quanh, chọn mạng WiFi, nhập mật khẩu, lưu cấu hình.
Hoạt động cơ bản WifiManager
-
Khi ESP8266 khởi động, ESP8266 sẽ vào chế độ STATION và sẽ tự động kết nối đến một Access Point với các thông tin kết nối đã được lưu vào ESP8266 ở lần kết nối thành công trước đó.
-
Nếu như kết nối không thành công (có thể là Access Point lần trước không còn nữa, hay sai mật khẩu, hoặc chưa có thông tin của bất cứ Access Point nào trong ESP8266 ), lúc này ESP8266 sẽ vào chế độ AP với một DNS trỏ về chính nó (có thể thiết lập DNS trỏ về địa chỉ khác) và khởi động Web Server (với địa chỉ mặc định là 192.168.4.1)
-
Sử dụng các thiết bị có hổ trợ wifi, và có trình duyệt web (điện thoại thông minh, laptop, máy tính bảng…) để kết nối đến AP của ESP8266 vừa mới tạo ra. Có thể thấy một giao diện (với tên AP của ESP8266 là mặc định và không cài đặt mật khẩu cho ESP8266 AP) tương tự như sau :
-
Sau khi vào được giao diện option của ESP8266 AP ở địa chỉ 192.168.4.1, chọn mục cấu hình cho wifi cho ESP8266 (như ví dụ trên là Configure WiFi hoặc Configure WiFi (No Scan)), có thể sẽ thấy giao diện tiếp theo tương tự như sau :
-
Chọn mạng wifi cần kết nối và nhập mật khẩu để vào wifi.
-
Nếu ESP8266 kết nối thành công, ta sẽ không thấy tên của ESP8266 AP nữa. Nếu chưa thành công thì chỉ cần kết nối lại ESP8266 AP và cấu hình lại.
Chuẩn bị
-
Cài đặt thư viện: github.com/tzapu/WiFiManager
Code
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//các thư viện cần thiết
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "WiFiManager.h" //https://github.com/tzapu/WiFiManager
void configModeCallback (WiFiManager *myWiFiManager)
{
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
Serial.println(myWiFiManager->getConfigPortalSSID());
}
// Cài đặt thông số ban đầu
void setup()
{
Serial.begin(115200);
//Khai báo wifiManager thuộc class WiFiManager, được quy định trong file WiFiManager.h
WiFiManager wifiManager;
//có thểreset các cài đặt cũ bằng cách gọi hàm:
//wifiManager.resetSettings();
//Cài đặt callback, khi kết nối với wifi cũ thất bại, thiết bị sẽ gọi hàm callback
//và khởi động chế độ AP với SSID được cài tự động là "ESP+chipID"
wifiManager.setAPCallback(configModeCallback);
if (!wifiManager.autoConnect())
{
Serial.println("failed to connect and hit timeout");
//Nếu kết nối thất bại, thử kết nối lại bằng cách reset thiết bị
ESP.reset();
delay(1000);
}
//Nếu kết nối wifi thành công, in thông báo ra màn hình
Serial.println("connected...yeey :)");
}
void loop()
{
// Chương trình chính
}
Nạp chương trình cho board NodeMCU.
Mở rộng
Ngoài các chế độ cơ bản, thì thư viện WiFiManager còn nhiều tính năng hữu ích khác như startConfigPortal
để khởi động cấu hình khi cần (ví dụ nhấn nút để cấu hình), bổ sung các trường tùy chọn trên giao diện Web, tùy chọn lại giao diện …
Các thông tin API và ví dụ bạn có thể dễ dàng tìm thấy tại github.com/tzapu/WiFiManager
Tổng kết
Để triển khai một ứng dụng IoT thực tế thì đòi hỏi rất nhiều vấn đề, một trong số những điều quan trọng là dễ dùng, dễ cấu hình cho người sử dụng và phải bảo mật trong quá trình cung cấp thông tin cho thiết bị. Tùy thuộc vào nhu cầu phát triển sản phẩm và tính năng của sản phẩm mà bạn có thể lựa chọn cho mình phương pháp cấu hình phù hợp. Ví dụ, nếu thiết bị có nút nhấn và có phần mềm trên điện thoại, thì SmartConfig và WPS là một sự lựa chọn. Nếu là 1 bóng đèn trống trơn không có gì cả, thì WiFiManager lại hữu hiệu.