ควบคุม DC Motor ด้วย L298N

ควบคุม DC Motor ด้วย L298N

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

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

บทความนี้จะสอนใช้งาน ATmega328P ควบคุมความเร็วมอเตอร์ไฟฟ้ากระแสตรง (DC motor) ด้วยการเขียนโปรแกรมภาษาซี (C) มาตรฐาน โดยใช้โมดูลขับมอเตอร์ L298N ที่มีขาที่ใช้งานสำหรับควบคุมความเร็วมอเตอร์ คือขา ENA และ ENB โดย ENA จะควบคุมมอเตอร์ A ที่ต่อกับ IN1 และ IN2 ส่วน ENB จะควบคุมมอเตอร์ B ที่ต่อกับ IN3 และ IN4

ควบคุม DC Motor ด้วย L298N


การต่อใช้งาน

Out 1: ช่องต่อขั้วไฟของมอเตอร์ A
Out 2: ช่องต่อขั้วไฟของมอเตอร์ A
Out 3: ช่องต่อขั้วไฟของมอเตอร์ B
Out 4: ช่องต่อขั้วไฟของมอเตอร์ B

12V: ช่องจ่ายไฟเลี้ยงมอเตอร์ 12V (ต่อได้ตั้งแต่ 5V ถึง 35V)
GND: ช่องต่อไฟลบ (Ground)
5V: ช่องจ่ายไฟเลี้ยงมอเตอร์ 5V (หากมีการต่อไฟเลี้ยงที่ช่อง 12V แล้ว
ช่องนี้จะทำหน้าที่จ่ายไฟออก เป็น 5V Output
สามารถต่อไฟจากช่องนี้ไปเลี้ยงบอร์ด ATmega328P ได้

ENA: ช่องต่อสัญญาณ PWM สำหรับมอเตอร์ A
IN1: ช่องต่อสัญญาณลอจิคเพื่อควบคุมทิศทางของมอเตอร์ A
IN2: ช่องต่อสัญญาณลอจิคเพื่อควบคุมทิศทางของมอเตอร์ A
IN3: ช่องต่อสัญญาณลอจิคเพื่อควบคุมทิศทางของมอเตอร์ B
IN4: ช่องต่อสัญญาณลอจิคเพื่อควบคุมทิศทางของมอเตอร์ B
ENB: ช่องต่อสัญญาณ PWM สำหรับมอเตอร์ B


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

วงจร H-Bridge ของ L298N จะขับกระแสเข้ามอเตอร์ ตามขั้วที่กำหนดด้วยลอจิกเพื่อควบคุมทิศทาง ส่วนความเร็วของมอเตอร์นั้นจะถูกควบคุมด้วย สัญญาณ (PWM Pulse Width Modulation)

PWM หมายถึง การควบคุมช่วงจังหวะการทำงานของอิเล็กตรอน ลองจินตนาการถึงแปรงขดลวดในมอเตอร์เป็นระหัดวิดน้ำและอิเล็กตรอนเป็นน้ำที่ตกลงมาจากระหัดวิดน้ำ ค่าแรงดันไฟฟ้าก็คล้ายกับกระแสน้ำที่ไหลผ่านระหัดวิดน้ำด้วยความเร็วคงที่ ยิ่งกระแสน้ำไหลเร็วเท่าไรก็จะหมายความว่าแรงดันไฟฟ้ายิ่งสูงขึ้น แต่มอเตอร์มีอัตราความเร็วคงที่และสามารถเสียหายได้หากมีแรงดันไฟฟ้าสูงไหลผ่านหรือหยุดทันทีเพื่อที่จะหยุดมอเตอร์ ดังนั้น PWM คล้ายกับการควบคุมระหัดวิดน้ำให้ตักน้ำในจังหวะคงที่ที่กระแสน้ำคงที่ ยิ่งระหัดวิดน้ำหมุนเร็วเท่าไรช่วงของ pulse ก็จะยาวขึ้น ในทางกลับกันถ้าระหัดวิดน้ำหมุนช้าช่วงของ pulse จะสั้นลง ดังนั้นเพื่อยืดอายุการใช้งานของมอเตอร์จึงควรที่จะควบคุมมอเตอร์ด้วย PWM


สัญญาณ (PWM Pulse Width Modulation)

 รายการอุปกรณ์


ขั้นตอนการทํางาน

1 : ทดสอบโปรแกรมแรก กับ ATmega328P


โปรแกรมแรกของ การใช้งานไมโครคอนโทรลเลอร์มักจะเป็น Blink ไฟกะพริบ ซึ่งเป็นหนึ่งในโปรแกรมที่ง่ายที่สุดเท่าที่จะเป็นไปได้ในการเขียนภาษาโปรแกรมต่างๆ เพราะฉะนั้นโดยธรรมเนียมปฏิบัติแล้ว มักจะใช้ในการตรวจสอบว่าเขียนภาษาโปรแกรมได้ถูกต้องหรือระบบมีการประมวลผลที่ถูกต้อง และมักถูกใช้เป็นตัวอย่างที่ง่ายที่สุดในการแสดงผลลัพธ์ของการเขียนโปรแกรม โดยทำตามขั้นตอนลิงค์ด้านล่าง


2: เชื่อมต่อมอเตอร์ เข้ากับ วงจร ATmega328P


เชื่อมต่อ สวิตช์กดติดปล่อยดับ 2 ขา เข้ากับ ขา PC1 , PC2 และ PC3 ของ ATmega328P ตามรูปด้านล่าง

ควบคุม DC Motor ด้วย L298N


ถ้าต้องการใช้งานขา ENB ให้ ให้ถอดจัมเปอร์ออก

ควบคุม DC Motor ด้วย L298N


เชื่อมต่อ L298N เข้ากับ ขา PB1 , PB2 และ PB3 ของ ATmega328P ตามรูปด้านล่าง

ควบคุม DC Motor ด้วย L298N



3: เขียนโค้ด ควบคุมมอเตอร์ DC Motor

ตัวอย่างโค้ด เขียนโค้ดแบบ ใช้ระบบเลขฐานสอง เป้าหมายคือ ถ้าสวิตช์ ตัวที่ 1 ถูก กด ให้มอเตอร์ หมุนตามเข็มนาฬิกา หรือ เดินหน้า , ถ้า สวิตช์ ตัวที่ 3 ถูก กด ให้มอเตอร์ หมุนทวนเข็มนาฬิกา หรือ ถอยหลัง และ ถ้า สวิตช์ ตัวที่ 2 ถูก กด ให้มอเตอร์หยุด

#include <avr/io.h>
#define F_CPU 16000000UL
#include "util/delay.h"

//Test1 the  PINC1 
#define forward  (PINC & 0b00000010)

//Test2 the PINC2
#define stop     (PINC & 0b00000100)

//Test3 the PINC3
#define backward (PINC & 0b00001000)

//OUTPUT DATA FOR MOTOR
#define run_forward  0b00000100
#define run_backward 0b00001000
#define stop_running 0b00000000

int main(void)
{
  
    DDRD |= (1 << DDD6); // Configuring PD6 as Output PWM
    OCR0A = 191;  // set PWM for 75% duty cycle

    TCCR0A |= (1 << COM0A1);  // set none-inverting mode
    TCCR0A |= (1 << WGM01) | (1 << WGM00);  // set fast PWM Mode
    TCCR0B |= (1 << CS01);  // set prescaler to 8 and starts PWM 

    DDRC |= 0b11110001; // Configuring PC3,PC2,PC1 as Input
    PORTC |= 0b00001110; // Enabling Internal Pull-Up to PC3,PC2,PC1

    DDRB |= 0b00001100; // Configuring PB3,PB2 as Output
    PORTB |= 0b11110011; // Writing LOW to PB3,PB2

    while (1) 
    {
        if (forward == 0)
        {
            PORTB = stop_running;
            _delay_ms(250);
            PORTB = run_forward;
        }
        else if (stop == 0)
        {
            PORTB = stop_running;
            _delay_ms(250);
            PORTB = stop_running;
        }
        else if (backward == 0)
        {
            PORTB = stop_running;
            _delay_ms(250);
            PORTB = run_backward;
        }
    }
}


อธิบายโค้ด


#include คือการเรียกใช้ไฟล์ภาษาซี จากไลบรารี ซึ่งอยู่ในโฟลเดอร์ avr และ ชื่อไฟล์ io.h สำหรับใช้งานเกี่ยวกับ ฟังก์ชั่น ควบคุมอินพุท/เอาท์พุท (เช่น PORTB, DDRB)

#include <avr/io.h>


#define คือ ค่าคงที่ และ ให้ชื่อว่า F_CPU กำหนดค่าให้เป็น 16000000 คือการกำหนดให้นำค่า 16MHz ไปไปคำนวณร่วมกับฟังก์ชั่น delay.h ในการหน่วงเวลาเพราะ วงจร Minimum ATmega328P Circuit ที่เราเชื่อมต่อนั้น ใช้คริสตัล 16Mhz เป็นแหล่งสัญญาณนาฬิกา

#define F_CPU 16000000UL


#include คือการเรียกใช้ไฟล์ภาษาซี จากไลบรารี ซึ่งอยู่ในโฟลเดอร์ util และ ชื่อไฟล์ delay.h สำหรับใช้งานเกี่ยวกับ ฟังก์ชั่น การหน่วงเวลา

#include "util/delay.h"


#define คือ ค่าคงที่ กำหนดให้ขา PC1 มีชื่อว่า forward สำหรับรับค่าจากสวิตช์ ตัวที่ 1

#define forward (PINC&0b00000010)


#define คือ ค่าคงที่ กำหนดให้ขา PC2 มีชื่อว่า stop สำหรับรับค่าจากสวิตช์ ตัวที่ 2

#define stop    (PINC&0b00000100)


#define คือ ค่าคงที่ กำหนดให้ขา PC3 มีชื่อว่า backward สำหรับรับค่าจากสวิตช์ ตัวที่ 3

#define backward (PINC&0b00001000)


#define คือ ค่าคงที่ มีชื่อว่า run_forward คำสั่งให้มอเตอร์ หมุนตามเข็มนาฬิกา (ขึ้นอยู่กับการต่อสายด้วย) โดย ให้ขา PB2 เอาต์พุตเป็น HIGH และ ขา PB3 เอาต์พุตเป็น LOW

#define run_forward 0b00000100


#define คือ ค่าคงที่ มีชื่อว่า run_backward คำสั่งให้มอเตอร์ หมุนทวนเข็มนาฬิกา (ขึ้นอยู่กับการต่อสายด้วย) โดย ให้ขา PB2 เอาต์พุตเป็น LOW และ ขา PB3 เอาต์พุตเป็น HIGH

#define run_backward 0b00001000


#define คือ ค่าคงที่ มีชื่อว่า stop_running คำสั่งให้มอเตอร์ หยุดการทํางาน โดย ให้ขา PB2 เอาต์พุตเป็น LOW และ ขา PB3 เอาต์พุตเป็น LOW

#define stop_running 0b00000000


กำหนดให้เป็นขา PฺฺD6 ทำงานแบบเอาท์พุท PWM

DDRD |= (1 << DDD6); 


กำหนดค่า PWM ค่า 0 ถึง 255 เป็นค่าความเร็ว ค่ายิงน้อยลงจะมอเตอร์หมุนช้าลง ในโค้ดคือ 191 คือ มีความเร็ว 75%

OCR0A = 191; 


เป็นโค้ดต่อเนื่องในการกำหนดค่า PWM

TCCR0A |= (1 << COM0A1);  // set none-inverting mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);  // set fast PWM Mode
TCCR0B |= (1 << CS01);  // set prescaler to 8 and starts PWM 


กำหนดให้เป็นขา PC3,PC2,PC1 ทำงานแบบอินพุท

DDRC |= 0b11110001;


เปิดการทำงาน Internal Pull-Up ให้กับขา PC3,PC2,PC1

PORTC |= 0b00001110;


กำหนดให้เป็นขา PฺฺB3 และ PB2 ทำงานแบบเอาท์พุท

DDRB |= 0b00001100; 


กำหนดให้เป็นขา PฺฺB3 และ PB2 ส่งค่าเอาท์พุท LOW ออกไป

PORTB |= 0b11110011;


ถ้า สวิตช์ ตัวที่ 1 (forward) ถูก กด

if (forward == 0)


เรียกคำสั่ง (ทีประกาศไว้ด้านบน บรรทัด 15 และ 17) ให้มอเตอร์ หมุนตามเข็มนาฬิกา หรือ เดินหน้า โดยเรียก stop_running; คือให้มอเตอร์หยุดทำงานก่อน 250 มิลลิวินาที แล้วจึงเรียกใช้งานคำสั่ง run_forward ; เพื่อให้มอเตอร์ หมุนตามเข็มนาฬิกา หรือ เดินหน้า

PORTB = stop_running;
_delay_ms(250);
PORTB = run_forward;


ถ้า สวิตช์ ตัวที่ 2 (stop) ถูก กด

else if (stop == 0)


เรียกคำสั่ง (ทีประกาศไว้ด้านบน บรรทัด 17) ให้มอเตอร์หยุด

PORTB = stop_running;
_delay_ms(250);
PORTB = stop_running;


ถ้า สวิตช์ ตัวที่ 3 (backward) ถูก กด

else if (backward == 0)


เรียกคำสั่ง (ทีประกาศไว้ด้านบน บรรทัด 16 และ 17) ให้มอเตอร์ หมุนทวนเข็มนาฬิกา หรือ ถอยหลัง โดยเรียก stop_running; คือให้มอเตอร์หยุดทำงานก่อน 250 มิลลิวินาที แล้วจึงเรียกใช้งานคำสั่ง run_backward ; เพื่อให้มอเตอร์ หมุนทวนเข็มนาฬิกา หรือ ถอยหลัง

PORTB = stop_running;
_delay_ms(250);
PORTB = run_backward;


4: ทดสอบการทํางาน


เมื่อกดสวิตช์ตัวที่ 1 ในตัวอย่าง มอเตอร์จะหมุน ตามเข็มนาฬิกา เมื่อกดสวิตช์ตัวที่ 3 จะหมุนตรงข้ามคือ ทวนเข็มนาฬิกา และ กดสวิตช์ตัวที่ 2 มอเตอร์จะหยุดหมุน

<<< C6: การใช้งาน PWM บทความก่อนหน้า | บทความต่อไป C8: ควบคุม Servo Motor >>>

Leave a Reply

Your email address will not be published. Required fields are marked *

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

Privacy Preferences

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

Allow All
Manage Consent Preferences
  • Always Active

Save