[1] Sau khi kết nối thành công, địa chỉ IP được wifi cấp xuống sẽ hiển thị ở đây. [2] Thời gian thực sẽ được cập nhật lại cho đúng như thời gian trên website quản lý.
50
Chƣơng 6:
ĐÁNH GIÁ KẾT QUẢ, KẾT LUẬN
6.1 Kết quả đạt đƣợc
Sau một thời gian nghiên cứu và hoàn thiện, hệ thống đã thực hiện quản lý và giám sát một chuỗi bao gồm 1000 tủ kem và cho đến hiện tại vẫn đang hoạt động ổn định.
Hệ thống đã truyền nhận thành công và ổn định lên server và website thiết bị mà độ trễ hầu như khơng đáng kể, có thể điều khiển bật tắt mạch trên website thiết bị khá tốt. Đồng thời hệ thống cũng đã thực hiện tạo điểm phát và kết nối với wifi tại nơi đặt tủ rất ổn định mà ít khi bị mất kết nối.
Tất cả cấu thành trong hệ thống đã được thử nghiệm và vận hành tốt, tuy nhiên vẫn còn nhiều nhược điểm do hạn chế về mặt kiến thức. Đề tài nghiên cứu này em sẽ rút kinh nghiệm và hoàn thiện tốt hơn trong tương lai.
6.2 Đánh giá kết quả thực tế
Bảng 6.1: Bảng thực nghiệm kết quả chạy thực tế
Công việc Số lần Số lần thành
công
Thời gian đáp
ứng Đánh giá
Điều khiển và thao tác
trên website thiết bị 50 50 2 - 3 giây Đạt
Hiện thị trạng thái và thời gian thực trên website thiết bị
50 40 1 giây Đạt
Thực hiện tạo điểm
phát và kết nối wifi 50 50 10 – 15 giây Đạt
Gửi dữ liệu và hiển thị
lên server 50 50 15 giây Đạt
51
6.3 Nhận xét
Ưu điểm:
+ Dễ dàng nắm bắt được hiện trạng của hệ thống để đưa ra hướng giải quyết kịp thời.
+ Tiết kiệm thời gian và chi phí nhân cơng. + Đơn giản hóa việc quản lý số lượng lớn tủ kem.
+ Mạch điều khiển nhỏ gọn, hoạt động ổn định, chính xác, dễ dàng lắp đặt vào tủ kem mà khơng gây ảnh hướng đến chức năng chính yếu của tủ.
+ Có server quản lý và lưu trữ dữ liệu.
+ Giao diện điều khiển đơn giản, trực quan và dễ sử dụng. Nhược điểm:
+ Giới hạn về thời gian và kiến thức nên hệ thống chưa tối ưu.
+ Hệ thống cịn phụ thuộc vào tốc độ mạng Internet, đơi khi sẽ xảy ra hiện tượng chậm trễ.
+ Hệ thống hiện tại vẫn đang vận hành trên server thuê bên ngoài, hiện tượng sập server đôi khi xảy ra.
+ Mạch phần cứng thường xuyên có hiện tượng quá nhiệt trong lúc hoạt động.
6.4 Định hƣớng phát triển
+ Sẽ thử nghiệm và thay đổi sang một số loại vi điều khiển thích hợp wifi có tốc độ thu phát tốt hơn trong tương lai.
+ Thêm vào một số cảm biến phục vụ tính năng an tồn như cảm biến nhiệt độ, cảm biến khí gas.
+ Thực hiện thêm vào tính năng bảo mật thơng tin trên đường truyền.
52
TÀI LIỆU THAM KHẢO
I. Tài liệu từ sách
[1]. Ths. Nguyễn Thị Ngọc Anh. Điện tử tương tự 1. Hutech, ấn bản 2015, tr. 1-31 [2]. Ths. Phạm Quốc Phương. Vi điều khiển. Hutech, ấn bản 2015, tr. 31-46, tr.104- 115
II. Tài liệu từ nguồn từ Internet
1/ https://randomnerdtutorials.com/ 2/ https://www.w3schools.com/html/default.asp 3/ https://randomnerdtutorials.com/decoding-and-encoding-json-with-arduino-or- esp8266/ 4/ http://arduino.vn/reference/millis 5/ https://stackoverflow.com/questions/10813718/ajax-onreadystatechange-function 6/ https://arduino.esp8266.vn/wifi/station.html 7/ https://randomnerdtutorials.com/esp32-access-point-ap-web-server/ 8/ https://codelearn.io/sharing/tao-server-cho-trang-web-ca-nhan-voi-arduino 9/ https://www.kasperkamperman.com/blog/arduino/arduino-programming-state- change 10/ http://arduino.vn/bai-viet/1231-ket-noi-voi-esp8266-thuan-voi-board-mo-rong- va- 11/ https://github.com/PaulStoffregen/Time 12/ https://stackoverflow.com/questions/64278397/arduino-esp8266-eeprom- commit-returns-false
53
PHỤ LỤC
Code lập trình Arduino
//================= Khai báo thư viện =============== #include <EEPROM.h> //thư viện bộ nhớ lưu trữ
#include <time.h> //khai báo thư viện thời gian
#include <string.h> // Thư viện hỗ trợ truyền chuỗi dữ liệu #include <ESP8266WiFi.h> //Khai báo thư viện cho ESP
#include <ESP8266WebServer.h> //Khai báo thư viện cho web thiết bị #include <ESP8266HTTPClient.h>
#include <WiFiClient.h> //#include "ArduinoJson.h"
#include <ArduinoJson.h> //Thư viện hỗ trợ gửi dữ liệu lên server ESP8266WebServer webServer(80);//khai báo port web thiết bị ESP8266WebServer webServer2(1605);//khai báo port server ESP8266WebServer webServer3(1605);//khai báo ghi log const int ledPin = 4; //d2
int timezone= 7*60*60; int dst=0;
//class SensorThread: public Thread //{
//public: //int value; //int pin; //void run(){
// Reads the analog pin, and saves it localy //value = map(analogRead(pin), 0,1023,0,255); //runned();
54
//} //};
//=============== Access Point Mode ===================== chế độ điểm phát wifi
char* ssid_ap = "Tukem"; //tên wifi tủ kêm phát ra
char* pass_ap = "12345678"; //mật khẩu wifi tủ kem phát ra //char* pass_login = "123"; //mật khẩu wifi tủ kem phát ra IPAddress ip_ap(192,168,1,200); //IP mặc định của wifi tủ kem IPAddress gateway_ap(192,168,0,1);
IPAddress subnet_ap(255,255,255,0);
//================= Station Mode ==================== String ssid; //Khai báo dữ liệu dạng chuỗi dưới tên biến "ssid" String pass; //Khai báo dữ liệu dạng chuỗi dưới tên biến "pass" String seri; //Khai báo dữ liệu dạng chuỗi dưới tên biến "seri" String addr; //Khai báo dữ liệu dạng chuỗi dưới tên biến "addr" String pass_login1 = "123";
String passwordlogin; String oldpass;
String newpass; String passcomfirm;
// const char* serverName = addr.c_str();
// const char* serverName = "http://14.225.27.59:1605"; //địa chỉ server để cập nhật log
//const char* serverName2 = "http://ctbus.cf:1605/device/update/wifi"; //địa chỉ server để update thông tin wifi
55
//================== phân luồng =========== unsigned long preTimeThread1 = millis();
unsigned long intervalThread1 = 15000; unsigned long preTimeThread4 = millis(); unsigned long intervalThread4 = 1000;
//========================================================== =========================================================== =========================================================== ======== char hex[256]; uint8_t data[256]; int start = 0; int seconds = 0; uint8_t hash[32]; String pin; #define SHA256_BLOCK_SIZE 32 typedef struct { uint8_t data[64]; uint32_t datalen;
unsigned long long bitlen; uint32_t state[8];
} SHA256_CTX;
void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len); void sha256_final(SHA256_CTX *ctx, uint8_t hash[]);
56
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
static const uint32_t k[64] = { 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f8 2a4,0xab1c5ed5, 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bd c06a7,0xc19bf174, 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a 9dc,0x76f988da, 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca 6351,0x14292967, 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c 2c92e,0x92722c85, 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e 3585,0x106aa070,
57 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9c ca4f,0x682e6ff3, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3 f7,0xc67178f2 };
void sha256_transform(SHA256_CTX *ctx, const uint8_t data[]) { uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = ((uint32_t)data[j] << 24) | ((uint32_t)data[j + 1] << 16) | ((uint32_t)data[j + 2] << 8) | ((uint32_t)data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0]; b = ctx->state[1]; c = ctx->state[2]; d = ctx->state[3]; e = ctx->state[4]; f = ctx->state[5]; g = ctx->state[6]; h = ctx->state[7]; for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; t2 = EP0(a) + MAJ(a,b,c);
58 h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2; } ctx->state[0] += a; ctx->state[1] += b; ctx->state[2] += c; ctx->state[3] += d; ctx->state[4] += e; ctx->state[5] += f; ctx->state[6] += g; ctx->state[7] += h; } void sha256_init(SHA256_CTX *ctx) { ctx->datalen = 0; ctx->bitlen = 0; ctx->state[0] = 0x6a09e667; ctx->state[1] = 0xbb67ae85; ctx->state[2] = 0x3c6ef372; ctx->state[3] = 0xa54ff53a; ctx->state[4] = 0x510e527f;
59
ctx->state[5] = 0x9b05688c; ctx->state[6] = 0x1f83d9ab; ctx->state[7] = 0x5be0cd19; }
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len) { uint32_t i;
for (i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i]; ctx->datalen++; if (ctx->datalen == 64) { sha256_transform(ctx, ctx->data); ctx->bitlen += 512; ctx->datalen = 0; } } }
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]) { uint32_t i;
i = ctx->datalen;
// Pad whatever data is left in the buffer. if (ctx->datalen < 56) {
ctx->data[i++] = 0x80; while (i < 56)
60 } else { ctx->data[i++] = 0x80; while (i < 64) ctx->data[i++] = 0x00; sha256_transform(ctx, ctx->data); memset(ctx->data, 0, 56); }
// Append to the padding the total message's length in bits and transform. ctx->bitlen += ctx->datalen * 8; ctx->data[63] = ctx->bitlen; ctx->data[62] = ctx->bitlen >> 8; ctx->data[61] = ctx->bitlen >> 16; ctx->data[60] = ctx->bitlen >> 24; ctx->data[59] = ctx->bitlen >> 32; ctx->data[58] = ctx->bitlen >> 40; ctx->data[57] = ctx->bitlen >> 48; ctx->data[56] = ctx->bitlen >> 56; sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash. for (i = 0; i < 4; ++i) {
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
61
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; }
}
char *btoh(char *dest, uint8_t *src, int len) { char *d = dest;
while( len-- ) sprintf(d, "%02x", (unsigned char)*src++), d += 2; return dest;
}
String SHA256(String data) {
uint8_t data_buffer[data.length()];
for(int i=0; i<data.length(); i++) { data_buffer[i] = (uint8_t)data.charAt(i); } SHA256_CTX ctx; ctx.datalen = 0; ctx.bitlen = 512; sha256_init(&ctx);
sha256_update(&ctx, data_buffer, data.length()); sha256_final(&ctx, hash);
62 return(btoh(hex, hash, 32)); } //========================================================== =========================================================== =========================================================== ========
//================== giao diện web thiết bị ============= const char MainPage[] PROGMEM = R"=====(
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Trang chủ</title> <style> .loader { border: 16px solid #f3f3f3; border-radius: 50%; border-top: 16px solid #3498db; width: 120px; height: 120px;
-webkit-animation: spin 2s linear infinite; /* Safari */ animation: spin 2s linear infinite;
} @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } }
63 @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .form { background: rgb(224, 246, 255); right: 0%; } .tittle {
font: 100px Segoe UI; text-align: center; font-weight: bold; }
h4 {
font: 50px Segoe UI; text-align: center; font-weight: bold; }
input {
font: 40px Segoe UI; border-radius: 10px; padding: 10px; border: 2px solid;
64 } button { background-color: skyblue; border-radius: 10px; border: none; font-size: 40px; width: 100%; padding: 10px; font-weight: bold; } label {
font: 40px Segoe UI; } button:hover, .detail:hover { opacity: 0.6; } .margin-top { margin-top: 6pt; } .margin-top-first { margin-top: 12pt; } span {
65
font: 30px Segoe UI; }
p {
font: 40px Segoe UI; padding-bottom: 10px; } </style> </head> <body> <div class="background"> <div class="form">
<div style="text-align: center;">
<span class="tittle">Apatm</span><br> <span>Thiết lập thông tin tủ kem</span> </div>
<div id="form-login">
<div class="margin-top-first">
<label for="passwordlogin"><strong>Mật Khẩu:</strong></label> </div>
<div class="margin-top">
<input type = "password" id="passwordlogin" placeholder="Nhập Mật Khẩu" />
</div>
<div class="margin-top">
<button onclick="login()">Đăng Nhập</button> </div>
66
<div id="form-changepass" style="display: none;"> <div class="margin-top-first">
<label for="oldpass"><strong>Mật Khẩu Cũ:</strong></label> </div>
<div class="margin-top">
<input id="oldpass" placeholder="Nhập Mật Khẩu Cũ" /> </div>
<div class="margin-top-first">
<label for="newpass"><strong>Mật Khẩu Mới:</strong></label> </div>
<div class="margin-top">
<input id="newpass" placeholder="Nhập Mật Khẩu Mới" /> </div>
<div class="margin-top-first">
<label for="passcomfirm"><strong>Xác Nhận Mật Khẩu:</strong></label> </div>
<div class="margin-top">
<input id="passcomfirm" placeholder="Nhập Mật Khẩu Xác Nhận" /> </div>
<div class="margin-top">
<button onclick="savepass()">Lưu</button> </div>
</div>
<div id="form-load" class="margin-top" style="text-align: center; display: none;">
<div class="loader"></div> </div>
67
<div id="form-setup" style="display: none;"> <div class="margin-top-first">
<label for="ssid"><strong>Tên Wifi:</strong></label> </div>
<div class="margin-top">
<input id="ssid" placeholder="Nhập Tên" /> </div>
<div class="margin-top-first">
<label for="pass"><strong>Password Wifi:</strong></label> </div>
<div class="margin-top">
<input type="password" id="pass" placeholder="Nhập Password" /> </div>
<div class="margin-top">
<label for="seri"><strong>Seri Number:</strong></label> </div>
<div class="margin-top">
<input id="seri" placeholder="Nhập Seri Number" /> </div>
<div class="margin-top">
<label for="addr"><strong>Địa chỉ server quản lý:</strong></label> </div>
<div class="margin-top">
<input id="addr" placeholder="Nhập địa chỉ" /> </div>
68
<div class="margin-top-first">
<button onclick="writeEEPROM()">Nhập</button> </div>
<div class="margin-top">
<button onclick="restartESP()">Khởi động lại</button> </div>
<div class="margin-top">
<button onclick="clearEEPROM()">Khôi phục cài đặt</button> </div>
<div id class="margin-top-first" style="text-align: center;"> <span>IP connected: </span><span id="ipconnected"></span> </div>
<div id style="text-align: center;">
<span style="font-size: 16px; font: Segoe UI;" id="showTemp"></span> </div>
<div>
<p>Trạng thái: </p> <p>
<a href="/off1"><button class="margin-top">ON</button></a> <a href="/on1"><button class="margin-top">OFF</button></a> </p>
<span id="reponsetext"></span> </div>
69
<div class="margin-top" id="btnchangepass">
<button onclick="changepass()">Thay Đổi Mật Khẩu</button> </div>
</div> </div>
<script>
<!-- Tạo đối tượng request --> function create_obj(){ td = navigator.appName;
if(td == "Microsoft Internet Explorer"){
obj = new ActiveXObject("Microsoft.XMLHTTP"); }else{
obj = new XMLHttpRequest(); } return obj; } var xhttp = create_obj(); <!-- Nhận Respone IP --> window.onload = function(){ xhttp.open("GET","/getIP",true);
xhttp.onreadystatechange = process_ip;//nhận reponse xhttp.send();
}
70
function process_ip(){
if(xhttp.readyState == 4 && xhttp.status == 200){ <!-- Update data sử dụng javascript -->
ketqua = xhttp.responseText; document.getElementById("ipconnected").innerHTML=ketqua; } } setInterval(function ( ) {
xhttp.open("GET", "/chotaoxem", true);
xhttp.onreadystatechange = process;//nhận reponse xhttp.send();
}, 1000) ;
<!-- ////////////////////////////////////////////////////// --> function login() {
var passwordlogin = document.getElementById("passwordlogin").value; xhttp.open("GET","/login?passwordlogin="+passwordlogin,true);
xhttp.onreadystatechange = processlogin;//nhận reponse xhttp.send(); } function changepass() { document.getElementById("form-changepass").style.display = "block"; document.getElementById("form-login").style.display = "none"; document.getElementById("form-setup").style.display = "none"; document.getElementById("btnchangepass").style.display = "none";
71
}
function savepass() {
var oldpass = document.getElementById("oldpass").value; var newpass = document.getElementById("newpass").value;
var passcomfirm = document.getElementById("passcomfirm").value;
xhttp.open("GET","/savepass?oldpass="+oldpass+"&newpass="+newpass+"&passc omfirm="+passcomfirm,true);
xhttp.onreadystatechange = processchangepass;//nhận reponse xhttp.send();
}
function writeEEPROM(){
var ssid = document.getElementById("ssid").value; var ssid = encodeURIComponent(ssid);
var pass = document.getElementById("pass").value; var seri = document.getElementById("seri").value; var addr = document.getElementById("addr").value; if (!/[^\s]/.test(ssid) === true) {
alert("Vui lòng nhập tên wifi !!!"); return;
} else if (!/[^\s]/.test(pass) === true) { alert("Vui lòng nhập mật khẩu wifi !!!"); return;
} else if (!/[^\s]/.test(seri) === true) { alert("Vui lòng nhập seri number!!!"); return;
72
alert("Vui lòng nhập địa chỉ server !!!"); return;
}
xhttp.open("GET","/writeEEPROM?ssid="+ssid+"&pass="+pass+"&seri="+seri+" &addr="+addr,true);
xhttp.onreadystatechange = process;//nhận reponse xhttp.send();
}
function clearEEPROM(){
xhttp.open("GET","/clearEEPROM",true);
xhttp.onreadystatechange = process;//nhận reponse xhttp.send();
}
function restartESP(){
xhttp.open("GET","/restartESP",true);
xhttp.onreadystatechange = process;//nhận reponse xhttp.send();
}
function seri(){
xhttp.open("GET","/seri",true);
xhttp.onreadystatechange = process_seri;//nhận reponse xhttp.send();
}
function process_seri(){
if(xhttp.readyState == 4 && xhttp.status == 200){ ketqua = xhttp.responseText;
document.getElementById("ttseri").innerHTML=ketqua; }
73
}
function process_temp(){
if(xhttp.readyState == 4 && xhttp.status == 200){ ketqua = xhttp.responseText;
document.getElementById("showTemp").innerHTML=ketqua; }
}
function process(){
if(xhttp.readyState == 4 && xhttp.status == 200){ ketqua = xhttp.responseText;
document.getElementById("reponsetext").innerHTML=ketqua; }
}
function processlogin(){
if(xhttp.readyState == 4 && xhttp.status == 200){ ketqua = xhttp.responseText; document.getElementById("form-load").style.display = "block"; if(ketqua == "0"){ document.getElementById("form-setup").style.display = "block"; document.getElementById("form-login").style.display = "none"; document.getElementById("form-load").style.display = "none"; } if(ketqua == "-1"){ document.getElementById("form-load").style.display = "none"; } } } function processchangepass(){
74
if(xhttp.readyState == 4 && xhttp.status == 200){ ketqua = xhttp.responseText; if(ketqua == "0"){ alert("Success"); document.getElementById("form-changepass").style.display = "none"; document.getElementById("form-login").style.display = "block"; document.getElementById("btnchangepass").style.display = "block"; } if(ketqua == "-1"){ alert("Fail"); } } } </script> </body> </html> )====="; //=========================================
// Replaces placeholder with LED state value String processor(const String& var){
Serial.println(var); if(var == "STATE"){ if(digitalRead(ledPin)){ ledState = "ON"; } else{ ledState = "OFF"; }
75
Serial.print(ledState); return ledState; }
String myStr;
const int Pin = 5; // Chân nhận tín hiệu trạng thái máy D1 int buttonState = LOW; // Tín hiệu mặc định là LOW
// chương trình set up chỉ chạy 1 lần khi mạch khởi động void setup() { //=========== Cài đặt Serial ====================== Serial.begin(115200); //mySerial.begin(115200); pinMode(ledPin, OUTPUT); pinMode(Pin, INPUT);
//================== Cài đặt thời gian ========= configTime(timezone,dst,"pool.ntp.org","time.nist.gov"); Serial.println("Waiting for NTP Server");
while(!time(nullptr)){ Serial.print("#"); delay(500); }
//============ Khởi tạo bộ nhớ EEPROM ================ EEPROM.begin(512);
delay(10);
76
if(read_EEPROM()){
checkConnection(); //kiểm tra xem đã có thơng tin wifi hay chưa delay(30000); api_start(); //wifi(); } else{ WiFi.disconnect(); WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip_ap, gateway_ap, subnet_ap); WiFi.softAP(ssid_ap,pass_ap);
Serial.println("Soft Access Point mode!"); Serial.print("Please connect to ");
Serial.println(ssid_ap);
Serial.print("Web Server IP Address: "); Serial.println(ip_ap);
WiFi.macAddress(); }
//================ cài đặt server ============= // kết nối id trên javascript xuống code C bên dưới
webServer.on("/",mainpage); webServer.on("/getIP",get_IP); webServer.on("/chotaoxem", fetchTemp); webServer.on("/seri", se_ri); webServer.on("/writeEEPROM",write_EEPROM); webServer.on("/restartESP",restart_ESP); webServer.on("/clearEEPROM",clear_EEPROM); webServer.on("/login",lo_gin); webServer.on("/savepass",change_pass);
77
////////////////////////////////////// // Route to set GPIO to HIGH