Bài viết này sẽ hướng dẫn bạn từng bước xây dựng một Webserver trên ESP8266 để điều 4 đèn Led độc lập qua mạng internet. Webserver trên ESP8266 mà mình sẽ hướng dẫn đáp ứng tất cả các trình duyệt trên điện thoại thông minh, như vậy các bạn có thể truy cập vào thiết bị bằng máy tính PC hoặc điện thoại thông minh trong mạng cục bộ ( mạng LAN ) thông qua địa chỉ IP của thiết bị


Ở đây mình sử dụng  Arduino IDE :
  + Link tải bản Arduino IDE ,các bạn tải bản mới nhất 
  + Sau đó bạn chạy cài đặt arduino lên máy tính , rồi khởi chạy Arduino , vào phần File > Preference
  + Nhập “http://arduino.esp8266.com/stable/package_esp8266com_index.json” vào mục Additional Board Manager URLs giống hình dưới rồi nhấp vào OK:


 + Tiếp tục vào Tools > Board > Boards Manager



 + Sau đó của sổ Boards Manager sẽ hiện ra , tìm ESP8266 package rồi cài đặt bằng cách nhấp vào Install 



Như vậy là đã xong phần cài đặt phần mềm, bây giờ đến phần cứng, các bạn đấu dây led với module wifi esp8266 như hình sau 

Sơ đồ mạch


Ở project này mình sử dụng module ESP8266 D1mini có bán tại các cửa hàng điện tử

Bây giờ đến Code : 

/********************************************
  Thạch điện tử ( thachdt )
  Code được viết bởi http://thachdt.com
********************************************/
#include <ESP8266WiFi.h>

// ten wifi va mat khau wifi
const char* ssid     = “thachdt”;
const char* password = “thachdt.com”;
WiFiServer server(80);
String header;
String trang_thai_led1 = “tat”;
String trang_thai_led2 = “tat”;
String trang_thai_led3 = “tat”;
String trang_thai_led4 = “tat”;
// chan su dung
const int led1 = 5;
const int led2 = 4;
const int led3 = 0;
const int led4 = 2;

void setup() {
  Serial.begin(115200);
  // cai dat cong output
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);

  Serial.print(“Dang ket noi voi mang wifi “);
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(“.”);
  }
  Serial.println(“”);
  Serial.println(“Da ket noi wifi thanh cong”);
  Serial.println(“Dia chi IP cua thiet bi la : “);
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // lang nghe xem co client nao dang ket noi den thiet bi khong

  if (client) {                             
    Serial.println(“New Client.”);          
    String currentLine = “”;                
    while (client.connected()) {            
      if (client.available()) {             
        char c = client.read();             
        Serial.write(c);                    
        header += c;
        if (c == ‘n’) {                    
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            client.println(“HTTP/1.1 200 OK”);
            client.println(“Content-type:text/html”);
            client.println(“Connection: close”);
            client.println();
            
            // Bat tat 4 led
            if (header.indexOf(“GET /1/bat”) >= 0) {
              Serial.println(“Led 1 bat”);
              trang_thai_led1 = “bat”;
              digitalWrite(led1, HIGH);
            } else if (header.indexOf(“GET /1/tat”) >= 0) {
              Serial.println(“Led 1 tat”);
              trang_thai_led1 = “tat”;
              digitalWrite(led1, LOW);
            }
              else if (header.indexOf(“GET /2/bat”) >= 0) {
              Serial.println(“Led 2 bat”);
              trang_thai_led2 = “bat”;
              digitalWrite(led2, HIGH);
            } else if (header.indexOf(“GET /2/tat”) >= 0) {
              Serial.println(“Led 2 tat”);
              trang_thai_led2  = “tat”;
              digitalWrite(led2, LOW);
            }
              else if (header.indexOf(“GET /3/bat”) >= 0) {
              Serial.println(“Led 3 bat”);
              trang_thai_led3 = “bat”;
              digitalWrite(led3, HIGH);
            } else if (header.indexOf(“GET /3/tat”) >= 0) {
              Serial.println(“Led 3 tat”);
              trang_thai_led3  = “tat”;
              digitalWrite(led3, LOW);
            }            
              else if (header.indexOf(“GET /4/bat”) >= 0) {
              Serial.println(“Led 4 bat”);
              trang_thai_led4 = “bat”;
              digitalWrite(led4, HIGH);
            } else if (header.indexOf(“GET /4/tat”) >= 0) {
              Serial.println(“Led 4 tat”);
              trang_thai_led4  = “tat”;
              digitalWrite(led4, LOW);
            }            
            // Hien thi trang web HTML
            client.println(“<!DOCTYPE html><html>”);
            client.println(“<head><meta name=”viewport” content=”width=device-width, initial-scale=1″>”);
            client.println(“<meta charset=”utf-8″/>”);
           // client.println(“<meta http-equiv=”refresh” content=”1″> “); // tu reload lai web html
            client.println(“<link rel=”icon” href=”data:,”>”);
           // code CSS tao button
           client.println(“<style>html { background-color: #000000; font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}”);
           client.println(“.button { display: inline-block;outline: none;cursor: pointer;text-align: center;text-decoration: none;”);
           client.println(“font: 30px/100% Arial, Helvetica, sans-serif;padding: 0.5em 2em .55em;text-shadow: 0 1px 1px rgba(0,0,0,.3);”);
           client.println(“-webkit-border-radius: 1em; -moz-border-radius: 1em;border-radius: 1em;-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);”);
           client.println(“-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); box-shadow: 0 1px 2px rgba(0,0,0,.2);}”);
           client.println(“.button:hover {text-decoration: none;}”);
           client.println(“.button:active {position: relative;top: 1px;}”);
           // button mau xanh
           client.println(“.red {color: #faddde;border: solid 1px #980c10;background: #d81b21;background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));”);
           client.println(“background: -moz-linear-gradient(top,  #ed1c24,  #aa1317);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#ed1c24′, endColorstr=’#aa1317′);}”);
           client.println(“.red:hover {background: #b61318;background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));”);
           client.println(“background: -moz-linear-gradient(top,  #c9151b,  #a11115);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#c9151b’, endColorstr=’#a11115′);}”);
           client.println(“.red:active {color: #de898c;background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));”);
           client.println(“background: -moz-linear-gradient(top,  #aa1317,  #ed1c24);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#aa1317′, endColorstr=’#ed1c24′);}”);
           // button mau xanh
           client.println(“.blue {color: #d9eef7;border: solid 1px #0076a3;background: #0095cd;background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));”);
           client.println(“background: -moz-linear-gradient(top,  #00adee,  #0078a5);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#00adee’, endColorstr=’#0078a5′);}”);
           client.println(“.blue:hover {background: #007ead;background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));”);
           client.println(“background: -moz-linear-gradient(top,  #0095cc,  #00678e);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#0095cc’, endColorstr=’#00678e’);}”);
           client.println(“.blue:active {color: #80bed6;background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));”);
           client.println(“background: -moz-linear-gradient(top,  #0078a5,  #00adee);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr=’#0078a5′, endColorstr=’#00adee’);} “);

           client.println(“</style></head>”);
           client.println(“<body><h1><font color=”white”>Điều Khiển 4 LED Qua Websever Trên ESP8266</font></h1>”);
           client.println(“<body><h2><font color=”white”>Blog thachdt.com</font></h2>”);
           if (trang_thai_led1==”tat”) {
              client.println(“<p><a href=”/1/bat”><button class=”button blue”>Bật Bóng Đèn 1</button></blue></p>”);
            } 
           else {
              client.println(“<p><a href=”/1/tat”><button class=”button button red”>Tắt Bóng Đèn 1</button></red</p>”);
            }               
           if (trang_thai_led2==”tat”) {
              client.println(“<p><a href=”/2/bat”><button class=”button blue”>Bật Bóng Đèn 2</button></blue></p>”);
            } 
           else {
              client.println(“<p><a href=”/2/tat”><button class=”button button red”>Tắt Bóng Đèn 2</button></red></p>”);
            }
           if (trang_thai_led3==”tat”) {
              client.println(“<p><a href=”/3/bat”><button class=”button blue”>Bật Bóng Đèn 3</button></blue></p>”);
            } 
           else {
              client.println(“<p><a href=”/3/tat”><button class=”button button red”>Tắt Bóng Đèn 3</button></red></p>”);
            }
           if (trang_thai_led4==”tat”) {
              client.println(“<p><a href=”/4/bat”><button class=”button blue”>Bật Bóng Đèn 4</button></blue></p>”);
            } 
           else {
              client.println(“<p><a href=”/4/tat”><button class=”button button red”>Tắt Bóng Đèn 4</button></red></p>”);
            }
  
            client.println(“</body></html>”);    
            client.println();
            break;
          } else { 
            currentLine = “”;
          }
        } else if (c != ‘r’) {  
          currentLine += c;      
        }
      }
    } 
    header = “”;
    client.stop();// ngat ket noi
    Serial.println(“Client disconnected.”);
      }

}




Để code hoạt động được với mạng wifi nhà bạn thì bạn cần thay đổi 2 dòng code sau :
// ten wifi va mat khau wifi nha ban , thay thế tên wifi và mật khẩu wifi nhà bạn trong ngoặc kép 
const char* ssid     = “thachdt”;
const char* password = “thachdt.com”;

Sau đó bạn UPLOAD Sketch vào module wifi esp8266 của bạn 



sau khi upload thành công bạn vào Serial Monitor để xem thiết bị kết nối vào wifi nhà bạn và xem địa chỉ IP của thiết bị 


Bạn vào trình duyệt gõ địa chỉ IP như bạn đã thấy ở Serial Monitor , ở đây là địa chỉ 192.168.43.2 , trang webserver của bạn sẽ được load từ thiết bị như hình sau :

TRUNG TÂM SỬA CHỮA ĐIỆN TỬ QUẢNG BÌNH
MR. XÔ - 0901.679.359 - 80 Võ Thị Sáu, Phường Quảng Thuận, tx Ba Đồn, tỉnh Quảng Bình
Sửa điện tử tại Quảng Bình



Như vậy bạn có thể điều khiển bật tắt 4 đèn led bằng cách nhấp chuột vào 4 nút nhấn trên web

Cách thức làm việc của code :

Đầu tiên là thêm thư viện ESP8266wifi 

#include <ESP8266WiFi.h>

sau đó là tên wifi và mật khẩu wifi nhà bạn

const char* ssid = "thachdt";
const char* password = "thachdt.com";

cài đặt webserver ở cổng 80

WiFiServer server(80);
tạo một biến để lưu header của http request
String header;
Định nghĩa các biến và chân sử dụng cho các output
String trang_thai_led1 = "tat";
String trang_thai_led2 = "tat";
String trang_thai_led3 = "tat";
String trang_thai_led4 = "tat";
// chan su dung
const int led1 = 5;
const int led2 = 4;
const int led3 = 0;
const int led4 = 2;
Hàm setup() , hàm setup này chỉ chạy khi ESP8266 được cấp nguồn , và tự tìm kiếm wifi nhà bạn và tự động kết nối với wifi
void setup() {
  Serial.begin(115200);
  // cai dat cong output
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  Serial.print("Dang ket noi voi mang wifi ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Da ket noi wifi thanh cong");
  Serial.println("Dia chi IP cua thiet bi la : ");
  Serial.println(WiFi.localIP());
  server.begin();
}

Hàm loop() , ở vòng lặp này sẽ xử lí các sự kiện diễn ra khi có một client được kết nối với thiết bị
Trước tiên esp8266 sẽ lắng nghe khi có 1 client mới kết nối vào tức là khi mình nhập địa chỉ IP của thiết bị vào trình duyệt thì hàm này sẽ lắng nghe
WiFiClient client = server.available(); 


Nếu có một yêu cầu từ client , mình cần lưu lại dữ liệu đến
 if (client) {                             
    Serial.println("New Client.");          
    String currentLine = "";                
    while (client.connected()) {            
      if (client.available()) {             
        char c = client.read();             
        Serial.write(c);                    
        header += c;
        if (c == 'n') {                    
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

Tiếp tục là hàm if else để kiểm tra nút nhấn nào đã được nhấn trên trang web , và điều khiển bật tắt tại các cổng output trên module wifi

       // Bat tat 4 led
            if (header.indexOf("GET /1/bat") >= 0) {
              Serial.println("Led 1 bat");
              trang_thai_led1 = "bat";
              digitalWrite(led1, HIGH);
            } else if (header.indexOf("GET /1/tat") >= 0) {
              Serial.println("Led 1 tat");
              trang_thai_led1 = "tat";
              digitalWrite(led1, LOW);
            }
              else if (header.indexOf("GET /2/bat") >= 0) {
              Serial.println("Led 2 bat");
              trang_thai_led2 = "bat";
              digitalWrite(led2, HIGH);
            } else if (header.indexOf("GET /2/tat") >= 0) {
              Serial.println("Led 2 tat");
              trang_thai_led2  = "tat";
              digitalWrite(led2, LOW);
            }
              else if (header.indexOf("GET /3/bat") >= 0) {
              Serial.println("Led 3 bat");
              trang_thai_led3 = "bat";
              digitalWrite(led3, HIGH);
            } else if (header.indexOf("GET /3/tat") >= 0) {
              Serial.println("Led 3 tat");
              trang_thai_led3  = "tat";
              digitalWrite(led3, LOW);
            }            
              else if (header.indexOf("GET /4/bat") >= 0) {
              Serial.println("Led 4 bat");
              trang_thai_led4 = "bat";
              digitalWrite(led4, HIGH);
            } else if (header.indexOf("GET /4/tat") >= 0) {
              Serial.println("Led 4 tat");
              trang_thai_led4  = "tat";
              digitalWrite(led4, LOW);
            }            
Hiển thị trang web : để gửi dữ liệu trang web cho client thì ta dùng hàm client.println() 

           // Hien thi trang web HTML
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name="viewport" content="width=device-width, initial-scale=1">");
            client.println("<meta charset="utf-8"/>");
            client.println("<link rel="icon" href="data:,">");
           // code CSS tao button
           client.println("<style>html { background-color: #000000; font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
           client.println(".button { display: inline-block;outline: none;cursor: pointer;text-align: center;text-decoration: none;");
           client.println("font: 30px/100% Arial, Helvetica, sans-serif;padding: 0.5em 2em .55em;text-shadow: 0 1px 1px rgba(0,0,0,.3);");
           client.println("-webkit-border-radius: 1em; -moz-border-radius: 1em;border-radius: 1em;-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);");
           client.println("-moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); box-shadow: 0 1px 2px rgba(0,0,0,.2);}");
           client.println(".button:hover {text-decoration: none;}");
           client.println(".button:active {position: relative;top: 1px;}");
           // button mau xanh
           client.println(".red {color: #faddde;border: solid 1px #980c10;background: #d81b21;background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));");
           client.println("background: -moz-linear-gradient(top,  #ed1c24,  #aa1317);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed1c24', endColorstr='#aa1317');}");
           client.println(".red:hover {background: #b61318;background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));");
           client.println("background: -moz-linear-gradient(top,  #c9151b,  #a11115);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#c9151b', endColorstr='#a11115');}");
           client.println(".red:active {color: #de898c;background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));");
           client.println("background: -moz-linear-gradient(top,  #aa1317,  #ed1c24);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#aa1317', endColorstr='#ed1c24');}");
           // button mau xanh
           client.println(".blue {color: #d9eef7;border: solid 1px #0076a3;background: #0095cd;background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));");
           client.println("background: -moz-linear-gradient(top,  #00adee,  #0078a5);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5');}");
           client.println(".blue:hover {background: #007ead;background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));");
           client.println("background: -moz-linear-gradient(top,  #0095cc,  #00678e);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e');}");
           client.println(".blue:active {color: #80bed6;background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));");
           client.println("background: -moz-linear-gradient(top,  #0078a5,  #00adee);filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee');} ");
           client.println("</style></head>");
           client.println("<body><h1><font color="white">Điều Khiển 4 LED Qua Websever Trên ESP8266</font></h1>");
           client.println("<body><h2><font color="white">Blog thachdt.com</font></h2>");
           if (trang_thai_led1=="tat") {
              client.println("<p><a href="/1/bat"><button class="button blue">Bật Bóng Đèn 1</button></blue></p>");
            } 
           else {
              client.println("<p><a href="/1/tat"><button class="button button red">Tắt Bóng Đèn 1</button></red</p>");
            }               
           if (trang_thai_led2=="tat") {
              client.println("<p><a href="/2/bat"><button class="button blue">Bật Bóng Đèn 2</button></blue></p>");
            } 
           else {
              client.println("<p><a href="/2/tat"><button class="button button red">Tắt Bóng Đèn 2</button></red></p>");
            }
           if (trang_thai_led3=="tat") {
              client.println("<p><a href="/3/bat"><button class="button blue">Bật Bóng Đèn 3</button></blue></p>");
            } 
           else {
              client.println("<p><a href="/3/tat"><button class="button button red">Tắt Bóng Đèn 3</button></red></p>");
            }
           if (trang_thai_led4=="tat") {
              client.println("<p><a href="/4/bat"><button class="button blue">Bật Bóng Đèn 4</button></blue></p>");
            } 
           else {
              client.println("<p><a href="/4/tat"><button class="button button red">Tắt Bóng Đèn 4</button></red></p>");
            }
  
            client.println("</body></html>");    
            client.println();
Cuối cùng khi kết thúc yêu cầu từ client, ta xóa dữ liệu đã chứa tạm thời trong biến header và dùng kết nối giữa client và server bằng hàm client.stop()

header = "";
    client.stop();// ngat ket noi
    Serial.println("Client disconnected.");

Nhượt điểm code này :
 + Tốn thời gian reload lại trang web khi mỗi lần điều khiển, trang web bị lag
 + Khi thiết bị mất kế nối thì client sẽ không biết, do không có kết nối liên tục mà chỉ kết nối khi client gửi yêu cầu
 + Chỉ điều khiển được trong mạng nội bộ, muốn điều khiển qua internet ở bất kì nơi ngoài mạng wifi nhà bạn thì phải cấu hình nat port vào router wifi rất phức tạp

Ở phần chia sẻ tiếp theo mình sẽ giới thiệu các bạn sử dụng Websoket để khắc phục được 2 nhược điểm đầu tiên

Nếu có thắc mắc hoặc lỗi khi bạn upload code vào module wifi thi để lại bình luận hoặc gửi tin nhắn qua facebook  http://www.facebook.com/thachdt.co

Cám ơn các bạn đã xem, nếu thấy bài viết hữu ích với các bạn thì hãy chia sẽ bài viết này

Mọi copy bài viết trên trang này xin vui lòng để nguồn bài viết từ thachdt.com

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

− 5 = 5