บทความ › อิเล็กทรอนิกส์

เซอร์โว SG90 และ MG90S กับ ESP32: สัญญาณ PWM 50 Hz และไฟเลี้ยงแยก

เซอร์โวจิ๋วหมุนตามความกว้างพัลส์ 1–2 ms ทุก 20 ms ต่อกับ ESP32 ยังไง ทำไมต้องใช้ไฟเลี้ยงแยกและกราวด์ร่วม กระแสตอนติดขัดเท่าไร และเขียนด้วย ESP32Servo หรือ LEDC

เริ่มต้น อ่าน 7 นาที 22 ตุลาคม 2569 อิเล็กทรอนิกส์ ช่างมือใหม่ · บทที่ 9/10

อ่านจบแล้วจะรู้
  • เซอร์โวจิ๋วรับพัลส์ทุก 20 ms (50 Hz) ความกว้างราว 1 ms = สุดด้านหนึ่ง 1.5 ms = กลาง 2 ms = สุดอีกด้าน
  • ไฟเลี้ยงเซอร์โวแยกจากบอร์ดได้ แต่กราวด์ต้องต่อร่วมกันเสมอ ไม่งั้นสัญญาณไม่มีจุดอ้างอิง
  • เผื่อกระแสตัวละอย่างน้อย 0.5 A สำหรับ SG90 และมากกว่านั้นสำหรับ MG90S เพราะตอนติดขัดกินกระแสสูงสุด
  • อย่าสั่งไปชนขอบกลไก ใช้ช่วงที่ทดสอบแล้ว เช่น 20–160° เพื่อลดกระแสค้างและเฟืองรูด

เซอร์โวจิ๋วอย่าง SG90 และ MG90S คือมอเตอร์ที่มีวงจรควบคุมและเฟืองทดในตัว สั่งด้วยพัลส์ไฟฟ้าทุก 20 ms (50 Hz) ความกว้างพัลส์ราว 1–2 ms บอกมุมที่ต้องการ แล้วมันหมุนไปค้างที่มุมนั้นเอง จุดที่มือใหม่พลาดเกือบทุกคนไม่ใช่โค้ด แต่เป็นไฟเลี้ยง เซอร์โวกินกระแสกระชากจนบอร์ดรีเซ็ต บทนี้จึงพูดเรื่องสัญญาณกับไฟเลี้ยงไปพร้อมกัน

ตัวเลขในบทอ้างอิง ESP32 รุ่นแรกบน Arduino-ESP32 core 3.x และเซอร์โวแบบ 180° (ไม่ใช่แบบหมุนต่อเนื่อง 360°)

เซอร์โวรู้มุมได้ยังไง

ข้างในมีมอเตอร์ DC เฟืองทด และตัวต้านทานปรับค่า (potentiometer) ติดกับแกนขาออก วงจรในตัวเทียบความกว้างพัลส์ที่เราส่งกับตำแหน่งแกนจริง แล้วหมุนมอเตอร์จนสองค่าตรงกัน ถ้ามีแรงดันแกนออกจากตำแหน่ง มันจะดันกลับ นี่คือเหตุผลที่เซอร์โวกินกระแสแม้ไม่ได้ขยับให้เห็น

สายมี 3 เส้น สีที่พบบ่อยคือ น้ำตาล = GND, แดง = ไฟเลี้ยง, ส้ม = สัญญาณ ดูเอกสารของตัวที่ซื้อมาก่อนต่อทุกครั้ง

สัญญาณ: 50 Hz และความกว้างพัลส์

ความกว้างพัลส์ตำแหน่ง (ตามสเปกผู้ขาย SG90)
1.0 ms0°
1.5 ms90° (กลาง)
2.0 ms180°

ส่งพัลส์ซ้ำทุก 20 ms ค่ากลางเป็นทางสายกลางที่ใช้ได้ทุกตัว แต่ปลายสองด้านแต่ละตัวไม่เท่ากัน ไลบรารี ESP32Servo ตั้งค่าเริ่มต้นไว้ 544–2400 µs และยอมให้กว้างสุด 500–2500 µs ตัวที่ซื้อมาอาจหมุนได้ไม่ถึง 180° เพราะติดตัวหยุดกลไก ถ้าสั่งเลยไป มอเตอร์จะพยายามดันค้างไว้ กินกระแสเต็มที่และร้อน

ทดสอบหาปลายจริงของเซอร์โวตัวนั้นก่อน แล้วใช้ช่วงที่ปลอดภัย เช่น 20–160° อย่าสั่งไปชนขอบ

ตัวอย่างคำนวณ: แปลง µs เป็นค่า duty ของ LEDC

ESP32 สร้าง PWM ด้วยวงจร LEDC ตั้งความถี่ 50 Hz และความละเอียด 14 บิต (ช่วงที่ใช้ได้ทุกชิปตามเอกสาร Arduino-ESP32 ชิปรุ่นแรกได้ถึง 20 บิต)

  1. หนึ่งรอบ = 1 ÷ 50 = 20 ms = 20,000 µs
  2. 14 บิต = 2¹⁴ = 16,384 ขั้น ต่อรอบ → ขั้นละ 20,000 ÷ 16,384 ≈ 1.22 µs
  3. 1,500 µs → 1,500 × 16,384 ÷ 20,000 = 1,228.8 → ใช้ 1,229 (โค้ดหารจำนวนเต็มได้ 1,228 ต่างกันไม่ถึง 1.3 µs)
  4. 1,000 µs → 819 และ 2,000 µs → 1,638
  5. ช่วง 1,000 µs ครอบ 180° → 1° ≈ 5.6 µs ≈ 4.5 ขั้น ละเอียดพอสำหรับของเล่น
// ESP32 + Arduino-ESP32 core 3.x, เซอร์โวต่อ GPIO13
const int SERVO_PIN = 13;

uint32_t usToDuty(uint32_t us) {
  return us * 16384UL / 20000UL;   // 14 บิต ที่ 50 Hz
}

void setup() {
  ledcAttach(SERVO_PIN, 50, 14);
  ledcWrite(SERVO_PIN, usToDuty(1500));  // ไปตำแหน่งกลาง
}

void loop() {}

ถ้าไม่อยากคิดเอง ไลบรารี ESP32Servo (ติดตั้งจาก Library Manager) ทำเหมือนกันแต่สั่งเป็นองศา

#include <ESP32Servo.h>
Servo arm;

void setup() {
  arm.setPeriodHertz(50);
  arm.attach(13, 1000, 2000);   // ขา, พัลส์ต่ำสุด, สูงสุด (µs)
}

void loop() {
  arm.write(20);  delay(1000);
  arm.write(160); delay(1000);
}

ESP32 รุ่นแรกคุมเซอร์โวได้ 16 ตัวด้วย LEDC ตาม README ของไลบรารี (S2 ได้ 8, C3 ได้ 6) ขาที่ README แนะนำคือ 2, 4, 12–19, 21–23, 25–27, 32–33

แหล่งจ่าย 5V แยกจ่ายกระแสพอสำหรับเซอร์โวเซอร์โวคร่อมตัวเก็บประจุ 470 µFกราวด์ร่วมต่อ GND ของทุกส่วนถึงกันESP32ส่งแค่สัญญาณ PWM
ไฟเซอร์โวแยกจากบอร์ด แต่กราวด์ต้องต่อถึงกัน

ไฟเลี้ยง: แยกได้ แต่กราวด์ต้องร่วม

สเปกผู้ขายระบุไฟเลี้ยง 4.8–6 V (5 V ใช้ทั่วไป) กระแสแต่ละช่วงต่างกันมาก

สถานะSG90MG90S
อยู่นิ่ง~10 mA~10 mA
กำลังหมุน100–250 mA120–250 mA
ติดขัด (stall)~360 mA (วัดโดยผู้ขายหนึ่งราย) แหล่งอื่นบอก ~550 mA~700 mA (วัด)
แรงบิด~1.7 kg·cm (วัด)2.2 kg·cm (สเปก)

ตัวเลข stall ของ SG90 ต่างกันตามแหล่งและตามล็อตของตัวเลียนแบบที่มีเยอะในตลาด ใช้เป็นช่วงสำหรับวางแผน ไม่ใช่ค่าตายตัว

วิธีต่อที่ปลอดภัย:

  • ไฟ 5 V ของเซอร์โว มาจากแหล่งจ่ายแยก (อะแดปเตอร์ 5 V หรือโมดูลลดแรงดัน) ไม่ดึงจากขา 3.3 V ของบอร์ดเด็ดขาด
  • GND ของแหล่งจ่าย ต่อเข้ากับ GND ของ ESP32 สัญญาณ PWM วัดเทียบกับกราวด์ ถ้าไม่ต่อร่วม เซอร์โวจะสั่น กระตุก หรือไม่ขยับเลย
  • ตัวเก็บประจุ 470 µF ขึ้นไป คร่อมไฟเลี้ยงใกล้เซอร์โว (ขายาว = +) ทำหน้าที่เป็นถังสำรองตอนมอเตอร์ออกตัว Adafruit แนะนำค่านี้เพื่อแก้อาการบอร์ดรีเซ็ต

ตัวอย่างคำนวณ: เลือกแหล่งจ่ายให้หุ่นแขน 3 ข้อ

แขนกลของเล่นใช้ MG90S 3 ตัว

  1. กรณีแย่สุด ทุกตัวติดขัดพร้อมกัน: 3 × 0.7 A = 2.1 A
  2. เผื่ออีกราว 20–30% สำหรับตัวที่กินมากกว่าค่าวัด: 2.1 × 1.25 ≈ 2.6 A
  3. เลือกแหล่งจ่าย 5 V 3 A แยกจากบอร์ด ESP32 ใช้ไฟ USB ของมันเอง
  4. ถ้าเป็น SG90 3 ตัว เผื่อตัวละ 0.5 A → 1.5 A → แหล่งจ่าย 5 V 2 A ก็พอ

ถ้าใช้แบตเตอรี่ลิเธียม ให้ผ่านวงจรป้องกันและโมดูลลดแรงดันที่รับกระแสได้ตามนี้ ห้ามต่อแบตตรงเข้าเซอร์โวโดยไม่รู้แรงดันจริง แพ็กลิเธียม 2 เซลล์เต็มที่ราว 8.4 V เกินสเปกเซอร์โวไปมาก

ข้อผิดพลาดที่เจอบ่อย

  • ESP32 รีเซ็ตทุกครั้งที่เซอร์โวขยับ ไฟตกจากกระแสกระชาก แยกไฟเลี้ยงและใส่ตัวเก็บประจุ
  • ลืมต่อกราวด์ร่วม อาการคือสั่นมั่ว หรือหมุนไปมุมแปลก ๆ
  • สั่งไปสุดขอบ 0° หรือ 180° เซอร์โวครางค้าง ร้อน เฟืองพลาสติกของ SG90 รูดได้
  • ใช้เซอร์โวแบบ 360° ด้วยความเข้าใจว่าสั่งมุมได้ แบบนั้นพัลส์คุมความเร็วและทิศ ไม่ใช่มุม
  • ใช้แขนยาวเกินแรงบิด 1.7 kg·cm แปลว่าที่ระยะ 1 cm ยกได้ราว 1.7 kg ที่ระยะ 5 cm เหลือราว 340 g ก่อนติดขัด
  • ชิ้นงานพิมพ์ยึดเซอร์โวหลวม เซอร์โวหมุนตัวเองแทนหมุนแขน ออกแบบช่องให้พอดี (ดูวิธีพิมพ์ชิ้นงานให้สวมพอดี)

ความปลอดภัย

งานนี้อยู่ที่ 5 V ทั้งหมด ถ้าใช้อะแดปเตอร์เสียบปลั๊ก ใช้ตัวที่มีกล่องปิดมิดชิด ห้ามแกะหรือต่อสายฝั่งไฟบ้าน มอเตอร์ที่ติดขัดนาน ๆ ร้อนจนเฟืองละลายได้ ตัดไฟเมื่อได้ยินเสียงครางค้าง และระวังนิ้วกับแขนกลตอนเปิดไฟครั้งแรก เพราะเซอร์โวจะกระโดดไปตำแหน่งเริ่มต้นทันที

บทถัดไป: เซนเซอร์สำหรับของเล่น เลือกแบบไหน ต่อยังไง

แหล่งข้อมูล

คำถามที่พบบ่อย

ต่อเซอร์โวตัวเดียวเข้าขา 5V ของบอร์ดได้ไหม

ทดลองตัวเดียวแบบไม่มีโหลดมักพอไหว แต่ตอนเริ่มหมุนกระแสกระชากจนบอร์ดรีเซ็ตได้ ใส่ตัวเก็บประจุ 470 µF ขึ้นไปคร่อมไฟเลี้ยงเซอร์โว และถ้ามีตั้งแต่สองตัวหรือมีแรงต้าน ให้ใช้แหล่งจ่าย 5 V แยก

ขา GPIO 3.3 V ของ ESP32 สั่งเซอร์โวที่เลี้ยง 5 V ได้ไหม

เซอร์โวจิ๋วส่วนใหญ่รับสัญญาณ 3.3 V ได้ในทางปฏิบัติ ตัวอย่างยอดนิยมก็ต่อตรง ถ้าตัวไหนสั่นหรือไม่ตอบสนอง ลองใช้ตัวแปลงระดับสัญญาณ และตรวจกราวด์ร่วมก่อน

SG90 กับ MG90S ต่างกันตรงไหน

ขนาดและสายเหมือนกัน MG90S ใช้เฟืองโลหะ แรงบิดมากกว่า แต่กินกระแสตอนติดขัดสูงกว่า (ผู้ขายรายหนึ่งวัดได้ราว 700 mA เทียบกับ SG90 ราว 360 mA)

วงจรและโค้ดในบทความทดสอบกับบอร์ดตัวอย่าง บอร์ดต่างรุ่นอาจใช้ขาต่างกัน ตรวจ pinout ของบอร์ดที่ใช้ก่อนต่อไฟเสมอ

อ่านต่อ

#วงจรเริ่มต้น

บอร์ด USB-C ไม่ติดเมื่อใช้สาย C ถึง C เพราะขาด ตัวต้านทาน 5.1 kΩ ที่ขา CC

บอร์ดพอร์ต USB-C ที่เสียบสาย A-to-C ติด แต่สาย C-to-C ไม่ติด เพราะไม่มี 5.1 kΩ ที่ขา CC1 และ CC2 แยกกันคนละตัว ทำไมที่ชาร์จไม่จ่ายไฟ วัดยังไง และแก้ยังไง

อ่าน 6 นาที
#วงจรเริ่มต้น

ปุ่มสัมผัส บนชิ้นงานพิมพ์ 3 มิติ ด้วยขา touch ของ ESP32 กับ สีนำไฟฟ้า

ทำปุ่มแตะบนของเล่นพิมพ์ 3 มิติ ด้วยขา touch ของ ESP32 กับสีหรือฟิลาเมนต์นำไฟฟ้า ตั้งค่า threshold จาก baseline และจำไว้ว่า ESP32 ค่าลดเมื่อแตะ แต่ S2/S3 ค่าเพิ่ม

อ่าน 9 นาที
#วงจรเริ่มต้น

เบรดบอร์ด กับสาย จัมเปอร์ แถวไหนต่อกัน และทำไม ESP32 ไม่พอดีบอร์ด

ข้างในเบรดบอร์ดต่อกันยังไง แถวละ 5 รู ร่องกลาง รางไฟที่บางบอร์ดขาดกลาง ทำไมบอร์ด ESP32 DevKit เสียบแล้วไม่เหลือรู แก้ยังไง และข้อผิดพลาดการต่อสายที่เจอบ่อย

อ่าน 6 นาที