วันอังคารที่ 28 พฤษภาคม พ.ศ. 2562

โปรเจค IoT ESP8266 NodeMCU เปิด ปิด ไฟ ผ่านเว็บ



ในช่วงไม่กี่ปีที่ผ่านมา ESP8266 เป็นดาวเด่นในโครงการ IoT หรือ ที่เกี่ยวข้อง WiFi  ซึ่ง ESP8266 NodeMCU  เป็นโมดูล WiFi ที่คุ้มค่ามาก โดยสามารถเชียนโปรแกรมเพื่อสร้างเว็บเซิร์ฟเวอร์แบบสแตนด์อโลนได้


โหมดการทำงานของ ESP8266

หนึ่งในคุณสมบัติที่ยอดเยี่ยมที่สุดของ ESP8266 คือไม่เพียง แต่เชื่อมต่อกับเครือข่าย WiFi ที่มีอยู่และทำหน้าที่เป็นเว็บเซิร์ฟเวอร์ แต่ยังสามารถตั้งค่าเครือข่ายของตัวเอง เพื่อให้อุปกรณ์อื่น ๆ สามารถเชื่อมต่อโดยตรงและเข้าถึงได้โดยเว็บเพจ สิ่งนี้เป็นไปได้เพราะ ESP8266 สามารถทำงานในโหมดต่าง ๆ ได้ 3 โหมด คือ โหมด AP โหมด STA และโหมด AP & STA โดยในแต่ละโหมดมีความแตกต่างกันดังนี้


  • โหมด AP - เป็นโหมดที่จะต้องรอให้มีอุปกรณ์มาเชื่อมต่อจึงจะสามารถรับส่งข้อมูลกันได้
  • โหมด STA - เป็นโหมดที่กำหนดให้ ESP8266 ไปเชื่อมต่อกับอุปกรณ์อื่น ๆ เช่น เร้าเตอร์ แล้วรับส่งข้อมูลระหว่างเครื่องในวงแลนได้
  • โหมด AP & STA - เป็นโหมดที่สามารถทำงานได้ทั้ง 2 อย่างภายในเวลาเดียวกัน แต่ความสเถียรจะลดลง และทำให้ใช้กำลังไฟฟ้ามากขึ้น
  • ในการใช้งานควบคุมอุปกรณ์ต่าง ๆ ที่อยู่ในระยะใกล้ และต้องย้ายสถานที่ใช้งานที่บ่อย เช่น นำไปใช้งานควบคุมหุ่นนต์ ควรจะใช้งานในโหมด AP


แบบ Station (STA) Mode


โหมด STA - เป็นโหมดที่กำหนดให้ ESP8266 ไปเชื่อมต่อกับอุปกรณ์อื่น ๆ เช่น เร้าเตอร์ แล้วรับส่งข้อมูลระหว่างเครื่องในวงแลนได้





แบบ Soft Access Point (AP) Mode


ESP8266 ที่สร้างเครือข่าย WiFi ของตัวเองและทำหน้าที่เป็นฮับ (เช่นเดียวกับเราเตอร์ WiFi) สำหรับสถานีหนึ่งสถานีหรือมากกว่านั้นเรียกว่าจุดเชื่อมต่อ (AP) ไม่เหมือนกับเราเตอร์ WiFi มันไม่มีส่วนต่อประสานกับเครือข่ายต่อสาย ดังนั้นโหมดการทำงานดังกล่าวจึงเรียกว่า Soft Access Point (soft-AP) นอกจากนี้จำนวนสถานีสูงสุดที่สามารถเชื่อมต่อได้จะถูก จำกัด ไว้ที่ 5 เท่านั้น




โหมด AP - เป็นโหมดที่จะต้องรอให้มีอุปกรณ์มาเชื่อมต่อจึงจะสามารถรับส่งข้อมูลกันได้ ในโหมด AP นั้น ESP8266 จะสร้างเครือข่าย WiFi ใหม่และตั้งค่า SSID (ชื่อเครือข่าย) และ IP ให้กับมัน ด้วย IP นี้มันสามารถส่งผ่านหน้าเว็บไปยังอุปกรณ์ที่เชื่อมต่อทั้งหมดภายในเครือข่ายของตัวเอง


ขั้นตอนการทำงาน


1. เรียนรู้การใช้งาน ESP8266 NodeMCU เบื้องต้นตามลิงค์ด้านล่าง



2. เชื่อมต่อ LED กับ ESP8266 NodeMCU


รายการอุปกรณ์ที่ใช้ (รายละเอียดคลิกตามลิงค์สินค้า)







3. โค้ดการทำงานแบบ โหมด AP


ข้อดีคือ IP นี้มันที่ส่งให้แสดงผ่านหน้าเว็บ จะเป็น IP เดิม ไม่เปลี่ยนแปลง ข้อเสียคือกำหนดจุดเชื่อมต่อในเครือข่ายไม่เกิน 5 จุด



อัพโหลดโค้ดด้านล่างนี้ไปยัง ESP8266 NodeMCU
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

/* Put your SSID & Password */
const char* ssid = "NodeMCU";  // Enter SSID here
const char* password = "12345678";  //Enter Password here

/* Put IP Address details */
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

uint8_t LED1pin = D7;
bool LED1status = LOW;

uint8_t LED2pin = D6;
bool LED2status = LOW;

void setup() {
  Serial.begin(115200);
  pinMode(LED1pin, OUTPUT);
  pinMode(LED2pin, OUTPUT);

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);
  
  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}
  
  if(LED2status)
  {digitalWrite(LED2pin, HIGH);}
  else
  {digitalWrite(LED2pin, LOW);}
}

void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status)); 
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO7 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status)); 
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO7 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status)); 
}

void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO6 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,true)); 
}

void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led1stat,uint8_t led2stat){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #16a085;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP8266 Web Server</h1>\n";
  ptr +="<h3>Using Access Point(AP) Mode</h3>\n";
  
   if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

  if(led2stat)
  {ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
  else
  {ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}


เลือกชนิดของบอร์ด : ไปที่ Tools > Board : เลือกเป็น NodeMCU 0.9 (ESP-12 Module)



เลือกพอร์ตการใช้งาน : ไปที่ Tools > Port แล้วเลือกพอร์ตที่ปรากฏ ในตัวอย่างเลือกเป็น "COM12"


กดปุ่ม   เพื่ออัพโหลด หากสามารถอัพโหลดโปรแกรมลงบอร์ดได้สำเร็จ จะแสดงคำว่า Done uploading. ที่แถบด้านล่าง

เปิดหน้าต่าง Serial Monitor  โดยไปที่ Tools > Serial Monitor



มุมขวาล่าง ของ Serial Monitor เลือก 115200 baud  คือ ตั้งค่าความเร็วในการรับ-ส่งข้อมูล  คือ 115200



แตะปุ่ม RST ที่บอร์ด ESP8266 NodeMCU เพื่อเริ่มต้นการทำงานของ ESP8266  รอจนกระทั่งที่ Serial Monitor แสดงข้อความ HTTP server started




ใช้ สมาร์ทโฟน ไปที่การตั้งค่า -> Wi-Fi




เลือกเครือข่าย Wi-Fi เป็น NodeMCU




   


รหัสผ่านเครือข่าย = 12345678  -> เชื่อมต่อ

 



แสดงการเชื่อมต่อเครือข่าย Wi-Fi เป็น NodeMCU





เปิดเว็บบราวเซอร์ ที่ URL ป้อนไอพี :  192.168.1.1

แล้วทดสอบการทำงาน




ที่ Serial Monitor จะแสดงสถานะ การเปิด ปิด ไฟ ของเรา


วีดีโอผลลัพธ์ โปรเจค IoT ESP8266 NodeMCU เปิด ปิด ไฟ ผ่านเว็บ





4. โค้ดการทำงานแบบ โหมด STA

ข้อดีคือ เชื่อมต่อให้แสดงผ่านหน้าเว็บ ได้หลายๆเครื่อง เท่าที่ความสามารถของเครือข่าย  ข้อเสียคือต้องตรวจสอบ IP ที่จะให้แสดงผ่านหน้าเว็บ เพราะการเชื่อมต่อแต่ละครั้งอาจจะได้ IP ไม่เหมือนกัน


*** ก่อนอัพโหลดโค้ดต้องแก้ไข *** 



ssid = "
เครือข่าย Wi-Fi ที่ต้องการเชื่อมต่อ"

password = "
รหัสผ่านเครือข่าย"






โค้ดต้นฉบับที่ยังไม่ได้แก้ไข
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

/*Put your SSID & Password*/
const char* ssid = "YourNetworkName";  // Enter SSID here
const char* password = "YourPassword";  //Enter Password here

ESP8266WebServer server(80);

uint8_t LED1pin = D7;
bool LED1status = LOW;

uint8_t LED2pin = D6;
bool LED2status = LOW;

void setup() {
  Serial.begin(115200);
  delay(100);
  pinMode(LED1pin, OUTPUT);
  pinMode(LED2pin, OUTPUT);

  Serial.println("Connecting to ");
  Serial.println(ssid);

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop() {
  server.handleClient();
  if(LED1status)
  {digitalWrite(LED1pin, HIGH);}
  else
  {digitalWrite(LED1pin, LOW);}
  
  if(LED2status)
  {digitalWrite(LED2pin, HIGH);}
  else
  {digitalWrite(LED2pin, LOW);}
}

void handle_OnConnect() {
  LED1status = LOW;
  LED2status = LOW;
  Serial.println("GPIO7 Status: OFF | GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,LED2status)); 
}

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO7 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status)); 
}

void handle_led1off() {
  LED1status = LOW;
  Serial.println("GPIO7 Status: OFF");
  server.send(200, "text/html", SendHTML(false,LED2status)); 
}

void handle_led2on() {
  LED2status = HIGH;
  Serial.println("GPIO6 Status: ON");
  server.send(200, "text/html", SendHTML(LED1status,true)); 
}

void handle_led2off() {
  LED2status = LOW;
  Serial.println("GPIO6 Status: OFF");
  server.send(200, "text/html", SendHTML(LED1status,false)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t led1stat,uint8_t led2stat){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr +=".button-on {background-color: #1abc9c;}\n";
  ptr +=".button-on:active {background-color: #16a085;}\n";
  ptr +=".button-off {background-color: #34495e;}\n";
  ptr +=".button-off:active {background-color: #2c3e50;}\n";
  ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<h1>ESP8266 Web Server</h1>\n";
    ptr +="<h3>Using Station(STA) Mode</h3>\n";
  
   if(led1stat)
  {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
  else
  {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

  if(led2stat)
  {ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
  else
  {ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}



ทำการแก้ไข แล้วอัพโหลดโค้ดที่แก้ไขแล้ว ไปยัง ESP8266 NodeMCU



เปิดหน้าต่าง Serial Monitor  โดยไปที่ Tools > Serial Monitor



แตะปุ่ม RST ที่บอร์ด ESP8266 NodeMCU เพื่อเริ่มต้นการทำงานของ ESP8266 



รอจนกระทั่งที่ Serial Monitor แสดง ชื่อเครือข่าย Wi-Fi และ IP ที่นำไปใช้งาน ในตัวอย่างนี้คือ  192.168.1.41

(ก่อนทดสอบการทำงงานควรตรวจสอบ IP ทุกครั้ง เพราะแต่ละครั้งในการเชื่อมต่ออาจได้ IP ไม่เหมือนเดิม)


ใช้โทรศัพท์มือถือ (Mobile)  หรือ คอมพิวเตอร์ (PC)  เชื่อมต่อ WiFi ชื่อเดียวกัน กับการทำงานในข้อที่ 4  แล้วเปิดเว็บบราวเซอร์ ที่ URL ป้อนไอพีที่ได้ ในตัวอย่างคือ :  192.168.1.41

     


คอมพิวเตอร์ PC เครื่องอื่นๆ ที่เชื่อมต่อเครือข่ายเดียวกันก็สามารถเรียกใช้หน้าเว็บ ได้เช่นเดียวกัน



ทดสอบการทำงาน ที่ Serial Monitor จะแสดงสถานะ การเปิด ปิด ไฟ ของเรา



ผลลัพธ์การทำงานจะเหมือนกับ วีดีโอผลลัพธ์ แบบโหมด AP เช่นเดียวกัน


credit : https://lastminuteengineers.com/creating-esp8266-web-server-arduino-ide/




ไม่มีความคิดเห็น:

แสดงความคิดเห็น

โปรเจค IoT ESP8266 วัดอุณหภูมิความชื้น บันทึกลงดาต้าเบส MySQL

เป้าหมายของโปรเจคนี้คือเราต้องดูข้อมูลด้วยการเข้าถึงโดเมน ของเราเอง ไม่ว่าจะอยู่ส่วนไหนของโลก โดย ESP8266 จะสร้างไคลเอ็นต์  ที่ทำให้คำขอ...