การใช้งาน Maker Drive: Simplifying H-Bridge Motor Driver for Beginner โมดูลขับมอเตอร์อย่างง่าย

ESP32-S3

Maker Motor Driver

N20 Micro Metal Gear Motor with Encoder – 6V 33RPM

จากอุปกรณ์ที่คุณมี

  • ESP32-S3
  • Maker Drive
  • N20 Gear Motor + AB Encoder จำนวน 1 หรือ 2 ตัว
  • Battery 7.4V (18650 จำนวน 2 ก้อน)

เราจะทดลองให้มอเตอร์หมุน พร้อมอ่านค่า Encoder แบบ Real-Time

1. ทำความเข้าใจ Maker Drive

Maker Drive เป็นโมดูล H-Bridge แบบ Dual Channel

สามารถควบคุมมอเตอร์ DC ได้ 2 ตัว

แต่ละช่องมี

Motor A
- DIRA
- PWMA

Motor B
- DIRB
- PWMB

หลักการทำงาน

DIR = ทิศทางหมุน

PWM = ความเร็ว

ตัวอย่าง

DIR = HIGH
PWM = 150

=> หมุนไปข้างหน้า
DIR = LOW
PWM = 150

=> หมุนย้อนกลับ

2. ขั้วต่อบน N20 Encoder

มอเตอร์ N20 Encoder ส่วนใหญ่จะมีสาย 6 เส้น

Motor +
Motor -

Encoder VCC
Encoder GND

Encoder A
Encoder B

ตัวอย่างสีที่พบบ่อย

แดง     = Motor +
ดำ = Motor -

เหลือง = Encoder A
ขาว = Encoder B

น้ำเงิน = VCC
เขียว = GND

แต่ควรตรวจสอบจาก Datasheet หรือใช้มัลติมิเตอร์วัดก่อน

3. การต่อวงจร

มอเตอร์

N20

Motor+ -------- MA+
Motor- -------- MA-

บน Maker Drive

MA+
MA-

4. ต่อ Encoder เข้ากับ ESP32-S3

Encoder ของ N20 เป็นแบบ Quadrature Encoder

มีสัญญาณ

A
B

ต่อดังนี้

Encoder VCC
→ 3.3V

Encoder GND
→ GND

Encoder A
→ GPIO4

Encoder B
→ GPIO5

สรุป

ESP32-S3

GPIO4 ← Encoder A

GPIO5 ← Encoder B

3.3V ← Encoder VCC

GND ← Encoder GND

5. ต่อ Maker Drive กับ ESP32-S3

ตัวอย่างกำหนดขา

DIRA → GPIO12

PWMA → GPIO13

ต่อสาย

Maker Drive

DIRA ← GPIO12

PWMA ← GPIO13

GND ← GND

สำคัญมาก

ESP32 GND
Maker Drive GND
Battery GND

ต้องต่อร่วมกันทั้งหมด

Common Ground

6. การต่อแบตเตอรี่

ใช้แบตเตอรี่ 18650 จำนวน 2 ก้อน

3.7V + 3.7V

ต่ออนุกรม

7.4V Nominal

8.4V Full Charge

ต่อเข้าที่

Battery +

→ VMOT

Battery -

→ GND

บน Maker Drive

แผนผังรวม

Battery 7.4V
|
|
v

+----------------+
| Maker Drive |
| |
| VMOT GND |
| |
| DIRA PWMA |
+----------------+
| |
| |
GPIO12 GPIO13
| |
+----------------+
| ESP32-S3 |
+----------------+

GPIO4 <--- Encoder A
GPIO5 <--- Encoder B

3V3 ---> Encoder VCC
GND ---> Encoder GND

Maker MA+ ---> Motor+
Maker MA- ---> Motor-

7. หลักการอ่าน Encoder

Encoder จะสร้าง Pulse

ตัวอย่าง

A

__----__----__----__

B

----__----__----__--

ESP32 จะนับ Pulse

Pulse = 100

หมายความว่า

ล้อหมุนไปแล้ว 100 Tick

8. วิธีคำนวณรอบหมุน

สมมุติ Encoder

12 PPR

และ Gear Ratio

1:30

จะได้

12 × 30

= 360 Pulse / รอบล้อ

ถ้านับได้

360 Pulse

แปลว่า

ล้อหมุนครบ 1 รอบ

9. วิธีคำนวณระยะทาง

สมมุติล้อ

เส้นผ่านศูนย์กลาง

32 mm

เส้นรอบวง

π × D

3.1416 × 32

= 100.5 mm

ล้อหมุน 1 รอบ

= 100.5 mm

ถ้า Encoder

360 Pulse

จะได้

1 Pulse

=

100.5 / 360

=

0.279 mm

ดังนั้น

100 Pulse

=

27.9 mm

10. เป้าหมายการทดลองแรก

ทดลอง 3 อย่าง

ทดสอบที่ 1

PWM = 100

หมุน 3 วินาที

หยุด

ทดสอบที่ 2

แสดงค่า Encoder

Pulse Count

บน Serial Monitor

ทดสอบที่ 3

สั่งให้หยุดเมื่อครบ

500 Pulse

เช่น

while(pulseCount < 500)
{
Motor Forward
}

Motor Stop

จากตัวอย่างการต่อวงจรก่อนหน้า

DIRA  -> GPIO12
PWMA -> GPIO13

DIRB -> GPIO14
PWMB -> GPIO15

ไฟล์ motordriver_1.0.ino

/*
motordriver_1.0.ino
ESP32-S3 + Maker Drive
Test Motor A and Motor B

DIRA -> GPIO12
PWMA -> GPIO13

DIRB -> GPIO14
PWMB -> GPIO15
*/

const int DIRA = 12;
const int PWMA = 13;

const int DIRB = 14;
const int PWMB = 15;

// PWM Configuration
const int PWM_FREQ = 1000;
const int PWM_RESOLUTION = 8; // 0-255

void setup()
{
Serial.begin(115200);

pinMode(DIRA, OUTPUT);
pinMode(DIRB, OUTPUT);

// ESP32 Core 3.x
ledcAttach(PWMA, PWM_FREQ, PWM_RESOLUTION);
ledcAttach(PWMB, PWM_FREQ, PWM_RESOLUTION);

stopMotor();

Serial.println();
Serial.println("=================================");
Serial.println("Micromouse Motor Driver Test");
Serial.println("Maker Drive + ESP32-S3");
Serial.println("=================================");
}

void loop()
{
Serial.println("Motor Forward");

motorForward(150);

delay(3000);

stopMotor();

delay(1000);

Serial.println("Motor Reverse");

motorReverse(150);

delay(3000);

stopMotor();

delay(2000);
}

void motorForward(int speedValue)
{
digitalWrite(DIRA, HIGH);
digitalWrite(DIRB, HIGH);

ledcWrite(PWMA, speedValue);
ledcWrite(PWMB, speedValue);
}

void motorReverse(int speedValue)
{
digitalWrite(DIRA, LOW);
digitalWrite(DIRB, LOW);

ledcWrite(PWMA, speedValue);
ledcWrite(PWMB, speedValue);
}

void stopMotor()
{
ledcWrite(PWMA, 0);
ledcWrite(PWMB, 0);
}

ผลลัพธ์ที่ควรได้

Motor Forward
(หมุนไปข้างหน้า 3 วินาที)

หยุด 1 วินาที

Motor Reverse
(หมุนย้อนกลับ 3 วินาที)

หยุด 2 วินาที

วนซ้ำ

หากมอเตอร์หมุนทิศทางไม่ถูกต้อง

ให้สลับสาย

MA+ <-> MA-

หรือ

MB+ <-> MB-

โดยไม่ต้องแก้โค้ด

ขั้นต่อไปที่ควรทำคือ motordriver_1.1.ino

  • เพิ่ม Encoder A/B
  • แสดง Pulse Count บน Serial Monitor
  • นับจำนวน Tick ของล้อ
  • คำนวณ RPM ของมอเตอร์

สำหรับ motordriver_1.1.ino เราจะเพิ่มความสามารถดังนี้

  • ควบคุมมอเตอร์ผ่าน Maker Drive
  • อ่าน Encoder A/B
  • นับ Pulse
  • คำนวณ Tick
  • คำนวณ RPM ทุก 1 วินาที
  • แสดงผลบน Serial Monitor

การต่อวงจร

Encoder VCC -> 3.3V
Encoder GND -> GND

Encoder A -> GPIO4
Encoder B -> GPIO5

DIRA -> GPIO12
PWMA -> GPIO13

หาก Encoder ของคุณเป็นแบบ Hall Sensor 3.3V สามารถต่อเข้ากับ ESP32-S3 ได้โดยตรง

ไฟล์ motordriver_1.1.ino

/*
motordriver_1.1.ino

ESP32-S3
Maker Drive
N20 Motor + AB Encoder

DIRA -> GPIO12
PWMA -> GPIO13

Encoder A -> GPIO4
Encoder B -> GPIO5
*/

const int DIRA = 12;
const int PWMA = 13;

const int ENCODER_A = 4;
const int ENCODER_B = 5;

volatile long encoderCount = 0;

unsigned long lastRPMTime = 0;
long lastEncoderCount = 0;

const int PWM_FREQ = 1000;
const int PWM_RESOLUTION = 8;

const int MOTOR_SPEED = 150;

/*
ปรับตาม Encoder จริงของคุณ

ตัวอย่าง:
Encoder Disc = 12 PPR
Gear Ratio = 30

12 x 30 = 360 Pulse / Wheel Revolution
*/

const float PULSE_PER_REV = 360.0;

void IRAM_ATTR encoderISR()
{
bool A = digitalRead(ENCODER_A);
bool B = digitalRead(ENCODER_B);

if (A == B)
{
encoderCount++;
}
else
{
encoderCount--;
}
}

void setup()
{
Serial.begin(115200);

pinMode(DIRA, OUTPUT);

pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(ENCODER_B, INPUT_PULLUP);

attachInterrupt(
digitalPinToInterrupt(ENCODER_A),
encoderISR,
CHANGE
);

ledcAttach(PWMA, PWM_FREQ, PWM_RESOLUTION);

Serial.println();
Serial.println("=================================");
Serial.println("Micromouse Encoder Test");
Serial.println("ESP32-S3 + Maker Drive");
Serial.println("=================================");

motorForward(MOTOR_SPEED);

lastRPMTime = millis();
}

void loop()
{
if (millis() - lastRPMTime >= 1000)
{
long currentCount = encoderCount;

long pulseDelta =
currentCount - lastEncoderCount;

float rpm =
(pulseDelta * 60.0) /
PULSE_PER_REV;

Serial.print("Pulse Count : ");
Serial.print(currentCount);

Serial.print(" Delta : ");
Serial.print(pulseDelta);

Serial.print(" RPM : ");
Serial.println(rpm);

lastEncoderCount = currentCount;
lastRPMTime = millis();
}
}

void motorForward(int speedValue)
{
digitalWrite(DIRA, HIGH);
ledcWrite(PWMA, speedValue);
}

void motorReverse(int speedValue)
{
digitalWrite(DIRA, LOW);
ledcWrite(PWMA, speedValue);
}

void stopMotor()
{
ledcWrite(PWMA, 0);
}

ผลลัพธ์บน Serial Monitor

Pulse Count : 356    Delta : 356    RPM : 59.3
Pulse Count : 714 Delta : 358 RPM : 59.7
Pulse Count : 1072 Delta : 358 RPM : 59.7
Pulse Count : 1429 Delta : 357 RPM : 59.5

การตรวจสอบค่า PULSE_PER_REV ที่แท้จริง

เนื่องจาก N20 Encoder แต่ละรุ่นไม่เท่ากัน ให้ทดลองดังนี้

  1. ทำเครื่องหมายที่ล้อ 1 จุด
  2. หมุนให้ครบ 1 รอบพอดี
  3. ดูค่า Pulse Count

ตัวอย่างแสดงว่า

const float PULSE_PER_REV = 420.0;

ค่าที่วัดจริงจะแม่นยำกว่าการคำนวณจาก Datasheet

Link:https://www.genlogic.co.th/product/1002/maker-drive-simplifying-h-bridge-motor-driver-for-beginner-%E0%B9%82%E0%B8%A1%E0%B8%94%E0%B8%B9%E0%B8%A5%E0%B8%82%E0%B8%B1%E0%B8%9A%E0%B8%A1%E0%B8%AD%E0%B9%80%E0%B8%95%E0%B8%AD%E0%B8%A3%E0%B9%8C%E0%B8%AD%E0%B8%A2%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2?srsltid=AfmBOoogULK07Dp9zkpZIVlKCj5YRMPhhVTtJk333Oy_2EnGOu4Vli2d

http://wiki.fluidnc.com/en/hardware/ESP32-S3_Pin_Reference

https://www.robotics.org.za/N20-33RPM-ENC-6V

https://www.hackster.io/amal-shaji/reading-the-encoder-value-of-n20-motor-using-esp32-56575a