ด้วยคุณสมบัติของ ESP32 ที่เหมาะสำหรับทำอุปกรณ์ IoT ทั้งทำเป็น Node ต่าง ๆ และทำเป็น Gateway สำหรับการนำ ESP32 ไปทำเป็น Node มักจะมีปัญหาหนึ่งซึ่งเป็นปัญหาสำคัญของผู้พัฒนา คือ ปัญหาการใช้พลังงาน การสร้าง Node ส่วนใหญ่มักจะใช้แบตเตอรี่เป็นพลังงาน เพื่อให้ Node สามารถทำงานได้ แต่ด้วยคุณสมบัติของ ESP32 ที่เมื่อมีการใช้งาน WiFi จะใช้พลังงานไฟฟ้าจำนวนมาก เมื่อมีการใช้งานอย่างต่อเนื่องจะทำให้สิ้นเปลืองพลังงานมาก และทำให้แบตเตอรี่หมดอย่างรวดเร็ว ดังนั้น การสร้าง Node ของ ESP32 จึงควรคำนึงถึงการประหยัดพลังงานเป็นสำคัญ การประหยัดพลังงานที่ง่ายที่สุดคือการปิดใช้งานระบบต่าง ๆ ทั้ง WiFi และ CPU ทำให้ประหยัดพลังงานลงไปได้ สำหรับ ESP32 ได้เตรียมฟังก์ชันต่าง ๆ ไว้ให้ใช้งานแล้ว โดยถูกเรียกรวม ๆ ว่า Deep Sleep
โหมดการใช้งาน Deep Sleep จะแบ่งได้ตามวิธีการ “ปลุกให้ตื่น” โดยสามารถแบ่งลักษณะการปลุกให้ตื่นได้ 2 แบบ ดังนี้
หมายถึง การทำให้ ESP32 กลับมาเริ่มทำงานใหม่ด้วยการกระตุ้นจากภายนอก แบ่งการกระตุ้นได้ 2 แบบ คือ
หมายถึง การใช้วงจรไฟฟ้าภายใน ESP32 เป็นตัวกระตุ้น แล้วทำให้ ESP32 ตื่นขึ้นมา มักจะหมายถึงการปลุกให้ตื่นตามเวลาด้วย RTC โดยปกติแม้ส่วนวงจรอื่น ๆ ของ ESP32 จะถูกปิดการทำงาน แต่ส่วนของ RTC จะยังนับ และจดจำค่าเวลาต่อไปเรื่อย ๆ ตราบใดที่ยังมีการจ่ายพลังงานไฟฟ้าเลี้ยงอยู่ตลอด เพื่อรอการดึงค่าเวลาออกมาใช้งาน
ในส่วนของฟังก์ชันที่เกี่ยวข้องกับ Deep Sleep มีด้วยกันดังนี้
จะใช้ฟังก์ชัน esp_deep_sleep_start(); มีรูปแบบการใช้งานดังนี้
void esp_deep_sleep_start();
ไม่มีค่าพารามิเตอร์ และไม่มีค่าที่ส่งกลับ จะใช้ก็ต่อเมื่อมีการตั้งค่าลักษณะการตื่นเรียบร้อยแล้วเท่านั้น กรณีที่เรียกใช้ฟังก์ชันนี้แล้วไม่ได้กำหนดลักษณะการตื่น จะต้องกดปุ่ม Reset เท่านั้น จึงจะทำให้ ESP32 กลับขึ้นทำงานอีกครั้ง
ฟังก์ชันกำหนดการตื่นด้วยการเปลี่ยนสถานะ GPIO ฟังก์ชัน esp_deep_sleep_enable_ext0_wakeup(); จะใช้สำหรับกำหนด GPIO ที่ต้องการให้ ESP32 ตื่นขึ้นมาเมื่อมีการเปลี่ยนสถานะของ GPIO ซึ่งมีรูปแบบการใช้งานดังนี้
void esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
มีรายละเอียดของค่าพารามิเตอร์ดังนี้
และไม่มีค่าที่ส่งกลับ
ฟังก์ชันกำหนดการตื่นด้วยเซ็นเซอร์สัมผัส ใช้ฟังก์ชัน esp_deep_sleep_enable_touchpad_wakeup(); กำหนด โดยมีรูปแบบการใช้งานดังนี้
void esp_deep_sleep_enable_touchpad_wakeup();
ไม่มีค่าพารามิเตอร์ และไม่มีค่าที่ส่งกลับ สำหรับการกำหนดช่องของเซ็นเซอร์ที่ใช้ จะกำหนดผ่านฟังก์ชัน touchAttachInterrupt(); ซึ่งผู้เขียนแนะนำให้ดูตัวอย่างจะเข้าใจมากขึ้น
ฟังก์ชันกำหนดการตื่นตามเวลา ใช้ฟังก์ชัน esp_deep_sleep_enable_timer_wakeup(); ในการกำหนด ซึ่งจะมีรูปแบบการใช้งานดังนี้
void esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us);
มีค่าพารามิเตอร์จำนวน 1 ตัว ซึ่งมีรายละเอียดดังนี้
และไม่มีค่าที่ส่งกลับมา
หลังจากการใช้ Deep Sleep จะมีการตัดการจ่ายไฟเลี้ยงในส่วนของแรมที่เชื่อมต่ออยู่กับ CPU ด้วย ทำให้ข้อมูลที่อยู่ในแรมนั้นถูกล้างออกจนหมด แต่จะมีข้อยกเว้นสำหรับแรมของวงจรส่วน RTC ที่ยังคงมีไฟเลี้ยงอยู่เสมอ ทำให้เราสามารถนำข้อมูลบางส่วนไปเก็บไว้บนแรมของ RTC ได้ แม้มีการใช้ Deep Sleep กี่ครั้ง ข้อมูลก็ยังคงถูกเก็บรักษาไว้เหมือนเดิม
การสร้างตัวแปรที่จะเก็บข้อมูลไว้บนแรมของ RTC สามารถทำได้โดยประกาศตัวแปรในรูปแบบดังต่อไปนี้
RTC_DATA_ATTR ชนิดตัวแปร ชื่อตัวแปร;
หรือ
RTC_DATA_ATTR ชนิดตัวแปร ชื่อตัวแปร = ค่าที่ต้องการเซ็ต;
ทั้งนี้ตัวแปรที่เก็บไว้บนแรมของ RTC สามารถนำมาอ่าน เขียนได้ตามปกติ การประกาศควรประกาศให้มีขอบเขตใช้งานแบบโกลบอล
ในการทดลอง จะสมมุติหน้าที่การทำงานของ Node ต่าง ๆ ที่จะกำหนดให้มีการตื่นที่แตกต่างกันออกไป ตามสถานะการที่สมมุติขึ้นมาดังนี้
การแสดงผลมักใช้จอแสดงผลที่มีการใช้พลังงานไฟฟ้ามาก ดังนั้นการใช้งาน Deep Sleep จึงเหมาะมากที่จะนำมาใช้งานกับ Node ประเภทนี้ โดยหลักการทำงานคือจะจำลองการแสดงผลบางอย่างนาน 30 วินาที แล้วจึงปิดหน้าจอไป จากนั้นจึงเข้าสู่โหมด Deep Sleep สำหรับการตื่น ให้ใช้วิธีการสัมผัสไปในจุดที่กำหนดขึ้นมา ซึ่งรวม ๆ จะเขียนโค้ดโปรแกรมส่วนของ Deep Sleep ได้ดังนี้
ให้สังเกตว่า ในโค้ดโปรแกรมผู้เขียนได้กำหนดขาที่จะให้ตื่นขึ้นมาไว้ที่ช่อง ??? ดังนั้นหากนำไปใช้งานจริงจะต้องมีการต่อสายขึ้นมา และทำจุดให้สัมผัสไว้ด้วย
Node ส่งค่าอุณหภูมิ
สำหรับ Node นี้ ผู้เขียนจะให้ Node มีการส่งค่าอุณหภูมิขึ้นระบบ MQTT ทุก ๆ 10 นาที หลักการคือ หลังจากการเชื่อมต่อ WiFi ได้แล้ว จะมีการส่งข้อมูลไปทันที จากนั้นจึงเข้าสู่โหมด Deep Sleep เป็นเวลา 10 นาที แล้วจึงกำหนดให้ตื่นขึ้นมา ดังนั้นในตัวอย่างนี้จะกำหนดให้ตื่นโดยใช้เหตุการณ์ภายใน นั้นก็คือการใช้ RTC ภายในเพื่อจับเวลาการ Deep Sleep นั่นเอง
ตัวอย่างของโค้ดของ Node นี้ในส่วนของ Deep Sleep จึงมีดังนี้
เซ็นเซอร์ส่วนใหญ่แล้ว จะมีการทำงานแบบดิจิตอล คือเมื่อมีการตรวจจับสัญญาณบางอย่างได้ จะใช้ค่าเป็น 0 หรือให้ค่าเป็น 1 แต่กรณีที่นำไปใช้กับ Node ต่าง ๆ มักจะเป็นการตรวจจับสภาพแวดล้อมในพื้นที่นั้น ๆ เช่น การใช้เซ็นเซอร์น้ำฝนเพื่อตรวจจับว่ามีฝนตกหรือไม่ หรือการใช้งาน PIR เพื่อตรวจจับผู้บุกรุก การสร้าง Node ขึ้นมาแล้วใช้ Deep Sleep จึงสำคัญมาก เพราะหากมีการเปิดใช้งาน ESP32 อยู่เสมอเพื่ออ่านสถานะลอจิกอยู่ตลอดเวลา จะทำให้ใช้พลังงานมาก ดังนั้น การใช้งาน Deep Sleep แล้วทำให้ตื่นขึ้นมาด้วยวิธีการเปลี่ยนสถานะ GPIO ก็จะทำให้ประหยัดพลังงานไปได้มาก
จากเหตุผลที่ได้อธิบายไปแล้ว ทำให้โค้ดส่วนของ Deep Sleep มีดังนี้
ในการทดลองวัดอัตราการใช้พลังงานของ ESP32 ผู้เขียนได้ใช้บอร์ด NodeMCU-32S และดิจิตอลมิเตอร์ 2 ตัว ต่างยีห้อกัน โดยตัวหนึ่งทำหน้าที่วัดแรงดันไฟฟ้าที่จ่ายให้กับ ESP32 (แรงดัน 3.3V) และอีกตัวหนึ่งทำหน้าที่วัดการจ่ายกระแสไฟฟ้าเข้าหัว MicroUSB จากการวัดค่าทั้ง 2 นี้ เมื่อนำมาคูณกันจะได้เป็นค่าของพลังงานไฟฟ้า
ผลการทดลอง คือสามารถวัดแรงดันไฟฟ้าได้ 3.28V และวัดค่ากระแสไฟฟ้าได้ 125mA เมื่อคำนวณออกมาเป็นพลังงานไฟฟ้าที่ใช้ คือ 410mW
การทดลองนี้จะอัพโหลดโปรแกรมเข้าไปใหม่ โดยโปรแกรมจะทำหน้าที่รอการกดปุ่ม IO0 บนบอร์ด NodeMCU-32S เพื่อเข้าโหมด Deep Sleep และเมื่อมีการกดปุ่ม IO0 อีกครั้ง จะตื่นจากโหมด Deep Sleep
การวัดพลังงานไฟฟ้าจะวัดจำนวน 2 ครั้ง คือครั้งที่กดแล้วเข้าโหมด Deep Sleep และครั้งที่กด แล้วกลับมาโหมดปกติ
ผลการทดลองคือ เมื่ออยู่ในโหมดปกติ วัดแรงดันไฟฟ้าได้ 3.29V และวัดกระแสไฟฟ้าได้ 68.5mA เมื่อนำไปคำนวณจะได้ค่ากำลังไฟฟ้าที่ใช้ 225mW
แต่เมื่อมีการเข้าสู่โหมด Deep Sleep สามารถวัดแรงดันไฟฟ้าได้ 3.3V และวัดค่ากระแสไฟฟ้าได้ 5.53mA เมื่อนำไปคำนวณแล้วพบว่า ค่ากำลังไฟฟ้าที่ใช้คือ 18mW
จากผลการทดลองจะเห็นได้ว่า เมื่อบอร์ด NodeMCU-32S อยู่ในโหมด Deep Sleep จะใช้พลังงานน้อยกว่าเดิมเมื่อเทียบกับโหมดปกติ 12 เท่า และเมื่อนำไปเทียบกับโปรแกรมตัวอย่าง WiFiScan จะใช้งานน้อยกว่าเดิมถึง 22 เท่า ! นั่นหมายความว่าหากใช้งานร่วมกับแบตเตอรี่จะทำให้สามารถใช้งานได้ยาวนานมากกว่าเดิมประมาณ 20 เท่านั่นเอง
สำหรับโค้ดที่ใช้ในการทดลองส่วนนี้ มีดังนี้
ตามความเป็นจริงแล้ว ESP32 เมื่ออยู่ในโหมด Deep Sleep จะใช้พลังงานไฟฟ้าในระดับไมโครแอมแปร์เท่านั้น แต่เนื่องจากการทดลองครั้งนี้ใช้บอร์ดสำเร็จรูป ซึ่งมีอุปกรณ์ต่าง ๆ บนบอร์ดใช้กระแสไฟฟ้าอยู่ ทำให้ผลการทดลองใช้กระแสไฟฟ้าในระดับมิลิแอมป์ กรณีหากจะนำ ESP32 ไปทำเป็นชิ้นงานจริง ควรใช้เฉพาะ ESP32 มาทดสอบ แล้วผลที่ได้คือการใช้กระแสไฟฟ้าระดับไมโครแอมแปร์