จ่ายไฟ ESP32 ให้ถูก USB ขา 5V ขา 3V3 และคำนวณอายุ แบตเตอรี่
ไฟ USB 5 V กับขา 3V3 ต่างกันยังไง ทำไม LDO ต้องมีแรงดันเหลือ งบกระแสตอน Wi-Fi ส่งข้อมูล และคำนวณอายุแบตด้วย deep sleep ทีละขั้น
- บอร์ด ESP32 รับไฟได้สามทาง USB ขา 5V หรือขา 3V3 ใช้ทางเดียวเท่านั้น ห้ามต่อพร้อมกัน
- ขา 3V3 ต้องเป็นไฟนิ่ง 3.0–3.6 V ห้ามต่อแบตลิเธียมตรง เพราะแบตเต็มสูงถึง 4.2 V
- ชิป ESP32 กินกระแสได้ถึงราว 240 mA ตอนส่ง Wi-Fi แหล่งจ่ายควรจ่ายได้อย่างน้อย 500 mA
- อายุแบตขึ้นกับกระแสตอนหลับมากกว่าตอนตื่น ไฟ LED และชิปบนบอร์ดทดลองกินแบตหมดได้ในไม่กี่วัน
บอร์ด ESP32 รับไฟได้สามทาง คือพอร์ต USB ขา 5V และขา 3V3 แต่ละทางมีเงื่อนไขต่างกัน และต้องเลือกใช้ทีละทาง ส่วนเรื่องแบตเตอรี่ ตัวที่กำหนดว่าอยู่ได้กี่วันไม่ใช่ตอนที่บอร์ดทำงาน แต่เป็นตอนที่บอร์ดหลับ บทนี้อธิบายเส้นทางไฟบนบอร์ด งบกระแส และคำนวณอายุแบตให้ดูทีละขั้น
ตัวเลขของชิปในบทมาจาก ESP32 Series Datasheet ของ Espressif ตัวอย่างใช้บอร์ดแบบ ESP32-DevKitC (โมดูล ESP32-WROOM-32) ถ้าใช้ชิปรุ่นอื่น เช่น ESP32-C3 หรือ S3 ให้เปิด datasheet ของรุ่นนั้นเทียบ
ไฟเดินทางยังไงบนบอร์ด
ตัวชิป ESP32 ทำงานที่ 2.3–3.6 V โดย Espressif แนะนำให้ใช้ 3.3 V และแหล่งจ่ายที่จ่ายกระแสได้ 500 mA ขึ้นไป แต่ USB ให้ 5 V บอร์ดจึงมีตัวควบคุมแรงดันแบบ LDO (low-dropout regulator) แปลง 5 V ลงเหลือ 3.3 V
| ทางเข้าไฟ | รับแรงดันเท่าไร | ผ่าน LDO ไหม | ใช้เมื่อไร |
|---|---|---|---|
| พอร์ต USB | 5 V จากคอมหรือหัวชาร์จ | ผ่าน | ตอนเขียนโค้ด ทดลองบนโต๊ะ |
| ขา 5V | 5 V จากแหล่งจ่ายภายนอก | ผ่าน | ติดตั้งจริง ใช้อะแดปเตอร์ 5 V |
| ขา 3V3 | 3.3 V ที่ควบคุมแรงดันแล้ว (ไม่เกิน 3.6 V) | ไม่ผ่าน | มีวงจรแปลงไฟของตัวเองแล้ว |
คู่มือ ESP32-DevKitC เขียนชัดว่าสามทางนี้ ใช้ได้ทีละทางเท่านั้น ต่อพร้อมกันแล้วบอร์ดหรือแหล่งจ่ายอาจเสีย
ขา 3V3 ไม่มีอะไรกั้นระหว่างไฟที่ป้อนเข้ากับตัวชิป ป้อนเกิน 3.6 V คือเกินพิกัดของชิปโดยตรง
LDO ต้องมีแรงดันเหลือ (dropout)
LDO ทำงานได้เมื่อแรงดันเข้าสูงกว่าแรงดันออกอย่างน้อยค่าหนึ่ง เรียกว่า dropout voltage บอร์ดราคาประหยัดหลายรุ่นใช้ชิปตระกูล 1117 ซึ่ง datasheet ของ AMS1117 ระบุ dropout ราว 1.1 V (สูงสุด 1.3 V) ที่กระแส 800 mA
ลองคิดสองกรณี
- ป้อน USB 5 V: 5.0 − 1.3 = 3.7 V มากกว่า 3.3 V ที่ต้องการ LDO ทำงานปกติ
- ป้อนแบตลิเธียม 1 เซลล์เข้าขา 5V: แบตเต็มอยู่ที่ 4.2 V ได้ 4.2 − 1.1 = 3.1 V พอแบตลดเหลือ 3.7 V จะเหลือแค่ราว 2.6 V ต่ำกว่า 3.3 V ไปเยอะ
กรณีที่ 2 บอร์ดอาจยังติด แต่พอ Wi-Fi ดึงกระแสสูง แรงดันจะตกจนบอร์ดรีเซ็ตเอง (brownout) อาการคือบอร์ดรีสตาร์ตวนตอนต่อ Wi-Fi ทั้งที่เสียบ USB แล้วปกติ ทางแก้คือใช้ LDO ที่ dropout ต่ำจริง ๆ หรือวงจรแปลงไฟแบบ buck-boost หรือใช้บอร์ดที่ออกแบบมาให้ต่อแบตลิเธียมโดยตรง (มีช่องเสียบแบตและวงจรชาร์จบนบอร์ด)
อีกเรื่องคือความร้อน LDO ทิ้งแรงดันส่วนเกินเป็นความร้อน ป้อน 5 V ใช้ 250 mA จะร้อน (5.0 − 3.3) × 0.25 ≈ 0.43 W ตัวเล็ก ๆ บนบอร์ดจึงอุ่นมือเวลาทำงานหนัก ถ้าต่อเซนเซอร์หรือโมดูลอื่นจากขา 3V3 เพิ่ม ให้นับกระแสรวมด้วย
งบกระแส: ใช้เท่าไร ตอนไหน
ค่าจาก datasheet ของชิป ESP32 (ไม่รวมชิ้นส่วนอื่นบนบอร์ด)
| สถานะ | กระแสโดยประมาณ |
|---|---|
| ส่ง Wi-Fi 802.11b ที่ +19.5 dBm | 240 mA |
| ส่ง Wi-Fi 802.11n MCS7 ที่ +14 dBm | 180 mA |
| รับ Wi-Fi | 95–100 mA |
| Light-sleep | 0.8 mA |
| Deep-sleep (RTC timer + RTC memory) | 10 µA |
ตัวเลข 240 mA เป็นช่วงสั้น ๆ ตอนส่งข้อมูล ไม่ใช่ค่าเฉลี่ย แต่แหล่งจ่ายต้องรับช่วงพีกนี้ได้โดยแรงดันไม่ตก จึงเป็นที่มาของคำแนะนำ 500 mA เผื่อไว้ให้อุปกรณ์อื่นด้วย พอร์ต USB 2.0 ของคอมจ่ายได้ราว 500 mA พอสำหรับบอร์ดเปล่ากับเซนเซอร์เล็ก ๆ แต่ไม่พอถ้าจะพ่วงไฟ LED หลายดวงหรือมอเตอร์
deep sleep คืออะไร
ใน deep sleep ซีพียูและ RAM ส่วนใหญ่ดับ Wi-Fi ดับ เหลือแค่วงจร RTC กับ RTC memory ที่ยังมีไฟ ตื่นได้ด้วยตัวจับเวลาหรือขา GPIO บางขา จุดที่คนพลาดบ่อยคือ ตื่นแล้วโปรแกรมเริ่มใหม่จาก setup() ไม่ได้ทำต่อจากบรรทัดที่สั่งหลับ
ตัวอย่างโค้ด Arduino-ESP32 ตื่นทุก 10 นาที อ่านค่า ส่งข้อมูล แล้วหลับต่อ
RTC_DATA_ATTR int bootCount = 0; // อยู่ใน RTC memory ไม่หายตอนหลับ
void setup() {
bootCount++;
// อ่านเซนเซอร์ ต่อ Wi-Fi ส่งข้อมูล ตรงนี้
esp_sleep_enable_timer_wakeup(600ULL * 1000000ULL); // 600 วินาที หน่วยเป็นไมโครวินาที
esp_deep_sleep_start();
}
void loop() {} // ไม่ถูกเรียก เพราะหลับก่อนถึง
รายละเอียดการเขียนโปรแกรมประหยัดไฟเชิงลึก เช่น ULP coprocessor หรือการลดเวลาต่อ Wi-Fi เป็นเรื่องของสายโปรแกรมมิ่ง บทนี้เน้นที่ไฟเลี้ยง
คำนวณอายุแบตทีละขั้น
โจทย์: เครื่องวัดอากาศ ตื่นทุก 600 วินาที ตื่นอยู่ 4 วินาทีเพื่อต่อ Wi-Fi และส่งข้อมูล ใช้แบต 2,000 mAh
ตัวเลขกระแสข้างล่างเป็น ค่าสมมติสำหรับตัวอย่าง ของจริงต้องวัดจากบอร์ดตัวเอง
- ตอนตื่น เฉลี่ย 150 mA (มีช่วงรับ ช่วงส่ง และช่วงรอ)
- ตอนหลับ แบบ A: บอร์ดที่ตัดส่วนเกินออกแล้ว วัดได้ 0.05 mA
- ตอนหลับ แบบ B: บอร์ดทดลองที่มีไฟ LED แสดงสถานะ ชิป USB-serial และ LDO ที่กินกระแสเอง วัดได้ 6 mA
ขั้นที่ 1 ประจุที่ใช้ต่อรอบ (หน่วย mA·s)
- ตื่น: 150 × 4 = 600
- หลับ แบบ A: 0.05 × 596 = 29.8 รวม 629.8
- หลับ แบบ B: 6 × 596 = 3,576 รวม 4,176
ขั้นที่ 2 กระแสเฉลี่ย หารด้วยเวลาหนึ่งรอบ 600 วินาที
- แบบ A: 629.8 ÷ 600 ≈ 1.05 mA
- แบบ B: 4,176 ÷ 600 ≈ 6.96 mA
ขั้นที่ 3 อายุแบต เผื่อใช้ได้จริงแค่ 80% ของความจุ = 1,600 mAh
- แบบ A: 1,600 ÷ 1.05 ≈ 1,524 ชั่วโมง ≈ 63 วัน
- แบบ B: 1,600 ÷ 6.96 ≈ 230 ชั่วโมง ≈ 9.6 วัน
โค้ดเหมือนกันทุกบรรทัด ต่างกันแค่บอร์ด อายุแบตต่างกันเกือบ 7 เท่า ตัวเลข 10 µA ใน datasheet คือของชิปเท่านั้น ไฟ LED บนบอร์ด ชิป USB-serial และ LDO ที่ datasheet ของ AMS1117 ระบุกระแสตัวเองไว้ราว 5 mA ไม่ได้หลับตามชิป
ถ้าจะใช้แบต วัดกระแสตอนหลับก่อนทำอย่างอื่น ตัวเลขนี้ตัดสินอายุแบตมากกว่าโค้ดทุกบรรทัด
ข้อผิดพลาดที่เจอบ่อย
- ต่อแบตลิเธียมเข้าขา 3V3 ตรง แบตเต็ม 4.2 V เกินพิกัด 3.6 V ของชิป
- ใช้แหล่งจ่ายเล็กเกิน หัวชาร์จหรือพาวเวอร์แบงก์บางรุ่นจ่ายกระแสพีกไม่ทัน บอร์ดรีเซ็ตตอนต่อ Wi-Fi
- จ่ายไฟหลายทางพร้อมกัน เสียบ USB ค้างพร้อมป้อนขา 5V จากแหล่งอื่น
- เชื่อตัวเลข 10 µA แล้วคำนวณอายุแบตจากค่านั้น โดยไม่วัดบอร์ดจริง
- ลืมว่าตื่นแล้วเริ่มใหม่ เก็บค่าในตัวแปรธรรมดาแล้วงงว่าทำไมนับไม่ขึ้น
- สายไฟเล็กและยาว แรงดันตกตามสายตอนกระแสพีก ใช้สายสั้นและใส่ตัวเก็บประจุใกล้บอร์ด (Espressif แนะนำอย่างน้อย 10 µF ที่ทางเข้าไฟ)
ถ้ายังไม่เคยคำนวณกระแสด้วย Ohm’s law ดูพื้นฐานได้ในบทต่อ LED กับ ESP32
แหล่งข้อมูล
คำถามที่พบบ่อย
เสียบ USB ค้างไว้แล้วต่อแบตเข้าขา 5V ด้วยได้ไหม
ไม่ควร คู่มือ ESP32-DevKitC ระบุให้จ่ายไฟทางเดียวเท่านั้น ไม่งั้นบอร์ดหรือแหล่งจ่ายอาจเสีย ถ้าอยากใช้ทั้ง USB และแบต ให้ใช้บอร์ดที่มีวงจรชาร์จและสลับไฟในตัว
deep sleep แล้วตื่นมา ตัวแปรหายหมด ทำยังไง
ตื่นจาก deep sleep คือเริ่มโปรแกรมใหม่จาก setup() ตัวแปรที่อยากเก็บไว้ให้ประกาศด้วย RTC_DATA_ATTR จะอยู่ใน RTC memory ที่ยังมีไฟตอนหลับ
วัดกระแสตอนหลับยังไง
ต่อมัลติมิเตอร์โหมดกระแสอนุกรมกับสายไฟบวกของแบต เริ่มที่ช่วง mA แล้วค่อยลดเป็นช่วง µA หลังบอร์ดเข้า deep sleep แล้ว เพราะตอนบูตกระแสสูงจนช่วง µA อาจรับไม่ไหว
วงจรและโค้ดในบทความทดสอบกับบอร์ดตัวอย่าง บอร์ดต่างรุ่นอาจใช้ขาต่างกัน ตรวจ pinout ของบอร์ดที่ใช้ก่อนต่อไฟเสมอ