Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino.Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google AssistantDự án 3 Giải mã dữ liệu thời tiết qua cấu trúc JSON trong ArduinoDự án 4 WiFiManager cho ESP8266 – tự động kết nối, cấu hình, quản lý SSID và Password
Trang 1Bốn dự án ứng dụng lập trình IOT với
ESP8266 trong Arduino
Trang 2Mục lục
Giới thiệu 3
Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino 3
Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307 10
Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google Assistant 31
Dự án 3 - Giải mã dữ liệu thời tiết qua cấu trúc JSON trong Arduino 38
Dự án 4 - WiFiManager cho ESP8266 – tự động kết nối, cấu hình, quản lý SSID và Password 53
Trang 3Giới thiệu
ESP8266 tương đối phổ thông ở Việt Nam và chi phí cũng không quá cao Trong tài liệu này, tôi giới thiệu các dự án tôi đã lập trình với ESP8266 cho các bạn tham khảo Công cụ dùng để lập trình là Arduino IDE
Chuẩn bị: Cài đặt ESP8266 để lập trình trong Arduino
NodeMCU là bo mạch khai thác khả năng của chip esp8266 Nó kết hợp các chức năng của WIFI, vi xử lý
và ngôn ngữ LUA ESP8266 NodeMCU cung cấp
Giống các chân IO phần cứng Arduino
API điền khiển sự kiện cho các ứng dụng mạng
10 chân GPIO từ D0 – D10, có chức năng PWM, IIC, giao tiếp SPI, 1-Wire và ADC trên chân A0
Kết nối mạng wifi (có thể là sử dụng như điểm truy cập và/hoặc trạm máy chủ lưu trữ một, máy chủ web), kết nối internet để lấy hoặc tải lên dữ liệu
Chi phí phù hợp cho các dự án Internet of Things (IoT)
PHẦN CỨNG
Module ESP8266
Trang 41) Cài Arduino dành cho chip ESP8266 WiFi trong Arduino IDE và xem các bài code mẫu trong đó 2) Chạy và chỉnh sửa các bài code mẫu để kiểm tra các chân D0 , GPIO-16 cũng như các chân cấu hình
Ghi chú – để sử dụng bo mạch NodeMCU V1 hoặc V2 hoặc V3 trong Arduino IDE, bạn không cần chép firmware với công cụ using nodemcu flasher Nó chỉ yêu cầu khi sử dụng ngôn ngữ LUA
Bạn có thể theo dõi video hướng dẫn chép firware sau:
Bước 1: Lập sơ đồ chân của NodeMCU ESP-12E
* Chip ESP8266 sử dụng điện áp 3.3V , bạn có thể lấy mức điện áp từ trên bo Arduino
* NodeMCU ESP-12E có thể nối với nguồn 5V sử dụng cáp micro USB hoặc chân Vin có sẵn trên bo
* Các chân ESP8266 chỉ sử dụng điện áp 3.3V , không sử dụng điện áp 5V tại các chân ngõ vào Khi sử dụng với các chân I/O 5V, bạn cần sử dụng mạch chuyển đổi từ 5V sang 3.3V
Tải : source of images
Trang 5Bước 2: cài đặt chương trình lõi Arduino cho NodeMCU ESP-12E dùng chương trình quản lý bo
Arduino
Chép đường link sau từ trang Github
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Trang 6Dán link vào Arduino IDE trong File -> Preferences-
Đóng và khởi động lại Arduino IDE
Bước 3 : Tools – Boards Manager
Vào Tools – Boards manager và tìm ESP8266 và cài đặt thư viện có tiêu đề ESP8266 by ESP community
Trang 7Khởi động Arduino IDE lại lần nữa
Bước 4: chọn NodeMCU Board trong Arduino IDE
Vào Tools – Boards kéo xuống cuối danh sách chọn NodeMCU 1.0 ( ESP-12EModule)
Trang 8Chọn tên Port đã kết nối tới nodeMCU, phần còn lại để mặc định
Bước 5: LED Blink – kết nối với led bên ngoài
Chúng ra sẽ nối LED trực tiếp vào chân GPIO16 hoặc D0 của NodeMCU (không cần điện trở hạn dòng)
Bước 6: chạy ví dụ LED Blink
Vào File – Examples – ESP8266 – Blink
Trang 9Trong video tôi đã sửa lại để LED nháy nhanh hơn, nhưng bạn có thể bỏ qua và up mã nguồn vào ESP xem kết quả
Ghi chú: Nếu bản Arduino IDE 1.6.7 bị lỗi bạn hãy trở lại bản arduino 1.6.5
Trang 10Dự án 1: Lập trình đồng hồ LED 7 đoạn dùng ESP8266 và DS1307
Trên thị trường có bán sẵn đồng hồ LED 7 đoạn dùng chip thời gian thực, nhưng kích thước các đồng hồ
đó đa số đều nhỏ Trong dự án này, tôi làm 1 đồng hồ dùng LED 7 đoạn loại lớn để hiển thị thời gian Điểm đặc thù của đồng hồ là dùng chip wifi ESP8266 để tự động cập nhật thời gian từ internet, sau đó lưu thông tin thời gian vào DS1307 và hiển thị lên LED 7 đoạn
Ưu điểm
Cập nhật thời gian thực từ Internet
Loại bỏ các phím nhấn vật lý
Linh kiện phần cứng
1 LED 7 đoạn loại lớn sử dụng nguồn dương chung
2 Module wifi ESP8266 nodeMCU
3 Module đồng hồ thời gian thực DS1307 hoặc tương đương
4 Pin CMOS dùng cho module đồng hồ
Trang 11Module giảm áp DC dùng hiển thị
Sơ đồ khối hiển thị
Tôi tự quy ước các chân của LED 7 đoạn, theo quy ước thì chúng ta sẽ không sử dụng chân số 3 và chân
số 6 Trước khi bạn sử dụng LED 7 đoạn, bạn cần kiểm tra các phân đoạn có giống trong hình tôi mô tả hay không, nếu không bạn hãy tự vẽ lại thứ tự các phân đoạn theo LED thực tế
Chúng ta sẽ kết nối 4 LED 7 đoạn lại với nhau, các phân đoạn sẽ được nối song song với nhau, các đoạn
từ A đến G sẽ kết nối với nhau thành từng dây dẫn điện riêng cho mỗi đoạn Các chân nguồn của LED 7 đoạn sẽ được nối vào chân C của transistor A1015 Chân B của A1015 nối với điện trở 1K hoặc 10K dùng cho chân tín hiệu từ 74HC595 Chân E của A1015 dùng cấp nguồn cho LED 7 đoạn
Như vậy chúng ta có 11 đường tín hiệu trên khối LED 7 đoạn gồm 7 đường tín hiệu phân đoạn và 4 đường điều khiển tắt mở các LED, chúng ta có 1 ma trận 7X4 dùng để hiển thị thông tin
Trang 12Sơ đồ kết nối 4 LED 7 đoạn thành ma trận 7x4 Đường màu đỏ chính là chân số 10 trên LED 7 đoạn
Trang 14Sơ đồ kết nối LED 7 đoạn với 74HC595
Theo thiết kế IC1 sẽ điều khiển 7 đường dữ liệu hiển thị số và IC2 sẽ tắt mở 1 trong 4 LED, như vậy trong
1 thời gian chỉ có 1 LED 7 đoạn được hiển thị, do chạy với tốc độ cao bạn sẽ thấy cả 4 LED hiển thị cùng lúc
Theo sơ đồ thiết kế dưới thì dữ liệu hiển thị LED 7 đoạn xuất trước rồi mới tới dữ liệu tắt mở 1 trong 4 led 7 đoạn Nếu trong quá trình thi công thứ tự 2 IC bị đảo lại khi lập trình cũng phải đảo lại thứ tự xuất
dữ liệu ra IC 74HC595
Trang 16Sơ đồ IC đồng hồ DS1307
Sơ đồ kết nối DS1307 – ESP8266 – 74HC595
Trang 17Vấn đề cấp nguồn
Do các LED 7 đoạn chạy điện áp tối đa là 4.3V, dư
dụng module hạ áp DC Mini để điều ch
cũng làm nguồn cung cấp cho module ESP8266
Lấy mức điện áp 3.3V trên module ESP8266 đ
ESP8366 chỉ nên sử dụng ở mức 3.3V và c
chỉ sáng ở mức 1.8V, cần sử dụng thêm đi
nháy giây này
Lập trình hiển thị LED 7 đoạn
//Pin connected to latch pin (ST_CP) of 74HC595
#define LATCH_PIN 15 //D8
//Pin connected to clock pin (SH_CP) of 74HC595
#define CLOCK_PIN 14 //pin D5
i đa là 4.3V, dưới mức này, LED có thể sẽ không sáng nên ta c
u chỉnh điện áp cho nó để đảm bảo LED sử dụng lâu b
p cho module ESP8266
n áp 3.3V trên module ESP8266 để cung cấp cho module DS1307 vì các tín hi
c 3.3V và cũng lấy mức điện áp này cung cấp cho LED báo giây vì LED
ng thêm điện trở 330ohm tại chân dương của LED để hạ
latch pin (ST_CP) of 74HC595
//Pin connected to clock pin (SH_CP) of 74HC595
g nên ta cần sử
ng lâu bền, đồng thời
p cho module DS1307 vì các tín hiệu xuất cho
p cho LED báo giây vì LED đỏ
ạn dòng cho LED
Trang 18//Pin connected to Data in (DS) of 74HC5
#define DATA_PIN 13 //pin D7
#define SDA_PIN 5
#define SCL_PIN 4
//Các biến lưu dữ liệu
byte numbers[10]; //biến lưu giá trị từ 0 đến 9
byte selectNumber[4]; // biến lưu giá trị tắt mở các LED từ 0 đến 3
Trang 19displayNumber[0] = numbers[minute % 10];
for (int j = 0; j < 4; j++) {
//ground latchPin and hold low for as long as you are transmitting digitalWrite(LATCH_PIN, 0);
shiftOut(DATA_PIN, CLOCK_PIN, selectNumber[j]);
shiftOut(DATA_PIN, CLOCK_PIN, displayNumber[j]);
digitalWrite(LATCH_PIN, 1);
delay(5);
}
}
// viết lại hàm shiftOut thay cho hàm của Arduino
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i = 0;
int pinState;
Trang 20pinState = myDataOut & (1 << i) ? 1 : 0;
//Sets the pin to HIGH or LOW depending on pinState
Lập trình hiển thị đồng hồ và cập nhật thời gian từ Internet
Trong mã nguồn, sử dụng thư viện Time để xử lý thông tin thời gian Xem trong mã nguồn đính kèm tài liệu này
Múi giờ của Việt Nam là 7
Địa chỉ của chip đồng hồ là 0x68
#include <Wire.h>
#include <ESP8266WiFi.h>
Trang 21#include <WiFiUdp.h>
#include <TimeLib.h>
//Pin connected to latch pin (ST_CP) of 74HC595
#define LATCH_PIN 15 //D8
//Pin connected to clock pin (SH_CP) of 74HC595
#define CLOCK_PIN 14 //pin D5
////Pin connected to Data in (DS) of 74HC5
#define DATA_PIN 13 //pin D7
#define SDA_PIN 5
#define SCL_PIN 4
#define DS1307 0x68
#define WLAN_SSID "ten_mang"
#define WLAN_PASS "password_mang_wifi"
// khai báo các biến và mảng lưu giá trị thời gian
int my_second, my_minute, my_hour, my_day, my_wday, my_month, my_year; byte numbers[10];
byte selectNumber[4];
byte displayNumber[4];
unsigned int localPort = 2390; // local port to listen for UDP packets
// A UDP instance to let us send and receive packets over UDP
static const char ntpServerName[] = "time.nist.gov";
const int timeZone = 7;
/* Số byte dữ liệu sẽ đọc từ DS1307 */
const byte NumberOfFields = 7;
Trang 22const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
WiFiUDP Udp;
time_t getNtpTime();
//khai báo các hàm, trong các phiên bản mới hơn của Arduino có thể bỏ qua bước này
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
Trang 23WiFi.begin (WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
Trang 24for (int j = 0; j < 4; j++) {
digitalWrite(LATCH_PIN, 0);
shiftOut(DATA_PIN, CLOCK_PIN, displayNumber[j]); shiftOut(DATA_PIN, CLOCK_PIN, selectNumber[j]); digitalWrite(LATCH_PIN, 1);
Trang 25while (Udp.parsePacket() > 0) ; // discard any previously received packets Serial.println("Transmit NTP Request");
// get a random server from the pool
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; }
}
Serial.println("No NTP Response :-(");
Trang 26return 0; // return 0 if unable to get the time
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
Trang 28int bcd2dec(byte num)
{
return ((num / 16 * 10) + (num % 16));
}
/* Chuyển từ Decimal sang BCD */
int dec2bcd(byte num)
{
return ((num / 10 * 16) + (num % 10));
}
/* cài đặt thời gian cho DS1307 */
void setTime(byte hr, byte min, byte sec, byte wd, byte d, byte mth, byte yr) {
Trang 29void printDigits(int digits) {
// các thành phần thời gian được ngăn chách bằng dấu : Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
// viết lại hàm shiftOut thay cho hàm của Arduino
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { int i = 0;
int pinState;
Trang 30pinState = myDataOut & (1 << i) ? 1 : 0;
//Sets the pin to HIGH or LOW depending on pinState
Trong trường hợp SCL và SDA không thể kết nối được bạn hãy đảo chân 2 chân này
Quá trình cập nhật thời gian đôi khi không thể cập nhật được và có hiện tượng hiển thị sai hoặc hiển thị
4 số 0 Bạn hãy reset chip ESP8266 vài lần
Trang 31Thứ tự 2 IC 74HC595 dùng trong việc truyền dữ liệu và điều khiển tắt mở các đèn LED 7 đoạn khác nhau thì thứ tự truyền trong phần mềm cũng cần điều chỉnh lại thì mới hiển thị được
Dự án 2: Điều khiển ESP8266 bằng giọng nói với Google Assistant
Genk.vn từng có bài giới thiệu giải pháp điều khiển bằng giọng nói sử dụng Raspberry Pi kết hợp với Google Home, hoặc điện thoại Tuy nhiên, sử dụng Raspberry Pi vẫn chưa thực sự kinh tế, nó chỉ phù hợp để làm server điểu khiển nhiều thiết bị Nếu chỉ điều khiển 1 thiết bị hoặc điều khiển nhiều lỗ cắm điện trên cùng một hệ thống thì sử dụng chip ESP8266 kinh tế hơn
Trong bài hướng dẫn này, tôi hướng dẫn các bước căn bản để điều khiển module ESP8266 bằng giọng nói với sự giúp đỡ của Google Assistant, dịch vụ IFTTT, và Adafruit IO Tôi điều khiển ESP8266 để tắt hoặc mở 2 rờ le, tích hợp chúng vào ổ cắm điện với chi phí khoảng 200 ngàn
Linh kiện:
1 Module ESP8266 (ESP-12E)
2 Rờ le loại điều khiển bằng điện áp 5V
3 Nguồn điện 5V, dây nguồn và một số thứ khác
4 Ổ cắm điện
Trang 32Phần mềm
Cài app Google Assistant lên điện tho
Đăng ký dịch vụ trực tuyến
Để điều khiển được ESP8266, bạn c
Dịch vụ adafruit, bạn chọn đăng ký gói mi
Đăng ký dịch IFTT tại link https://platform.ifttt.com/
với tài khoản IFTTT
Bước 1: Cài đặt Adafruit IO
Adafruit IO là nền tảng IOT xây dựng d
Đây là một giao thức truyền thông đi
sử dụng băng thông thấp, độ tin cậy cao và có kh
ổn định
Trong Adafruit IO, sau khi đã tạo tài kho
bên trái màn hình Chọn Actions từ
Tiếp theo, vào Dashboards, menu bên trái Ch
mới (dashboard), đặt tên là "LightSwitch" M
tượng dấu cộng (+) màu xanh sẽ cho b
Khi được nhắc chọn 1 feed, bạn chọ
định
Tới đây là kết thúc mọi việc với Adafruit IO Ti
n thoại (Có sẵn trên chợ ứng dụng Android và iPhone)
n cần đăng ký tài khoản ở 2 dịch vụ trực tuyến:
n đăng ký gói miễn phí Đăng ký tại link : https://io.adafruit.com
atform.ifttt.com/ Bạn phải dùng tài khoản Google Assistant chung
ng dựa theo giao thức Message Queue Telemetry Transport
n thông điệp (message) theo mô hình publish/subscribe (xuấ
y cao và có khả năng hoạt động trong điều kiện đườ
o tài khoản tại Adafruit IO, bạn trở lại trang home, chọn menu "Feeds" menu sổ xuống và tạo 1 feed mới gọi là "onoff"
Dashboards, menu bên trái Chọn mục Actions từ menu sổ, vào tạo một b
t tên là "LightSwitch" Mở bảng theo dõi mới, bắt đầu với 1 trang tr
cho bạn tạo mới linh kiện Bây giờ, chúng ta sẽ tạo 1 nút nh
ọn feed đã tạo trước đó, và tất cả những thứ còn lại đAdafruit IO Tiếp theo kết nối ESP8266 tới MQTTBroker
ng Android và iPhone)
https://io.adafruit.com
n Google Assistant chung
Message Queue Telemetry Transport (MQTT)
ất bản – theo dõi), ờng truyền không
Trang 34Kết nối ESP8266
Trước khi lập trình, bạn sẽ cần cài đ
của Arduino (Sketch > Include Library > Library Manage
Client” và cài vào chương trình
Mở code mẫu từ trong ví dụ Adafruit MQTT Client/mqtt_esp8266.ino.
Có 3 thư viện bạn cần trong chương tr
n cài đặt thư viện Adafruit MQTT Client, vào mục quản lý th
Sketch > Include Library > Library Manager ) Tìm thư viện với từ khóa “
Trang 35Cấu hình tài khoản mạng wifi nhà bạn
#define WIFI_SSID "<Tên Wifi nhà bạn>"
#define WIFI_PASS "<Mật khẩu wifi nhà bạn>"
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "<Tên đăng nhập tại Adafruit IO >"
#define AIO_KEY "<Mã IO Key trên Adafruit IO>"
Những khai báo này dùng kết nối tới tài khoản Adafruit IO Khóa Adafruit IO là chuỗi ký tự bạn có thể tìm thấy bằng cách nhấn vào menu "View AIO Key" bên trái của Adafruit IO
Tiếp theo, tạo đối tượng WiFiClient và Adafruit_MQTT_Client như là các biến toàn cục:
// Setup a feed called 'onoff' for subscribing to changes
Trang 36// Setup MQTT subscription for onoff feed
pinMode(D1, OUTPUT); //khai báo ngõ ra cho relay
digitalWrite(D1, HIGH); //tắt relay
}
Kết nối với Google Assistant thông qua IFTTT
Bước cuối cùng, chúng ta sẽ kết nối Google Assistant tới Adafruit IO MQTT Broker để điều khiển tắt mở bằng giọng nói Chúng ta sử dụng nền tảng IFTTT (If This Then That) có hàng trăm dịch vụ khác nhau
Địa chỉ truy cập https://ifttt.com/my_applets Chọn nút "New Applet" để tạo Applet điều khiển bằng giọng nói Chọn ("If This") để cài đặt khẩu lệnh và chọn ("Then That") để chọn feed đã tạo trước đó Mỗi Applet chỉ phục vụ cho 1 khẩu lệnh, nên bạn có 2 lệnh tắt, mở thiết bị thì bạn cần tạo 2 applet
Trong "Google Assistant" chọn "Say a simple phrase" để cài đặt câu lệnh ví dụ như "Turn the light on,"
"Turn on the light," và "Switch the light on" Hiện tại Google Assistant chưa hỗ trợ tiếng Việt, nên bạn chỉ
có thể sử dụng tiếng Anh
Phần cuối của applet là Action, phản hồi tới Trigger Trong phần dịch vụ chọn "Adafruit", và xác định điều khiển Action, chọn "Send data to Adafruit IO" Chọn Adafruit IO feed bạn sẽ gửi dữ liệu, trong trường hợp này là "onoff" Nhập dữ liệu sẽ gửi, ví dụ "ON", dữ liệu này sẽ được gửi tới chip ESP8266 trong khoảng 1 giây Tương tự, bạn tạo thêm applet để gửi lệnh "OFF" tới ESP8266
Chạy thử
Nếu không có Google Home, bạn có thể sử dụng điện thoại cài app Google Assistant Mở app và đọc khẩu lệnh như đã tạo trong các applet Phần mềm sẽ tìm kiếm và trả về lệnh theo như đã khai báo ở trên Nếu mọi thứ đã suôn sẻ, thiết bị của bạn sẽ hoạt động như ý bạn mong muốn
Các vấn đề gặp phải
Trang 37Có những nơi bạn điều khiển bằng giọng nói không được, thì bạn cần kiểm tra một vài thứ
Trạng thái tắt mở có thể hiện trên bảng điều khiển Adafruit IO không? Nếu không, ESP8266 chưa kết nối tới máy chủ, các feed Kiểm tra ESP8266 trên Serial Monitor
Google Assistant dịch có chính xác những gì bạn nói không ?
Google Assistant có trả lại dữ liệu không? Nếu không, bạn cần kiểm tra tài khoản Google và tài khoản IFTTT có cùng 1 tài khoản hay không
Bảng điều khiển Adafruit IO không cập nhật các applet IFTTT? Nếu không, kiểm tra tài khoản Adafruit IO
và tài khoản IFTTT có kết nối không