ESP32 อ่าน analog ไม่ได้ตอนเปิด WiFi: เลือกขา ADC1 กับ ADC2 ให้ถูก
ทำไม analogRead() บนบางขาของ ESP32 ใช้ไม่ได้เมื่อเปิด WiFi ขาไหนเป็น ADC1 ที่ใช้ได้ตลอด และทำอย่างไรเมื่อเซนเซอร์ analog มีมากกว่าขาที่ว่าง
อาการที่เจอบ่อย: เซนเซอร์ analog อ่านค่าได้ปกติตอนทดสอบ แต่พอเพิ่มโค้ด WiFi เข้าไป analogRead() กลับได้ค่าผิดหรืออ่านไม่ได้
สาเหตุคือขานั้นอยู่บน ADC2 ซึ่ง ESP32 ใช้ร่วมกับวงจร WiFi
บทความนี้พูดถึง ESP32 รุ่นแรก (ESP32-WROOM-32 บนบอร์ด DevKit V1) รุ่น S2, S3 และ C3 จัดขาต่างออกไป
ADC1 กับ ADC2
| ADC | ขา (GPIO) | ใช้ตอนเปิด WiFi |
|---|---|---|
| ADC1 | 32, 33, 34, 35, 36 (VP), 39 (VN) | ✅ ได้ |
| ADC2 | 0, 2, 4, 12, 13, 14, 15, 25, 26, 27 | ❌ ไม่ได้ |
บนบอร์ด DevKit V1 จึงมีขา analog ที่ใช้ได้แน่นอนแค่ 6 ขา และในนั้น GPIO 34, 35, 36, 39 เป็นขา input อย่างเดียว ไม่มีตัวต้านทาน pull-up ภายใน ใช้กับเซนเซอร์ analog ได้ดี แต่ใช้กับปุ่มกดต้องต่อ pull-up ภายนอกเอง
ตัวอย่าง: หุ่นยนต์หาแสงใช้ ADC1 ครบ 6 ขา
หุ่นใน โปรเจกต์หุ่นยนต์หาแสง มี LDR 2 ตัวกับ IR Sharp 4 ตัว รวม 6 สัญญาณ analog พอดีกับ ADC1 ตัวจำลองจัดขาให้โดยเลือก ADC1 ก่อนเสมอ:
| TB6612FNG Motors | VM → แบต 7.4 VVCC → 3V3GND → GNDPWMA → GPIO25AIN1 → GPIO13AIN2 → GPIO4PWMB → GPIO26BIN1 → GPIO19BIN2 → GPIO21STBY → 3V3 (ต่อค้างไว้) |
|---|---|
| HC-SR04 Front sonar | VCC → 5VTRIG → GPIO22ECHO → GPIO14GND → GND |
| LDR Left eye LDR | VCC → 3V3GND → GNDAO → GPIO32 |
| LDR Right eye LDR | VCC → 3V3GND → GNDAO → GPIO33 |
| Microswitch Front bumper | COM → GNDNO → GPIO16 |
| GP2Y0A21 IR front-left | VCC → 5VGND → GNDVO → GPIO34 |
| GP2Y0A21 IR front-right | VCC → 5VGND → GNDVO → GPIO35 |
| GP2Y0A21 IR left side | VCC → 5VGND → GNDVO → GPIO36 |
| GP2Y0A21 IR right side | VCC → 5VGND → GNDVO → GPIO39 |
| Microswitch Rear bumper | COM → GNDNO → GPIO17 |
| SG90 Head servo | GND → GNDVCC → 5VPWM → GPIO27 |
| ST7789 Face Display | GND → GNDVCC → 3V3SCL → GPIO18SDA → GPIO23RES → GPIO5DC → GPIO15BLK → 3V3 (ต่อค้างไว้) |
ถ้าเพิ่มเซนเซอร์ analog ตัวที่ 7 ตัวจำลองจะจำเป็นต้องใช้ขา ADC2 และขึ้นคำเตือนในหน้า Wiring ว่า “อ่านค่าไม่ได้ขณะเปิด WiFi” ลองดูได้ด้วยการเพิ่ม IR อีกตัวในหน้า Robot Body
เปิดหุ่นหาแสงแล้วลองเพิ่มเซนเซอร์ →
เมื่อขา analog ไม่พอ
- ใช้ ADC ภายนอก ADS1115 ต่อผ่าน I²C (ใช้แค่ 2 ขาร่วมกับอุปกรณ์ I²C อื่น) ได้ 4 ช่องต่อชิป ความละเอียด 16 บิต ต่อได้สูงสุด 4 ชิปบนบัสเดียวโดยตั้ง address 0x48–0x4B ตัวจำลองใช้วิธีนี้กับ Raspberry Pi ที่ไม่มีขา analog เลย
- เปลี่ยนเป็นเซนเซอร์แบบดิจิทัล เช่นใช้ HC-SR04 หรือเซนเซอร์ระยะแบบ I²C (เช่น VL53L0X) แทน IR analog บางตัว
- ใช้ ADC2 เฉพาะกับงานที่ไม่ต้องอ่านค่าระหว่างเปิด WiFi ทางนี้ยุ่งยากและพลาดง่าย แนะนำเป็นทางสุดท้าย
เรื่องอื่นที่ควรรู้เกี่ยวกับ ADC ของ ESP32
analogRead()ให้ค่า 0–4095 (12 บิต) ใน Arduino core ค่าเริ่มต้นวัดได้ถึงราว 3.1–3.3 V- ค่าที่อ่านไม่เป็นเส้นตรงช่วงใกล้ 0 V และใกล้ค่าสูงสุด ถ้าต้องการแปลงเป็นแรงดันจริงใช้
analogReadMilliVolts() - ห้ามให้แรงดันเข้าขาเกิน 3.3 V เซนเซอร์ที่เลี้ยงด้วย 5 V และส่งสัญญาณได้ถึง 5 V ต้องแบ่งแรงดันก่อน (เหมือนกรณี ขา ECHO ของ HC-SR04)