ไฟ WS2812 กับ ESP32 คำนวณไฟเลี้ยง จำกัดความสว่าง และต่อสายข้อมูลให้นิ่ง
WS2812 กินไฟสูงสุดราว 60 mA ต่อดวงตอนขาวเต็ม คำนวณขนาดแหล่งจ่าย จำกัดความสว่าง ใส่ตัวต้านทานสายข้อมูลและตัวเก็บประจุ และปัญหาสัญญาณ 3.3 V กับไฟ 5 V
- WS2812 หนึ่งดวงกินได้ถึงราว 60 mA ตอนขาวสว่างสุด 60 ดวงคือ 3.6 A ห้ามดึงจาก USB หรือขา 5V ของบอร์ด
- จำกัดความสว่างในโค้ด กระแสลดลงตามโดยประมาณ ช่วยให้ใช้แหล่งจ่ายเล็กลงได้
- ใส่ตัวต้านทาน 300–500 Ω ที่สายข้อมูลใกล้ดวงแรก และตัวเก็บประจุ 500–1000 µF คร่อมไฟเลี้ยง
- WS2812 ที่ไฟ 5 V ต้องการสัญญาณ HIGH อย่างน้อย 3.5 V แต่ ESP32 ให้ได้ต่ำสุด 2.64 V ใช้ level shifter ให้ชัวร์
WS2812 (หรือที่หลายคนเรียกว่า NeoPixel) คือ LED สามสีที่มีชิปควบคุมในตัว ต่อสายข้อมูลเส้นเดียวคุมได้ทั้งเส้น ปัญหาที่เจอเกือบทุกคนไม่ใช่โค้ด แต่เป็นไฟเลี้ยง: แต่ละดวงกินได้ถึงราว 60 mA ตอนขาวเต็ม เส้น 60 ดวงจึงต้องการแหล่งจ่าย 5 V หลายแอมป์ บทนี้คำนวณขนาดแหล่งจ่าย วิธีจำกัดความสว่าง และอุปกรณ์เล็ก ๆ สามชิ้นที่ทำให้เส้นไฟนิ่ง
ตัวอย่างใช้เส้นไฟ WS2812B ไฟเลี้ยง 5 V คุมด้วยบอร์ด ESP32 DevKit และไลบรารี Adafruit NeoPixel ใน Arduino IDE 2
กระแสต่อดวง: 60 mA คือกรณีแย่สุด
หนึ่งดวงมี LED แดง เขียว น้ำเงิน สีละราว 20 mA เมื่อสว่างสุด เปิดทั้งสามสีเต็มที่ (ขาว) จึงราว 60 mA ต่อดวง คู่มือของ Adafruit และ SparkFun ใช้ตัวเลขนี้ตรงกัน
แต่งานส่วนใหญ่ไม่ได้เปิดขาวเต็มทุกดวงตลอดเวลา Adafruit จึงให้กฎหยาบ ๆ ว่าคิดเฉลี่ย 20 mA ต่อดวง (หนึ่งในสามของสูงสุด) สำหรับงานสีสันทั่วไป แต่ถ้าโค้ดมีโอกาสสั่งขาวเต็มทั้งเส้น (เช่น ตอนบั๊ก หรือโหมดไฟฉาย) แหล่งจ่ายต้องรองรับกรณีนั้น หรือต้องจำกัดความสว่างในโค้ด
| จำนวนดวง | เฉลี่ย 20 mA/ดวง | ขาวเต็ม 60 mA/ดวง | กำลังไฟที่ 5 V (ขาวเต็ม) |
|---|---|---|---|
| 8 | 0.16 A | 0.48 A | 2.4 W |
| 30 | 0.6 A | 1.8 A | 9 W |
| 60 | 1.2 A | 3.6 A | 18 W |
| 144 | 2.88 A | 8.64 A | 43.2 W |
นับกรณีแย่สุดก่อนเสมอ แล้วค่อยตัดสินใจว่าจะซื้อแหล่งจ่ายใหญ่ขึ้น หรือจำกัดความสว่างในโค้ด
ตัวอย่างคำนวณ: เส้น 60 ดวงบนโต๊ะทำงาน
ขั้นที่ 1 กรณีแย่สุด 60 × 60 mA = 3,600 mA = 3.6 A ที่ 5 V = 18 W
ขั้นที่ 2 จำกัดความสว่าง ไลบรารีส่วนใหญ่มีคำสั่งตั้งความสว่างรวม ค่า 0–255 ตั้ง 64 คือ 64 ÷ 255 ≈ 25% กระแสลดลงตามโดยประมาณ: 3.6 × 0.25 ≈ 0.9 A
ขั้นที่ 3 รวมบอร์ด ESP32 ตอนส่ง Wi-Fi กินได้ถึงราว 240 mA ถ้าใช้แหล่งจ่ายเดียวกัน รวม 0.9 + 0.24 ≈ 1.14 A
ขั้นที่ 4 เลือกแหล่งจ่าย เผื่อให้ทำงานไม่เต็มพิกัด ใช้อะแดปเตอร์ 5 V 2 A ขึ้นไป
เทียบกับไฟจากพอร์ต USB 2.0 ของคอมที่ให้ราว 500 mA: หักบอร์ด 240 mA เหลือ 260 mA ÷ 60 mA ≈ 4 ดวง ที่ขาวเต็ม นี่คือเหตุผลที่เส้นไฟยาวต่อกับ USB แล้วบอร์ดรีเซ็ตเอง
ตัวอย่างโค้ดตั้งความสว่าง
#include <Adafruit_NeoPixel.h>
const int LED_PIN = 13; // สายข้อมูล ผ่านตัวต้านทานไปที่ DIN ของดวงแรก
const int NUM_LEDS = 60;
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.setBrightness(64); // ราว 25% กระแสขาวเต็มลดจาก 3.6 A เหลือราว 0.9 A
strip.show(); // เริ่มด้วยทุกดวงดับ
}
void loop() {
strip.fill(strip.Color(255, 255, 255)); // ทดสอบกรณีแย่สุด แล้ววัดกระแสจริง
strip.show();
delay(1000);
}
ตั้ง setBrightness() ครั้งเดียวตอนเริ่ม แล้ววัดกระแสจริงด้วยมัลติมิเตอร์ตอนสั่งขาวเต็ม ตัวเลขที่วัดได้คือตัวที่ใช้เลือกแหล่งจ่าย
ต่อไฟเลี้ยงให้ถูก
- ไม่ดึงไฟเส้นยาวผ่านบอร์ด ต่อไฟ 5 V จากแหล่งจ่ายเข้าเส้นไฟโดยตรง ไม่ผ่านพอร์ต USB หรือรางไฟบนบอร์ด
- GND ต้องต่อร่วมกัน ระหว่างแหล่งจ่าย เส้นไฟ และ ESP32 ไม่งั้นสัญญาณข้อมูลไม่มีจุดอ้างอิง
- ห้ามแรงดันเกิน Adafruit เตือนว่ากระแสเกินไม่เป็นไร แต่แรงดันเกินทำให้ LED พัง datasheet ของ WS2812B ระบุไฟเลี้ยง 3.5–5.3 V ถ่านอัลคาไลน์ 4 ก้อนให้ราว 6 V จึงเกิน
- เส้นยาวแรงดันตก ดวงท้าย ๆ สีเพี้ยนหรือหรี่ ทางแก้ทั่วไปคือเดินสายไฟเลี้ยงไปป้อนเพิ่มอีกจุด
- ต่อสายตอนไม่มีไฟ ถ้าจำเป็นต้องต่อตอนวงจรมีไฟ Adafruit ให้ลำดับ GND ก่อน แล้ว +5 V แล้วสายข้อมูล ถอดกลับลำดับ
อุปกรณ์เล็ก ๆ ที่ช่วยให้เส้นไฟนิ่ง
| ชิ้น | ค่าที่แนะนำ | ใส่ตรงไหน | ช่วยอะไร |
|---|---|---|---|
| ตัวเก็บประจุ | 500–1000 µF ทนแรงดัน 6.3 V ขึ้นไป (SparkFun ใช้ช่วง 100–1000 µF) | คร่อม + กับ − ใกล้ต้นเส้น | กันแรงดันกระชากตอนความสว่างเปลี่ยนเร็ว |
| ตัวต้านทานสายข้อมูล | 300–500 Ω (SparkFun ใช้ 220–470 Ω) | อนุกรมกับสายข้อมูล ฝั่งใกล้ดวงแรก | ทั้งสองคู่มือแนะนำให้ใส่ บางสินค้ามีในตัวแล้ว ใส่เพิ่มก็ไม่เสียหาย |
| Level shifter | ชิปอย่าง 74AHCT125 หรือ 74HCT245 | ระหว่างขา ESP32 กับ DIN | ยกสัญญาณ 3.3 V เป็น 5 V |
ตัวเก็บประจุแบบอิเล็กโทรไลต์มีขั้ว ต่อขาลบ (มีแถบบนตัว) เข้า GND ต่อกลับขั้วแล้วอาจเสียหาย
สัญญาณ 3.3 V กับไฟ 5 V
datasheet ของ WS2812B ระบุว่าขา DIN จะนับเป็น HIGH เมื่อแรงดันอย่างน้อย 0.7 × VDD คำนวณ
- ไฟเลี้ยง 5.0 V: 0.7 × 5.0 = 3.5 V
- ESP32 ขาออก HIGH ต่ำสุดตาม datasheet คือ 0.8 × VDD = 0.8 × 3.3 = 2.64 V
2.64 V ต่ำกว่า 3.5 V ที่ต้องการ แปลว่าต่อตรงอยู่นอกสเปก หลายเส้นติดได้เพราะแต่ละตัวทนกว่าสเปก แต่ไม่รับประกัน ทางแก้ที่ Adafruit ให้ไว้
- ใส่ level shifter แปลงสัญญาณเป็น 5 V (ทางที่ชัวร์ที่สุด)
- ลดไฟเลี้ยงของไฟลง เช่น ใช้แบตลิเธียม 3.7 V เลี้ยงเส้นไฟ เกณฑ์ HIGH จะลดลงตาม (0.7 × 3.7 ≈ 2.6 V) แต่ความสว่างลดลงด้วย และต้องดูแลแบตตามบทใช้แบตลิเธียมอย่างปลอดภัย
ข้อผิดพลาดที่เจอบ่อย
- เลี้ยงเส้นไฟจาก USB ทุกอย่างปกติจนสั่งขาวเต็ม แล้วบอร์ดรีเซ็ตหรือไฟกะพริบมั่ว
- ลืมต่อ GND ร่วม ระหว่างแหล่งจ่ายภายนอกกับบอร์ด
- ใส่ตัวต้านทานสายข้อมูลไว้ฝั่งบอร์ด แทนที่จะอยู่ใกล้ดวงแรกตามคำแนะนำ
- เชื่อกฎ 20 mA แต่โค้ดมีโหมดขาวเต็ม
- ต่อเส้นไฟเข้ากับแหล่งจ่ายตอนเปิดอยู่ โดยไม่ต่อ GND ก่อน
- ใช้สายเส้นเล็กกับกระแสหลายแอมป์ สายร้อนและแรงดันตกมาก
แหล่งข้อมูล
คำถามที่พบบ่อย
ต่อสัญญาณ 3.3 V จาก ESP32 ตรงเข้า WS2812 แล้วก็ติดนี่
หลายครั้งติดจริง แต่อยู่นอกสเปกของ datasheet อาจกะพริบมั่วเมื่ออากาศร้อน สายยาว หรือเปลี่ยนล็อตของไฟ ถ้าจะติดตั้งใช้งานจริงให้ใส่ level shifter เช่น 74AHCT125
ไฟปลายเส้นสีเพี้ยน ขาวกลายเป็นออกเหลืองหรือส้ม
แรงดันตกตามความยาวเส้น ดวงท้าย ๆ ได้ไฟเลี้ยงต่ำลง ลดความสว่าง หรือเดินสายไฟเลี้ยงเพิ่มไปป้อนอีกจุดของเส้น โดยต่อ GND ร่วมกันทั้งหมด
ใช้ถ่าน AA 4 ก้อนเลี้ยงไฟได้ไหม
ถ่านอัลคาไลน์ 4 ก้อนให้ราว 6 V สูงเกินไปสำหรับไฟ 5 V Adafruit แนะนำถ่าน NiMH 4 ก้อน ซึ่งได้ราว 4.8 V แทน
วงจรและโค้ดในบทความทดสอบกับบอร์ดตัวอย่าง บอร์ดต่างรุ่นอาจใช้ขาต่างกัน ตรวจ pinout ของบอร์ดที่ใช้ก่อนต่อไฟเสมอ