ESP32 Networking

ตัวอย่างการใช้งานไมโครไพธอนและบอร์ด ESP32 สำหรับเครือข่ายไร้สาย โดยใช้ MicroPython v1.13 (built on 2020-09-02)

1. ESP32 Networking

ESP32 สามารถเชื่อมต่อกับอุปกรณ์อื่นแบบไร้สายได้ โดยใช้ Wi-Fi ตามมาตรฐาน IEEE 802.11b/g/n (2.4GHz) และ Bluetooth และมีโหมดการทำงานสำหรับ Wi-Fi ดังนี้

  • STA (Station)

  • AP (Access Point)

  • Soft-AP (both STA and AP)

แต่ถ้าจะเชื่อมต่อกับ Ethernet จะต้องมีวงจร Ethernet PHY Transceiver (RMII Interface) นำมาต่อเพิ่ม เช่น LAN8720 หรือ TLK110 (10/100 Mbps) เป็นต้น ตัวอย่างบอร์ด ESP32 ที่มี Ethernet/LAN Port ได้แก่

สำหรับ ESP32 การเชื่อมต่อด้วย Wi-Fi คงเป็นวิธีที่ง่ายและสะดวกที่สุด โดยทั่วไปแล้ว เราจะโปรแกรมให้อุปกรณ์ ESP32 ทำงานในโหมด STA และเชื่อมต่อกับอุปกรณ์ Wi-Fi Access Point หรือ Router ในระบบเครือข่าย WLAN และทำให้สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้

ถ้าจะให้ ESP32 ทำงานในโหมด AP หรือ Soft-AP ก็อนุญาตให้อุปกรณ์อื่นเชื่อมต่อผ่าน Wi-Fi เข้ามายัง ESP32 ได้ เราอาจจะเห็นตัวอย่างการใช้งาน ESP32 ที่ทำงานในโหมดดังกล่าวและทำหน้าที่เป็น Light-weight Web Server ในตัวด้วย ทำให้คอมพิวเตอร์อื่นสามารถเชื่อมต่อผ่าน Wi-Fi มายัง ESP32 และผู้ใช้สามารถเปิด Web Browser เพื่อเข้าสู่หน้าเว็บของ ESP32 เช่น ใช้ในการตั้งค่าอุปกรณ์ผ่านหน้าเว็บ หรือดูสถานะบางอย่างของระบบ เป็นต้น

อีกตัวเลือกหนึ่งที่น่าสนใจสำหรับ ESP32 คือ การสื่อสารแบบไร้สายในรูปแบบที่เรียกว่า ESP-NOW โดยไม่จำเป็นต้องใช้ Wi-Fi Infrastructure แต่ใช้รูปแบบการทำงานแบบ Peer-to-Peer และในปัจจุบัน เราก็สามารถใช้ ESP-NOW (Micropython Port) ร่วมกับไมโครไพธอนได้เช่นกัน

2. ESP32 Wi-Fi Scan

เริ่มต้นตัวอย่างแรกด้วยการสแกนหาอุปกรณ์หรือเครือข่ายไร้สาย Wi-Fi โดยจะต้องทำให้ ESP32 เปิดใช้งานในโหมด STA ก่อน และสามารถใช้คำสั่งจากไลบรารี network ดังนี้ โดยทำการสแกนซ้ำไปเรื่อย ๆ และถ้าต้องการหยุดหรือจบการทำงาน ให้กด Ctrl+C ในหน้าต่าง Interactive Shell ของ REPL

เมื่อสแกนเครือข่าย Wi-Fi ข้อมูลสำหรับแต่ละอุปกรณ์ที่พบ จะประกอบด้วยชื่ออ้างอิงในการเชื่อมต่อ (SSID), หมายเลขของอุปกรณ์ (MAC address), ช่องสัญญาณความถี่ (Channel), ค่าตัวชี้วัดความแรงของสัญญาณที่รับได้ (RSSI), โหมดการเข้ารหัสสำหรับความปลอดภัย (Authentication Mode) และมีการซ่อนชื่อ SSID หรือไม่ (Hidden) ตามลำดับ

ลองมาดูตัวอย่างการเขียนโค้ดไมโครไพธอนที่ใช้สำหรับสแกนระบบเครือข่าย Wi-Fi ที่อยู่โดยรอบ แล้วแปลงผลที่ได้ให้เป็นข้อมูลแบบ JSON เช่น แสดงชื่อ SSID รหัสเครื่อง (MAC Address) โหมดการตั้งค่าความปลอดภัย (Authentication Mode) และช่องสัญญาณ เป็นต้น

3. Wi-Fi Connection in STA Mode

การเชื่อมต่อกับเครือข่าย Wi-Fi ในโหมด STA จะต้องระบุชื่อ SSID และรหัสผ่าน (Password) สำหรับเชื่อมต่ออุปกรณ์ไร้สาย เช่น Wireless Access Point / Router ตามตัวอย่างโค้ดต่อไปนี้

ในตัวอย่างนี้ มีการสร้างฟังก์ชันชื่อ connect_wifi() เพื่อใช้ในการเชื่อมต่อ Wi-Fi (STA Mode) เมื่อเรียกใช้ จะต้องระบุอาร์กิวเมนต์เป็นโครงสร้างข้อมูลแบบ dictionary อ้างอิงโดยตัวแปร WIFI_CFG ที่มีชื่อสมาชิก ‘ssid’ และ ‘pwd’ ตามลำดับ ดังนั้นให้กำหนดค่าให้ถูกต้องเมื่อนำไปใช้งาน

เมื่อเรียกใช้ฟังก์ชันนี้ และสามารถเชื่อมต่อได้สำเร็จ จะได้ค่ากลับคืนเป็นอ็อบเจกต์ที่ไม่ใช่ None และเราก็สามารถใช้คำสั่ง wifi.ifconfig() เพื่อดูข้อมูลเกี่ยวกับการเชื่อมต่อเครือข่าย เช่น หมายเลขของไอพีที่ได้รับ (IP address) หมายเลขของไอพีของอุปกรณ์ Gateway เป็นต้น

4. Wi-Fi in AP Mode + Simple HTTP Server

ตัวอย่างถัดไป สาธิตการเปิดใช้งาน Wi-Fi ในโหมด AP แบบ Open (ไม่มีการป้องกันด้วยรหัสผ่าน) โดยการสร้างและเรียกใช้ฟังก์ชัน start_wifi_ap() จากนั้นเมื่อ ESP32 ทำงานเป็น Wi-Fi AP แล้ว (จะมีหมายเลขไอพีตรงกับ 192.168.4.1 และเลือกใช้ช่องสัญญาณหมายเลข 11) ยังได้มีการสร้างและเรียกใช้ฟังก์ชัน start_web_server() เพื่อให้สามารถทำงานเป็น Web Server (HTTP protocol) อย่างง่ายได้ด้วย แสดงข้อความเป็นหน้าเว็บได้

ในตัวอย่างนี้ ถ้าต้องการจบการทำงานของ Web Server เราจะใช้วิธีตรวจสอบการกดปุ่ม ดังนั้นจะต้องมีการต่อวงจรกดปุ่มภายนอกแบบ Active-Low และเลือกใช้ขา GPIO23 เป็นอินพุตสำหรับปุ่มกด

ถ้าจะเปลี่ยนจาก Open เป็นการตั้งรหัสป้องกันด้วยวิธี WPA2-PSK ก็กำหนดค่าสำหรับ Configuration ตามตัวอย่างดังนี้

AP_CFG = { 'essid': 'MyAP', 'password': 'YOUR_STRONG_PASSWORD', 'authmode': network.AUTH_WPA2_PSK, 'channel':11, }

5. Getting Date & Time From NTP Server

ตัวอย่างถัดไปสาธิตการเปิดใช้งาน ESP32 ในโหมด STA และเชื่อมต่อกับอุปกรณ์ Wi-Fi AP ที่สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้ และใช้คำสั่ง ntptime.settime() เพื่อเชื่อมต่อกับคอมพิวเตอร์ในอินเทอร์เน็ตที่ทำหน้าที่เป็น NTP Server และอัปเดทเวลาปัจจุบันสำหรับการทำงานของวงจรของ RTC (Real-Time Clock) ของ ESP32

6. HTTP GET: Getting Datetime Using WorldTime API

ตัวอย่างถัดไปสาธิตการเปิดใช้งาน ESP32 ในโหมด STA และเชื่อมต่อกับอุปกรณ์ Wi-Fi AP ที่สามารถเชื่อมต่อไปยังอินเทอร์เน็ตได้ และร้องขอข้อมูลแบบ HTTP Request / GET Method ไปยัง World Time API ซึ่งเป็นผู้ให้บริการข้อมูลเกี่ยวกับวันและเวลาในปัจจุบันตามโซนเวลา (Timezone) ที่ระบุไว้ ข้อมูลที่ได้รับกลับมานั้น จะอยู่ในรูปแบบของ JSON String

ตัวอย่างเอาต์พุตที่ได้

Timezone: Asia/Bangkok Epoch time (Jan 1, 1970): 1609939805 UTC datetime: 2021-01-06T13:30:05.138524+00:00 Local datetime: 2021-01-06T20:30:05.138524+07:00 UTC offset (hours): +07:00 UTC offset (seconds): 25200

7. HTTPS GET: Thailand's COVID-19 Status Update

ตัวอย่างถัดไป สาธิตการดึงข้อมูลเกี่ยวกับผู้ป่วย COVID-19 สำหรับประเทศไทย ด้วยวิธี HTTPS GET จาก API ของเว็บ covid19.th-stat.com ข้อมูลที่ได้จะอยู่ในรูปของ JSON String

ตัวอย่างข้อความเอาต์พุตที่ได้

ยอดผู้ป่วยสะสม: 9331 ผู้ป่วยรักษาหายแล้ว: 4418 ผู้ป่วยรักษาตัวในโรงพยาบาล: 4847 ผู้เสียชีวิตสะสม: 66 ผู้ป่วยตรวจพบเพิ่มวันนี้: 365 ผู้ป่วยรักษาหาย: 21 ผู้เสียชีวิตวันนี้: 1 อัปเดตล่าสุด: 06/01/2021 12:25

8. Getting Air Quality & Weather Data from AirVisual

ตัวอย่างถัดไปแสดงการขอข้อมูลเกี่ยวกับสภาพอากาศและดัชนีชี้วัดคุณภาพอากาศจาก Airvisual Platform ซึ่งใช้วิธีสื่อสารแบบ HTTPS ตามรูปแบบ AirVisual REST API ที่ทางบริษัทกำหนดไว้ และจะได้ข้อมูลกลับมาเป็น JSON Data

การเรียกใช้ REST API ในกรณีนี้ จะต้องมี API Key โดยจะต้องสมัครสมาชิกเพื่อใช้งาน โดยเลือกแบบฟรี (Community) และระบุสถานที่หรือ Location (ในตัวอย่างนี้คือ เมืองนนทบุรี ประเทศไทย)

ในการทำงานของโค้ดนี้ จะต้องมีไฟล์ config.json ซึ่งได้บันทึกเก็บไว้ใน MicroPython Flash Storage และมีข้อความแบบ JSON ตามลักษณะดังนี้

{ "ssid": "XXXXXXX", "pwd": "XXXXXXXXX", "airvisual_api_key": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" }

ตัวอย่างข้อความเอาต์พุต มีดังนี้

Location: Nonthaburi, Mueang Nonthaburi, Thailand US AQI : 126 Temperature : 29 deg.C Humidity : 55 %RH Pressure : 1011 mBar

9. Getting Weather Data from OpenWeatherMap

OpenWeatherMap (https://openweathermap.org/) มีบริการ API ให้ดึงข้อมูลด้วยโพรโทคอล HTTP/HTTPS (ดูตัวอย่างการใช้ API และตัวอย่างข้อมูลในรูปแบบ JSON ได้จาก https://openweathermap.org/current)

ผู้ใช้จะต้องสมัครสมาชิกก่อนจึงจะสามารถใช้งานได้ฟรี (แต่มีข้อจำกัดและเงื่อนไขในการใช้งาน) เพื่อให้ได้ APPID ซึ่งเป็นข้อความแบบเลขฐานสิบหกจำนวน 32 หลัก

ในตัวอย่างนี้ เราจะดึงข้อมูลสภาพภูมิอากาศ และเลือกนำมาแสดงเฉพาะ อุณหภูมิ (Temperature) ความชื้นสัมพัทธ์ (Relative Humidity) และความกดอากาศ (Pressure) และเลือกเมืองเป็น จังหวัดนนทบุรี (Nonthaburi, TH) แล้วนำมาแสดงผลเป็นข้อความเอาต์พุตผ่านทาง REPL

ในการทำงานของโค้ดนี้ จะต้องมีไฟล์ config.json ซึ่งได้บันทึกเก็บไว้ใน MicroPython Flash Storage และมีข้อความแบบ JSON ตามลักษณะดังนี้

{ "ssid": "XXXXXXX", "pwd": "XXXXXXXXX", "openweather_appid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }

ตัวอย่างข้อความเอาต์พุต มีดังนี้

Mueang Nonthaburi, TH - Temperature : 29.53 deg.C - Pressure : 1011 hPa - Humidity : 54 %RH

10. Getting Air Quality Data from Air4Thai

ตัวอย่างถัดไป สาธิตการดึงข้อมูลเกี่ยวกับคุณภาพอากาศในเขตกรุงเทพจากเว็บ Air4Thai ใช้ HTTP GET แล้วนำข้อมูลบางส่วนซึ่งเป็น JSON Data มาแสดงผลเป็นข้อความเอาต์พุตทาง REPL

ในตัวอย่างนี้ได้เลือกสถานีตรวจวัดที่มี Station ID ตรงกับ bkp95t ซึ่งเป็นเขตบางซื่อของกรุงเทพ ฯ

ตัวอย่างข้อความเอาต์พุต มีดังนี้

Station: Bang Sue, Bangkok Last update: 2021-01-06 00:00 PM25: 41 µg/m³ AQI: 63

11. ส่งข้อความแจ้งเตือนผ่าน LINE Notify API

อีกตัวอย่างหนึ่งพบเห็นได้คือ การให้อุปกรณ์ประเภทไมโครคอนโทรลเลอร์สำหรับงาน IoT สามารถส่งข้อความแจ้งเตือน หรือ Chat Message ไปยังผู้ใช้ LINE App โดยใช้บริการที่เรียกว่า LINE Notify API ซึ่งมีการเริ่มใช้งานมาตั้งแต่ปีค.ศ. 2016

ถ้าจะใช้งานได้นั้น ผู้ใช้จะต้องไปตั้งค่าการใช้งานผ่านหน้าเว็บที่ https://notify-bot.line.me/en/ เพื่อให้ได้ Access Token มาใช้งาน

  1. ทำขั้นตอน Login เข้าใช้งานด้วย email address และ password แล้วยืนยันผ่าน LINE App บน Smartphone

  2. ไปที่เมนู MyPage

  3. กดปุ่ม Generate Token ในส่วนที่เรียกว่า "Generate access token (For developers)"

  4. จากนั้นจะมี Pop-up window ให้กรอกข้อมูล โดยจะต้องระบุ Token Name (ชื่อที่จะปรากฎเมื่อส่งข้อมูลไปยัง LINE) และเลือกว่า จะส่งข้อความ Chat ไปยังกลุ่ม LINE ใด ซึ่งผู้ใช้ได้สร้างหรืออยู่ในกลุ่มดังกล่าว หรือจะส่งหาตัวเองก็ได้โดยให้เลือก "1-on-1 chat with LINE notify" แล้วจึงกดปุ่ม Generate Token

  5. เมื่อมีการจับคู่และสร้าง Token แล้ว ในหน้า MyPage ในส่วนที่เรียกว่า "Connected services" จะมีรายการการเชื่อมต่อ From (ชื่อ Token Name ตามที่ได้ตั้งไว้ ) To (ชื่อกลุ่มไลน์ตามที่ได้เลือก หรือ ชื่อบัญชีของผู้ใช้เอง)

การส่งข้อความไปยัง LINE Notify API จะใช้วิธี HTTPS POST Method โดยระบุ URL เป็น https://notify-api.line.me/api/notify และในส่วน HTTPS Header จะมีต้องการระบุ 'Authorization' ร่วมกับ 'Bearer ' ตามด้วย Access Token

ตัวอย่างโค้ดสำหรับไมโครไพธอนที่ทดลองใช้งานกับ ESP32 มีดังนี้ และเป็นการทดลองส่งข้อความ เช่น ระบุค่าอุณหภูมิและความชื้นในบ้าน (เป็นตัวอย่างสมมุติ)

ข้อมูลที่ใช้สำหรับการตั้งค่า Wi-Fi และ LINE Token Access จะถูกเก็บอยู่ในไฟล์ config.json ใน Flash File Storage ของตัวอุปกรณ์ไมโครไพธอน ตัวอย่างเช่น

{ "ssid": "my_wifi_ssid", "pwd": "my_wifi_password", "line_notify_token": "sSVjJ3qoX17pdw5UETGfi3EhLxaCzTxxxxxxxxxxxx" }

เมื่อส่งข้อความไปยัง LINE Notify Service จะได้ข้อความตอบกลับมาเป็น JSON String ถ้าทำงานได้ถูกต้องจะได้ข้อความ

{"status":200,"message":"ok"}

รูปภาพ: ตัวอย่างข้อความที่ได้รับบนสมาร์ทโฟน

แต่ถ้าเกิดความผิดพลาด จะได้ข้อความ เช่น ในกรณีที่ไม่ได้ระบุ Authorization ในส่วน Header ของ HTTPS POST

{"status":401,"message":"Missing authorization header"}

หรือถ้าระบุ Access Token ไม่ถูกต้อง ก็จะได้ข้อความ

{"status":401,"message":"Invalid access token"}

ข้อสังเกต: เนื่องจากว่า มีการใช้ข้อความเป็นภาษาไทยด้วย ซึ่งบันทึกเป็น UTF-8 และเมื่อจะส่งออกไปโดยใช้ HTTPS POST จึงต้องมีการแปลงข้อมูลก่อน โดยใช้คำสั่ง urllib.parse.quote()

ดังนั้นจึงจะต้องติดตั้งไลบรารี urllib.parse ของ mciropython-lib โดยสามารถทำได้ง่ายใน MicroPython REPL โดยใช้คำสั่ง upip ดังนี้ (และการทำงานของ MicroPython ใน ESP32 จะต้องเคยเชื่อมต่อกับ Wi-Fi ได้สำเร็จแล้ว)

>>> import upip >>> upip.install('urllib.parse')

และจะมีการดาวน์โหลดไฟล์ (.tar.gz) ที่เกี่ยวข้องจากเว็บ micropython.org แล้วเก็บลงใน /lib

ปัญหาที่พบ: แต่การใช้งานไลบรารี urllib.parse จะพบปัญหา วิธีแก้คือ ให้ลบไฟล์ re.py และ ffilib.py ออกไป จากนั้นกด Ctrl+D เพื่อเริ่มต้นการทำงานของ MicroPython ใหม่อีกครั้ง

รูปภาพ: การติดตั้งไลบรารีผ่านทาง REPL ของ Thonny IDE

เราสามารถลองใช้ไลบรารี urequests ซึ่งเป็นโมดูลแบบ built-in สำหรับไมโครไพธอน และใช้คำสั่ง urequests.post() สำหรับส่งข้อมูลแบบ POST ได้ แต่จากการที่ได้ลองใช้กับ LINE Notify API พบว่า มีความผิดพลาดเกิดขึ้นในการรับข้อมูลตอบกลับ (Response) แต่ก็ได้รับข้อความใน LINE App

12. ตรวจสอบการเชื่อมต่อในเครือข่ายด้วย Ping

ตัวอย่างถัดไปสาธิตการตรวจสอบการเชื่อมต่อกับเครื่องคอมพิวเตอร์หรืออุปกรณ์ในเครือข่าย โดยใช้คำสั่ง ping ซึ่งเป็นการส่งแพคเกจตามรูปแบบ ICMP (Internet Control Message Protocol)

รูปภาพ: โครงสร้าง IPv4 ICMP Packet (Source: Wikipedia)

โค้ดตัวอย่างต่อไปนี้ ดัดแปลงมาจากโค้ด uping.py (Micro-Ping for MicroPython) ที่ได้มีการแชร์ไว้ใน gist.github.com

ตัวอย่างข้อความเอาต์พุต

PING 8.8.8.8 (8.8.8.8): 44 data bytes 64 bytes from 8.8.8.8: icmp_seq=1, ttl=112, time=139.7 ms 64 bytes from 8.8.8.8: icmp_seq=2, ttl=112, time=64.4 ms 64 bytes from 8.8.8.8: icmp_seq=3, ttl=112, time=150.3 ms 64 bytes from 8.8.8.8: icmp_seq=4, ttl=112, time=61.7 ms 64 bytes from 8.8.8.8: icmp_seq=5, ttl=112, time=158.2 ms 5 packets transmitted, 5 packets received

กล่าวสรุป

เราได้เห็นตัวอย่างการเขียนโค้ดภาษาไมโครไพธอนสำหรับ ESP32 เพื่อเชื่อมต่อกับระบบเครือข่ายไร้สายผ่าน Wi-Fi และสามารถใช้โพรโตคอลได้ อย่างเช่น HTTP/HTTPS

เผยแพร่ภายใต้ลิขสิทธิ์ Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)

Last updated

Was this helpful?