ESP8266 OTA & WiFi Manager

เรื่องที่ลิสต์ว่าจะเขียนไว้นี่เพียบเลย เมื่อวานนี้ย้อนไปอ่านๆของเก่าแล้วมีท่านหนึ่ง Comment ไว้ว่าอยากให้เขียนเรื่อง OTA ซึ่งก็ถือว่าเป็นเรื่องสำคัญเหมือนกันสำหรับงานด้าน iot ถ้าเป็นสมัยก่อนเวลาจะ update เครื่องโทรศัพท์มือถือก็ต้องมานั่งต่อสาย data link แล้ว flash rom กันทีละเครื่องแล้วก็นั่งลุ้นกันว่าจะ Boot ได้มั้ย แต่สมัยนี้อุปกรณ์ที่เป็น connected device ก็มักจะรองรับการ update แบบ OTA (Over The Air) กันแล้วทั้งนั้น

ถ้าเราทำโครงการทางด้าน iot แล้วต้องการ Update โปรแกรมของเรา ถ้าต้องมานั่งต่อสาย Upload โปรแกรมกันก็คงไม่สะดวก ง่ายขึ้นมาหน่อยก็เขียนโปรแกรมให้รองรับการ Upload ผ่าน WiFi แต่กรณีที่อุปกรณ์ของเรามีหลายตัว และอยู่กันคงละที่ การเดินทางไป Update ทุกๆตัว ทุกๆที่ อาจจะไม่สนุกแน่ๆ ดังนั้น OTA Update จึงตอบโจทย์งานลักษณะนี้มาก ซึ่งในส่วนของอุปกรณ์ประเภท Smart Phone นั้นก็มีให้เห็นกันนานแล้ว และวันนี้เราจะมาทดลองกัน

ในส่วนของอุปกรณ์ที่เราจะใช้ในวันนี้ก็คือ Nodemcu (ESP8266) นั่นเอง ใครจะใช้ Wemos D1 mini, ESP-01, ESP-07 หรือ ESP-12E ก็ได้เพราะที่ว่ามาทั้งหมดเป็นตระกูล ESP8266 ของ Espressif ทั้งนั้น

 

Library ที่ใช้ก็จะเป็น WiFi Manager ของ Tzapu สามารถติดตั้งได้จาก Library Manager ได้เลยครับ

ขั้นตอนของเราที่จะทำการทดลองจะมีแค่ 2 Step ง่ายๆแค่นั้นเองครับ

ขั้นตอนที่ 1: Compile Code ที่จะทำการ Update แล้วใส่ไว้ที่ WebServer / Nas / Storage Server ที่สามารถเข้าถึงได้ผ่าน Internet หรือ ​Network ที่ Nodemcu เราเชื่อมต่ออยู่

#if defined(ESP8266)
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#else
#include <WiFi.h>          //https://github.com/esp8266/Arduino
#endif


#include <DNSServer.h>
#if defined(ESP8266)
#include <ESP8266WebServer.h>
#else
#include <WebServer.h>
#endif
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager


void setup() {
  
  Serial.begin(115200);

  WiFiManager wifiManager;
  
  wifiManager.autoConnect("AutoConnectAP");
  
  Serial.println("connected...yeey :)");

  pinMode(LED_BUILTIN, OUTPUT);

  Serial.println("Connected: "+String(WiFi.SSID()));
  Serial.println("with Password: "+String(WiFi.psk()));
  Serial.println("IP "+WiFi.localIP().toString());
  
}

void loop() {

  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);

}

Code ด้านบนก็มาจากตัวอย่างของ WiFi Manager แหละครับ แต่ผมโมเพิ่มในส่วนของ Serial.println ที่ใช้แสดงผลว่า Connect ที่ WiFi AP ชื่ออะไร ด้วย password อะไรและได้ IP อะไรมา แล้วก็เพิ่มในส่วนของ loop ที่ให้ ไฟบนบอร์ดกระพริบแค่นั้นเอง จากนั้นก็ Save –> Compile และ Export Compiled Binary File ของโปรแกรมของเราครับ ยังไม่ต้อง flash/upload ไปที่บอร์ดของเรานะครับ

ซึ่ง binary ไฟล์ของโปรแกรมที่ export จะอยู่ที่ folder เดียวกับ code ของโปรแกรมเรา จากนั้นก็ rename ไฟล์ .bin ของเราให้เป็นอะไรก็ได้ง่ายๆหน่อย จะ Update.bin หรือจะเป็นวันที่ Version อะไรก็ได้ครับ แล้ว Upload ไปที่ Web Server หรือ Storage Server ที่สามารถเข้าถึงผ่าน Internet/Network ได้

 

ขั้นตอนที่ 2: Compile / Upload โปรแกรมที่มีชุดคำสั่ง OTA เข้าไปที่ Nodemcu

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

 

ซึ่งผมก็เอาโค้ดจากตัวอย่างนี้มาโมรวมเข้ากับ WiFi Manager ก่อนหน้านี้ แล้วก็ลบในส่วนของไฟกระพริบใน loop ออกก็จะได้โค้ดตามด้านล่างนี้ครับ

#include <Arduino.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#else
#include <WiFi.h>          //https://github.com/esp8266/Arduino
#endif

#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>

#include <DNSServer.h>
#if defined(ESP8266)
#include <ESP8266WebServer.h>
#else
#include <WebServer.h>
#endif
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

void exe_ota()
{

  Serial.println("Start Update");


  t_httpUpdate_return ret = ESPhttpUpdate.update("http://www.xxxxxx.com/updates/Update2.bin"); //<--- ส่วนนี้ต้องแก้เป็น url/address ของไฟล์ที่เราต้องการ download มา update นะครับ


  switch (ret) {
    case HTTP_UPDATE_FAILED:
      Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
      break;

    case HTTP_UPDATE_NO_UPDATES:
      Serial.println("HTTP_UPDATE_NO_UPDATES");
      break;

    case HTTP_UPDATE_OK:
      Serial.println("HTTP_UPDATE_OK");
      break;
  }

}

void setup() {

  Serial.begin(115200);

  WiFiManager wifiManager;

  wifiManager.autoConnect("AutoConnectAP");

  Serial.println("connected...yeey :)");

  

  Serial.println("Connected: " + String(WiFi.SSID()));
  Serial.println("with Password: " + String(WiFi.psk()));
  Serial.println("IP " + WiFi.localIP().toString());

}

void loop() {

  delay(3000);

  if (WiFi.status() == WL_CONNECTED)
    exe_ota();
}

 

เสร็จแล้วก็ Save, Compile, Flash/Upload โค้ดของเราไปที่บอร์ดเลยครับ เพียงแต่ว่าการ Upload นั้นครั้งนี้ให้เลือกเป็นแบบ “All Flash Content” เพื่อที่จะได้เคลียร์ค่า Config ต่างๆก่อนหน้านี้ที่เขียนในส่วนของ SPIFFS ไว้ด้วย

 

เมื่อ Upload โค้ดของเราเรียบร้อยก็จะเข้ามาสู่ในส่วนของ WiFi Manager กันเพื่อ Config ค่า WiFi ข้อดีก็คือไม่ต้อง Hard Code กันตั้งแต่แรก สะดวกสบาย สามารถที่จะ Config ให้ใสค่า Line Token, Blink Token, หรือแม้กระทั่ง MQTT Config ของเราก็ได้ครับ ขึ้นอยู่ใครจะประยุกต์ใช้

จากนั้นก็ connect wifi จากมือถือหรือ pc ของเราไปที่ SSID: AutoConnectAP ซึ่งค่า Default ของตัว Captive Portal ของ WiFi Manager ก็คือ 192.168.4.1 สามารถเข้าผ่าน Browser เพื่อ Config ได้เลยครับ

จากนั้นตัว Library ของ WiFi Manager ก็จะทำการ Connect WiFi ตามค่า SSID และ Password ที่เรากรอกข้อมูลไป และทำการ Save ค่านี้ลงไปในส่วนของ SPIFSS ด้วย เพื่อที่ตอนที่ Board Reset จะได้ไม่ติดในหน้าของ Captive Portal และนำค่า WiFi Setting เดิมมาทำการเชื่อมต่อได้ทันที ลองคิดดูว่าถ้าเราทำการ OTA Update ไปแล้วฝั่ง User ของเราต้องมานั่งตั้งค่า WiFi อีกคงไม่สนุกแน่ๆ

 

แต่เดี่ยวก่อน ทำไมบอร์ดของเรายังวาร์ป เอ้ยยย ยังไม่ไปดึง ไฟล์ Update.bin ที่เรา upload ไว้ที่ Web Server หละ???  ไม่ต้องตกใจครับนี่เป็น error ปกติเมื่อใช้งานในส่วนของ OTA Update เนื่องจากเรา Update ผ่านทาง Hardware Serial วิธีแก้ก็แค่กด reset ที่บอร์ดแค่นั้นเองครับ

หลังจากที่กด Reset ตัว Library  WiFi Manager ก็จะไปดึงค่า WiFi Setting เดิมก่อนหน้านี้มาเชื่อมต่อ จากนั้นก็จะเข้าสู่ขั้นตอนการ Download binary file ที่เราต้องการ Update มาและทำการ Update –> Reboot ซึ่งพอ Reboot เสร็จ เนื่องจาก Code ในขั้นตอนที่ 1 เราใช้ WiFi Manager เหมือนกัน ก็เข้าสู่การดึงค่าที่อยู่ใน SPIFSS ออกมาใช้งาน หลังจากนั้นบอร์ดของเราก็เข้าสู่ loop ในส่วนของไฟกระพริบต่อ ก็เป็นอันเรียบร้อยกับการทำ OTA Update ซึ่งการใช้งานจริง Code ที่ Update เสร็จก็ควรมีส่วนของ OTA Update อยู่ด้วยนะครับ เพื่อรองรับการ Update ในครั้งถัดไป

สำหรับใครที่ใช้ ESP32 ก็มีตัวอย่างที่มาพร้อมตอนติดตั้งเหมือนกัน ลักษณะการทำงานก็คล้ายๆกันเพียงแต่ในตัวอย่างเป็นการใช้งานผ่าน Amazon S3 สำหรับการ Update นั้นเราคงไม่เอาโค้ดใส่ไว้ใน loop แล้วให้ update ตลอดเวลา แต่อาจจะใช้ในการยิงคำสั่งผ่าน mqtt หรือให้เช็คทุกเที่ยงคืนว่าถ้ามีไฟล์วางอยู่บน Server ให้ทำการ Update ในส่วนของไฟล์ก็อาจใช้ ID เฉพาะของแต่ละ Node ก็ได้ ซึ่งก็มีหลายเทคนิคให้ทำครับ

ส่งท้ายบทความนี้กันหน่อย ช่วงนี้ทดลองกับ Battery ค่อนข้างเยอะ ก็อ่านและหาข้อมูลไปเรื่อย อ่านไปอ่านมา กลายเป็นว่าน่าจะต้องบรรจุเรื่องการทำ Power wall เข้าไปใน Project List ซะแล้วเนื่องจากแบตเตอรี่และ Solar Cell ที่มีราคาถูกลง ประสิทธิภาพดีขึ้น เผื่ออนาคตอาจไปสร้างกระต๊อบแบบ off-grid ที่ต่างจังหวัดใช้เพื่อทำเกษตรยามเกษียณ โดยไม่ต้องขอมิเตอร์หรือตั้งเสาจากการไฟฟ้า ^_^

Author: Joe D.S.
Just a man on earth

2 thoughts on “ESP8266 OTA & WiFi Manager

  1. พี่Joe เคยลอง PlatformIO แทน Arduino IDE ไหมครับ? มีความคิดเห็นอย่างไร?
    เพิ่งเจอ blog ของพี่วันนี้ตอนกำลังหาข้อมูล LoRa + ESP32
    น่าติดตามมากๆๆๆครับ Thank you for sharing your knowledge with all of us!

    1. เคยลงแต่ยังไม่เคยใช้งานจริงจังครับ ไว้มีโอกาสใช้จริงๆจังๆจะเอามาเขียนเล่าให้ฟังครับผม

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.