[IoT] Bài 5: Tạo WebServer Với ESP8266 Và Lập Trình Cho Esp8266 ...

Trong bài này, chúng ta sẽ tạo webserver với esp8266 và biến esp8266 thành một máy chủ web để điện thoại, máy tính truy cập tới ! Chúng ta đã quen với việc điều khiển esp8266 qua các lệnh AT command, tuy nhiên các lệnh AT command không phát huy được hết hoàn toàn khả năng của esp8266. Bản thân esp8266 hỗ trợ lập trình trực tiếp như 1 con vi điều khiển, trong bài này, mình sẽ hướng dẫn các bạn tạo web server cho esp8266

Arduino IDE là một môi trường lập trình với hệ thống thư viện đồ sộ, công đồng cực kì lớn mạnh ! Và đương nhiên Arduino IDE cũng hỗ trợ chúng ta lập trình cho esp8266, ngoài arduino ide còn rất nhiều môi trường khác nữa để lập trình cho esp8266, tuy nhiên cộng đồng và thư viện của nó không được mạnh. Do đó, mình sẽ chọn Arduino IDE để viết code

Về việc cài dặt arduino IDE, các bạn tham khảo trên google nhé vì nó quá cơ bản rồi. Sau khi cài xong, chúng ta tích hợp thư viện esp8266 để vào arduino ide như sau: (phần này mình tham khảo tại đây)

Vào File→ Preferences, vào textbox Additional Board Manager URLs thêm đường link này vào:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

cài đặt thư viện esp8266 cho arduino

Click OK để chấp nhận

Tiếp theo vào ToolBoardBoards Manager

cài đặt thư viện esp8266 cho arduino

Đợi một lát để chương trình tìm kiếm. Ta kéo xuống và click vào ESP8266 by ESP8266 Community, click vào Install. Chờ phần mềm tự động download và cài đặt.

cài đặt thư viện esp8266 cho arduino

Chọn Board để lập trình cho ESP8266:

Kết nối mudule USB-to-UART vào máy tính. Vào ToolBoardGeneric ESP8266 Module, chọn cổng COM tương ứng với module USB-to-UART tương ứng.

cài đặt thư viện esp8266 cho arduino

Chọn chế độ nạp Arduino as ISP. Vậy là ta đã có môi trường lập trình cho esp8266 rất thân thiện.

Thiết kế webserver

Ngôn ngữ HTML

HTML là chữ viết tắt của Hypertext Markup Language. Nó giúp người dùng tạo và cấu trúc các thành phần trong trang web hoặc ứng dụng, phân chia các đoạn văn, heading, links, blockquotes …

Khi làm việc với HTML, chúng ta sẽ sử dụng cấu trúc code đơn giản (tags và attributes) để đánh dấu lên trang web. Ví dụ, chúng ta có thể tạo một đoạn văn bằng cách đặt văn bản vào trong cặp tag mở và đóng văn bản <p></p>

Các bạn tự tìm hiểu thêm nhé,

  • https://thachpham.com/web-development/html-css/html-la-gi-va-vi-sao-no-quan-trong.html
  • https://www.hostinger.vn/huong-dan/html-la-gi/
  • https://vi.wikipedia.org/wiki/HTML
  • https://wiki.matbao.net/kb/html-la-gi-nen-tang-lap-trinh-web-cho-nguoi-moi-bat-dau/

Trước khi đi vào lập trình, chúng ta sẽ viết mã html cho server web bằng máy tính trước, giới thiệu với các bạn phần mềm Sublime Text đây là 1 công cụ text editer mà mình rất thích, giao diện đẹp, chuyên nghiệp, hệ thống nhắc lệnh rất ok ! Mình sẽ viết demo mã html trên phần mềm này !

Các bạn vào File -> New tạo 1 file mới và lưu với đuôi .html, ở đây mình lưu file với tên index.html

Tiến hành viết mã code html

C <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Điều khiển thiết bị</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;} .t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;} </style> </head> <body> <div style="width: 330px;height: auto;margin: 0 auto;margin-top: 70px"> <h1 align="center">Điều khiển thiết bị qua WIFI</h1> <table align="center"> <tr> <td><a href='/bat1'><button class='b'>Bật 1</button></a><td> <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td> <tr> <tr> <td><a href='/bat2'><button class='b'>Bật 2</button></a><td> <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td> <tr> <tr> <td><a href='/bat3'><button class='b'>Bật 3</button></a><td> <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td> <tr> <tr> <td><a href='/bat4'><button class='b'>Bật 4</button></a><td> <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td> <tr> </table> </div> </body> </html>
1234567891011121314151617181920212223242526272829303132333435 <!DOCTYPE html><html><head><meta http-equiv="Content-Type"content="text/html; charset=utf-8"><title>Điukhinthiếtb</title><meta name="viewport"content="width=device-width, initial-scale=1"><style>.b{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#4caf50;border-radius:10px;}.t{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#f44336;border-radius:10px;}</style></head><body><div style="width: 330px;height: auto;margin: 0 auto;margin-top: 70px"><h1 align="center">Điukhinthiếtbqua WIFI</h1><table align="center"><tr><td><ahref='/bat1'><button class='b'>Bt1</button></a><td><td><ahref='/tat1'><button class='t'>Tt1</button></a><td><tr><tr><td><ahref='/bat2'><button class='b'>Bt2</button></a><td><td><ahref='/tat2'><button class='t'>Tt2</button></a><td><tr><tr><td><ahref='/bat3'><button class='b'>Bt3</button></a><td><td><ahref='/tat3'><button class='t'>Tt3</button></a><td><tr><tr><td><ahref='/bat4'><button class='b'>Bt4</button></a><td><td><ahref='/tat4'><button class='t'>Tt4</button></a><td><tr></table></div></body></html>

Sau đó lưu lại và mở file đó lên bằng trình duyệt WEB nhé, ở đây mình dùng Chrome

Và đây là kết quả:

webserver với esp8266

Giải thích:

Cấu trúc của 1 file html như sau:

C <!DOCTYPE html> <html> <head> <title></title> </head> <body> </body> </html>
123456789 <!DOCTYPE html><html><head><title></title></head><body> </body></html>

<!DOCTYPE html> là tiêu đề bắt buộc mở đầu file

Cặp thẻ <html> </html> cũng là cặp thẻ bắt buộc. Tiếp đến là cặp thẻ <head> </head> nơi chứa nhưng khai báo mở dầu của trang, ví dụ thêm thư viện, …Thẻ <title> </title> chính là phân nội dung in trên tab của trinh duyệt web (cạnh favicon)Và cặp thẻ <body> </body> nơi chứa nội dung của trang web

Tiếp đến

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″> khai báo định dạng text – kiểu utf-8<title>Điều khiển thiết bị</title> Khai báo phần title trên tab của trình duyệt web<meta name=”viewport” content=”width=device-width, initial-scale=1″> đây là đoạn mã để trình duyệt web tự động căn chỉnh trang cho vừa nhìn với màn hình (để vừa đẹp với cả điện thoại lẫn máy tính)<style>.b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;}.t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;}</style>Trong cặp thẻ style mình khai báo 2 class “b” và “t” và viết các thuộc tính như chiều dài, chiều rộng, màu sắc cho nút nhấnVà ở phần thẻ body chính là nội dung chính của trang web với các button

Sau khi đã biên tập file html xong, chúng ta tiến hành viết code trên arduino và nhúng mã html vào esp8266

Server web ở chế độ Access Point

Ở chế độ Access Point, mình sẽ cho wifi tự thân phát ra wifi để các thiết bị khác kết nối tới

C #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> ESP8266WebServer server(80); String webPage = { "<!DOCTYPE html>" "<html>" "<head>" " <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" " <title>Điều khiển thiết bị</title>" " <meta name='viewport' content='width=device-width, initial-scale=1'>" " <style>" " .b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;}" " .t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;}" " </style>" "</head>" "<body>" "<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>" "<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>" " <table align='center'>" " <tr>" " <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>" " <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>" " <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>" " <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>" " <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>" " <tr>" " </table>" "</div>" "</body>" "</html>" }; void TrangChu() { server.send(200, "text/html", webPage); } void setup() { Serial.begin(9600); while (WiFi.softAP("ESP8266 WiFI", "12345678") == false) { Serial.print("."); delay(300); } IPAddress myIP = WiFi.softAPIP(); server.on("/", TrangChu); server.begin(); } void loop() { server.handleClient(); }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 #include <ESP8266WiFi.h>#include <ESP8266WebServer.h>#include <ESP8266mDNS.h> ESP8266WebServer server(80); StringwebPage={"<!DOCTYPE html>""<html>""<head>"" <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"" <title>Điều khiển thiết bị</title>"" <meta name='viewport' content='width=device-width, initial-scale=1'>"" <style>" ".b{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#4caf50;border-radius:10px;}" ".t{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#f44336;border-radius:10px;}" "</style>""</head>""<body>""<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>""<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>"" <table align='center'>"" <tr>"" <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>"" <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>"" <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>"" <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>"" <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>"" <tr>"" </table>""</div>""</body>""</html>"};voidTrangChu(){server.send(200,"text/html",webPage);}voidsetup(){Serial.begin(9600);while(WiFi.softAP("ESP8266 WiFI","12345678")==false){Serial.print(".");delay(300);}IPAddress myIP=WiFi.softAPIP();server.on("/",TrangChu);server.begin();}voidloop(){server.handleClient();}

Sau khi include các file thư viện cần thiết, ở dòng số 3, mình khởi tạo 1 đối tượng server hoạt động ở cổng 80.Tiếp đến nhúng toàn bộ đoạn code web đã viết vài biến String webPage

Lưu ý: Ở đầu và cuối mỗi dòng chúng ta nhé thêm 1 dấu nháy đôi và tất cả các dấu nháy đôi phía trong phải sửa thành dấu nháy đơn

Bạn cũng có thể thêm dấu xổ \ trước nháy đôi thay vì sửa thành nháy đơn

Trong hàm setup chúng ta khởi tạo cổng serial với tốc độ baud 9600 và cho esp8266 phát ra wifi với tên ESP8266 WiFI và password 12345678

Hàm server.on(“/”, TrangChu); yêu cầu esp tạo ra 1 callback tới hàm tên là TrangChu khi có thiết bị truy cập tới, và ở hàm TrangChu , mình sẽ cho esp8266 trả lời lại mã html với code reponse là 200 (http code 200 báo truy vấn thành công – mình đã nói ở bài 4 )

Nạp chương trình:

Cách nạp chương trình giống như nạp firmwave mà mình đã hướng dẫn ở bài 2. Tuy nhiên chúng ta sẽ nạp trực tiếp bằng phần mềm arduino luôn !

Các bạn chuẩn bị 1 module UART-USB như pl2303, hc340 rồi kết nối như sau:

ESP8266PL2303 (hoặc module uart bất kì)
3.3V3.3V
GNDGND
RXTX
TXRX
CH_PD3.3V
GPIO0GND

Sau khi kết nối như trên xong thì chúng ta mới cắm module uart vào máy tính

Các bạn vào Tool -> Port để chọn cổng COM tương ứng:

tạo webserver esp8266

Sau đó ấn nút nạp xuống:

tạo webserver esp8266

Sau khi nạp code xong thì gỡ GPIO0 ra khỏi mass và reset esp8266 (cấp lại nguồn hoặc kích GND vào chân reset)

Bây giờ lấy máy tính ra, cho nó kết nối vào wifi ESP8266 WiFI với mật khẩu 12345678Sau đó mở trình duyệt gõ địa chỉ mặc định của server là 192.168.4.1

Chún ta có kết quả

tạo webserver esp8266

Server web ở chế độ Station

Ở chế độ station, esp8266 sẽ không phát wifi nữa mà truy cập vào wifi ở nhà

C #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> MDNSResponder mdns; ESP8266WebServer server(80); String webPage = { "<!DOCTYPE html>" "<html>" "<head>" " <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" " <title>Điều khiển thiết bị</title>" " <meta name='viewport' content='width=device-width, initial-scale=1'>" " <style>" " .b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;}" " .t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;}" " </style>" "</head>" "<body>" "<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>" "<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>" " <table align='center'>" " <tr>" " <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>" " <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>" " <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>" " <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>" " <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>" " <tr>" " </table>" "</div>" "</body>" "</html>" }; void TrangChu() { server.send(200, "text/html", webPage); } void setup() { Serial.begin(9600); Serial.println(); Serial.println(); Serial.print("Connecting to "); WiFi.begin("Tang5", "12345678"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) Serial.println("MDNS responder started"); server.on("/", TrangChu); server.on("/bat1", bat1); server.on("/tat1", tat1); server.on("/bat2", bat2); server.on("/tat2", tat2); server.begin(); } void loop() { server.handleClient(); }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 #include <ESP8266WiFi.h>#include <WiFiClient.h>#include <ESP8266WebServer.h>#include <ESP8266mDNS.h> MDNSResponder mdns;ESP8266WebServer server(80); StringwebPage={"<!DOCTYPE html>""<html>""<head>"" <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"" <title>Điều khiển thiết bị</title>"" <meta name='viewport' content='width=device-width, initial-scale=1'>"" <style>" ".b{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#4caf50;border-radius:10px;}" ".t{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#f44336;border-radius:10px;}" "</style>""</head>""<body>""<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>""<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>"" <table align='center'>"" <tr>"" <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>"" <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>"" <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>"" <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>"" <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>"" <tr>"" </table>""</div>""</body>""</html>"};voidTrangChu(){server.send(200,"text/html",webPage);}voidsetup(){Serial.begin(9600);Serial.println();Serial.println();Serial.print("Connecting to ");WiFi.begin("Tang5","12345678");while(WiFi.status()!=WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());if(mdns.begin("esp8266",WiFi.localIP()))Serial.println("MDNS responder started");server.on("/",TrangChu);server.on("/bat1",bat1);server.on("/tat1",tat1);server.on("/bat2",bat2);server.on("/tat2",tat2);server.begin();}voidloop(){server.handleClient();}

Trong đó yourSSID YourPass là tài khoản và mật khẩu wifi nhà bạn !

OK bây giờ esp8266 sẽ tự kết nói vào wifi nhà bạn và in ra địa chỉ IP có dạng 192.168.1.xxx Đây là địa chỉ IP mà modem mạng của bạn cấp phát cho nó, bạn chỉ việc gõ địa chỉ ip vào trinh duyệt web là trang web như trên sẽ hiện ra

Bật cổng Serial Monitor lên để xem Log nhé

ESP8266 và thiết bị truy cập phải cùng kết nối tới 1 mạng wifi nhé

tạo webserver esp8266
Kết quả

Code chức năng bật tắt LED

Tiếp tục, chúng ta sẽ code thêm chức năng bật tắt led, do ở đây mình dùng esp8266v1 nó chỉ có 2 chân GPIO nên mình sẽ chỉ code chức năng bật tắt cho kênh 1,2. Kênh 3,4 tạm để trạng trí vậy 🙂

C #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> MDNSResponder mdns; ESP8266WebServer server(80); String webPage = { "<!DOCTYPE html>" "<html>" "<head>" " <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" " <title>Điều khiển thiết bị</title>" " <meta name='viewport' content='width=device-width, initial-scale=1'>" " <style>" " .b{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#4caf50;border-radius: 10px;}" " .t{width: 100px;height: 40px;font-size: 21px;color: #FFF;background-color:#f44336;border-radius: 10px;}" " </style>" "</head>" "<body>" "<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>" "<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>" " <table align='center'>" " <tr>" " <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>" " <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>" " <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>" " <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>" " <tr>" " <tr>" " <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>" " <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>" " <tr>" " </table>" "</div>" "</body>" "</html>" }; void TrangChu() { server.send(200, "text/html", webPage); } void bat1() { digitalWrite(0, HIGH); Serial.println("Bật LED 1"); server.send(200, "text/html", webPage); } void tat1() { digitalWrite(0, LOW); Serial.println("Tắt LED 1"); server.send(200, "text/html", webPage); } void bat2() { digitalWrite(2, HIGH); Serial.println("Bật LED 2"); server.send(200, "text/html", webPage); } void tat2() { digitalWrite(2, LOW); Serial.println("Tắt LED 2"); server.send(200, "text/html", webPage); } void setup() { pinMode(0, OUTPUT); pinMode(2, OUTPUT); Serial.begin(9600); Serial.println(); Serial.println(); Serial.print("Connecting to "); WiFi.begin("Tang5", "12345678"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) Serial.println("MDNS responder started"); server.on("/", TrangChu); server.on("/bat1", bat1); server.on("/tat1", tat1); server.on("/bat2", bat2); server.on("/tat2", tat2); server.begin(); } void loop() { server.handleClient(); }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 #include <ESP8266WiFi.h>#include <WiFiClient.h>#include <ESP8266WebServer.h>#include <ESP8266mDNS.h> MDNSResponder mdns;ESP8266WebServer server(80); StringwebPage={"<!DOCTYPE html>""<html>""<head>"" <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>"" <title>Điều khiển thiết bị</title>"" <meta name='viewport' content='width=device-width, initial-scale=1'>"" <style>" ".b{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#4caf50;border-radius:10px;}" ".t{width:100px;height:40px;font-size:21px;color:#FFF;background-color:#f44336;border-radius:10px;}" "</style>""</head>""<body>""<div style='width: 330px;height: auto;margin: 0 auto;margin-top: 70px'>""<h1 align='center'>Điều khiển thiết bị qua WIFI</h1>"" <table align='center'>"" <tr>"" <td><a href='/bat1'><button class='b'>Bật 1</button></a><td>"" <td><a href='/tat1'><button class='t'>Tắt 1</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat2'><button class='b'>Bật 2</button></a><td>"" <td><a href='/tat2'><button class='t'>Tắt 2</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat3'><button class='b'>Bật 3</button></a><td>"" <td><a href='/tat3'><button class='t'>Tắt 3</button></a><td>"" <tr>"" <tr>"" <td><a href='/bat4'><button class='b'>Bật 4</button></a><td>"" <td><a href='/tat4'><button class='t'>Tắt 4</button></a><td>"" <tr>"" </table>""</div>""</body>""</html>"};voidTrangChu(){server.send(200,"text/html",webPage);}voidbat1(){digitalWrite(0,HIGH);Serial.println("Bật LED 1");server.send(200,"text/html",webPage);}voidtat1(){digitalWrite(0,LOW);Serial.println("Tắt LED 1");server.send(200,"text/html",webPage);}voidbat2(){digitalWrite(2,HIGH);Serial.println("Bật LED 2");server.send(200,"text/html",webPage);}voidtat2(){digitalWrite(2,LOW);Serial.println("Tắt LED 2");server.send(200,"text/html",webPage);}voidsetup(){pinMode(0,OUTPUT);pinMode(2,OUTPUT);Serial.begin(9600);Serial.println();Serial.println();Serial.print("Connecting to ");WiFi.begin("Tang5","12345678");while(WiFi.status()!=WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());if(mdns.begin("esp8266",WiFi.localIP()))Serial.println("MDNS responder started");server.on("/",TrangChu);server.on("/bat1",bat1);server.on("/tat1",tat1);server.on("/bat2",bat2);server.on("/tat2",tat2);server.begin();}voidloop(){server.handleClient();}

Code trên mình thêm dòng cấu hình ngõ ra cho GPIO0 và GPIO2, sau đó thêm hàm callback nhận lệnh bặt tắt từ trình duyệt và xuất tin hiệu HIGH LOW ra chân GPIO và in log ra màn hình Serial

Mẹo: Có thể tận dụng 2 chân Serial làm GPIO luôn, như thế con espv1 sẽ điều khiển được 4 thiết bị

NAT PORT

Chúng ta đã có thể truy cập vào server của esp8266 thông qua mạng LAN trong gia đình, tuy nhiên, nó chỉ là 1 cái server hoạt động cục bộ trong gia đình, nếu muốn đi ra ngoài mà điều khiển được thì cần phải đưa nó ra ngoài thế giới internet rộng lớn.

IP cục bộ và IP công cộng

Các bạn có thể thấy ở video demo trên, modem mạng nhà mình đã cấp phát cho esp8266 địa chỉ 192.168.1.11, đây chính là IP cục bộ mà modem đã cấp cho esp8266 để nó phân biệt với các thiết bị khác cũng chung mạng wifi ( điện thoại, laptop, smart tivi cũng đều đc cấp 1 cái ip riêng, không thằng nào dùng chung với thằng nào)

Bản thân modem wifi thông thường cùng sẽ lấy địa chỉ 192.168.1.1 hoặc 192.168.0.1 là IP cục bộ mặc định ! Nếu nó được đăng kí internet với nhà mạng (viettel, vina … ) – tức có sợi dây cáp quang gắn vào đấy – thì nhà mạng sẽ cung cấp cho modem 1 IP công cộng, đây là địa chỉ IP duy nhất để phân biệt modem nhà bạn với hàng tỉ thiết bị internet trên thế giới. Như vậy tất cả thiết bị trong LAN muốn giao tiếp với bên ngoài phải thông qua modem.

Để biết modem của bạn có IP công cộng (public IP) là gì, bạn hãy ấn vào đây

nat port

Như ở trên 117.1.165.234 chính là IP của modem wifi nhà mình, bây giờ 1 thiết bị bên ngoài muốn truy cập vào web server của esp8266, nó phải truy cập vào IP này trước, sau đó, nó sẽ thông báo cho modem biết cụ thể là nó muốn truy cập vào esp8266 bằng cách thông báo cổng

nat port

Ở bức ảnh trên, laptop và esp8266 đều ở trong LAN và có IP riêng, esp muốn cái điện thoại bên ngoài liên lạc được với nó, nó sẽ nói với modem rằng: “Ê modem, tao đăng kí cổng số 207”, tương tự nếu laptop cũng đua đòi tạo web server và muốn điện thoại truy cập vào, nó cũng bào với modem cần đăng kí cổng số 102

Bây giờ, khi điện thoại bên ngoài gõ vào trình duyệt 117.1.165.234:207 nó sẽ truy cập được vào esp8266, còn nếu muốn truy cập vào laptop thì nó sẽ vào 117.1.165.234:102

Hành động khai báo cổng cho modem chính là NAT PORT

Để NAT PORT, có 2 cách chính:

  • Port Forwarding, đây là cách mình khuyên các bạn nên xài và mình sẽ hướng dẫn các bạn Port Forwarding
  • DMZ, cái này các tự tìm hiểu thêm

Hướng dẫn NAT PORT – tạo webserver với esp8266

Tùy vào modem mạng của bạn thuộc hãng nào, phiên bản nào mà sẽ có các cách NAT khác nhau, nhưng nhìn chung đều tương tự nhau và mò tí là ra thôi.

Đầu tiên, phải biết được IP cục bộ của modem mạng để tín hành vào trang cài đặt ( chính là cái trang các bạn hay vào để đổi tên, mật khẩu wifi đó), thông thường nó sẽ là 192.168.1.1 hoặc 192.168.0.1 các bạn cứ gõ thử vào trình duyệt để xem cái nào vào được. Nếu cả 2 đều không vào được thì lấy laptop ra, mở cmd lên gõ ipconfig rồi tìm đến dòng Defaut gatewway sẽ thấy ip của modem

Như ở trên ip modem của mình 192.168.1.1

Sau đó gõ IP đó vào trình duyệt và bạn sẽ được đưa đến trang đăng nhập ( Nguồn tham khảo https://lapcamera247.com/huong-dan-nat-port-va-cau-hinh-ten-mien-modem-viettel-f608-f600w.html )

Thông thường tài khoản là admin và mật khẩu là admin hoặc 123456 . Nếu thử không được thì lật mặt dưới modem wifi lên xem sẽ thấy ! Nếu vẫn không được thì ấn giữ nút reset modem để khôi phục mật khẩu về mặc định

Tài khoản mật khẩu được ghi ở phía sau
Tắt tường lửa
  • Tích vào enable
  • Name: Đặt tên gì cũng được
  • WAN Connection: mặc định
  • 4 ô có thông số PORT: điền PORT mà bạn muốn
  • LAN Host IP: Chính là IP của esp8266 mà modem đã cấp phát cho

Sau đó save lại

Kiểm tra xem đã thông được ra internet chưa

Vào https://canyouseeme.org/ gõ IP công cộng của modem và port mà lúc nãy bạn đã mở, nếu báo OK là ok rùi đó

Từ giờ mình có thể đi ra Úc, hay Tây Ban Nha rồi gõ 117.1.165.234:207 là có thể ung dung vào điều khiển các thiết bị trong nhà

Khắc phục lỗi NAT mãi không được – tạo webserver với esp8266

Chủ yếu có 2 nguyên nhân: Nguyên nhân 1, là mạng bang đang dùng là mạng đa lớp

nat port

Như hình trên, có thể thấy esp8266 của chúng ta không kết nối trực tiếp với modem wifi gốc mà qua 1 roter tp-link nữa. Vậy nên bạn phải NAT cả cho roter tp-link luôn ( NAT 2 lần). Nếu bạn đang ở phòng trọ thì đến 99% là dùng qua mạng nhiều lớp !

Cái modem mà của vina, vietel, FPT mà có cái dây cáp quang cắm vào ý, cái ấy mới là modem gốc

Nguyên nhân 2 là nhà mạng chưa cập nhật đúng IP công cộng của modem nhà bạnKhắc phục rất đơn giản, alo cho tổng đài bảo nó reset lại modem wifi (nó reset ở trên tổng chứ không phải cái nút reset ở modem đâu :v )

Bài đã dài, có thể bạn nghĩ tới đây đã hết, nhưng chưa đâu, vào 1 ngày đẹp trời cái web server lại đ*o vào được >< , Nguyên nhân là do khi modem wifi bị mất điện hay khởi động lại nó sẽ được nhà mạng phát ip mới, bạn lên trang https://whatismyipaddress.com/ sẽ thấy cái ip mới đét >< Để khắc phục vấn đề này chúng ta cần tới DDNS

Hướng dẫn cấu hình DDNS – tạo webserver với esp8266

Hiểu nôm na DDNS là 1 tên miền để bạn gõ vào trình duyệt thay vì gõ mấy cái số ip khô khan. Lúc nhà mạng phát ip công cộng mới cho modem ta vẫn vào được.

Vào trang https://www.noip.com/ đăng kí tài khoản và đăng kí 1 tên miền có dạng yourname.ddns.com, mà ngày trước nó free giờ nó đồi phí hay sao ấy, để rảnh mình kiếm cái trang free khác up lên sau

Sau khi đăng kí xong và đã có tên miền riêng thì quay trở lại rang quản lí của modem wifi, tìm đến phần DDNS setting và điền thông tin tên miền + user name + password mà bạn vừa đăng kí vào

Vậy là xong, giờ chúng ta có thể an tâm gõ tên miền kèm theo đuôi port phía sau là có thể điều khiển ngôi nhà của mình rồi !Ví dụ dây là địa chỉ esp8266 mà mình đã nat và cấu hình ddns: iot47-test.ddns.net:80

Related posts:

[ENC28J60] Bài 15: Giao thức DHCP - lấy IP động[ENC28J60] Bài 13: Giao thức TCP – truyền nhận dữ liệu[ENC28J60] Bài 3: Khởi tạo module enc28j60 - giao tiếp enc28j60 (phần 2)[ENC28J60] Bài 19: Giao thức MQTT

Từ khóa » Thư Viện Esp8266webserver.h