四驱小车循迹实验-直流电机驱动封装

四驱小车循迹实验-直流电机驱动封装

    上篇文章已经介绍了四驱小车如何组装,这篇文章我们将继续介绍如何驱动小车前进后退以及左转右转;因为小车循迹的过程中,会遇到左转线、直线、右转线以及停顿标示;这个时候就需要小车能实现左转、右转、直行、停车、后退等动作。
#直流电机驱动板L298N驱动原理:
直流电机转动效果IN1IN2IN3IN4
MOTOR-A正向(调速)高电平/PWM低电平
反向(调速)低电平高电平/PWM
停止低电平低电平
刹车高电平高电平
MOTOR-B正向(调速)高电平/PWM低电平
反向(调速)低电平高电平/PWM
停止低电平低电平
刹车高电平高电平
    从上面表格可见,motorA连接引脚IN1和IN2,当IN1高电平IN2低电平的时候,电机正向转动,其中IN1输入PWM进行调速和扭矩变化;反之IN1低电平和IN2高电平的时候电机反向转动,从而实现倒车;其他电机以此类推。
#其中PWM控制转速和扭矩,示例如下:
1、创建PWM实例:p = GPIO.PWM(channel, frequency);
2、开始PWM:p.start(duty_cycle)  #duty_cycle为占空比;
3、更改频率,更改扭矩:p.ChangeFrequency(frequency);
4、更改占空比,更改转速:p.ChangeDutyCycle(duty_cycle);
5、PWM停止:p.stop()
#代码示例

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.shumeijiang.com
'''

import RPi.GPIO as GPIO ##引入GPIO模块
import time    ##引入time库
GPIO.setmode(GPIO.BCM)

#驱动类
class baseAct:
    def __init__(self, ain1, ain2, ain3, ain4, bin1, bin2, bin3, bin4):
        self.ain1 = ain1
        self.ain2 = ain2
        self.ain3 = ain3
        self.ain4 = ain4
        self.bin1 = bin1
        self.bin2 = bin2
        self.bin3 = bin3
        self.bin4 = bin4
        GPIO.setup(self.ain1, GPIO.OUT)
        GPIO.setup(self.ain2, GPIO.OUT)
        GPIO.setup(self.ain3, GPIO.OUT)
        GPIO.setup(self.ain4, GPIO.OUT)
        GPIO.setup(self.bin1, GPIO.OUT)
        GPIO.setup(self.bin2, GPIO.OUT)
        GPIO.setup(self.bin3, GPIO.OUT)
        GPIO.setup(self.bin4, GPIO.OUT)

    #结束动作
    def act_stop(self, duration, slow_time=0.15):

        #执行时间
        duration = float(duration)-slow_time
        time.sleep(duration)
   
        #self.init_move('forward', duration, 50, 50)

        if slow_time:
            #执行缓冲慢行
            self.apwm1.ChangeDutyCycle(20)
            self.apwm3.ChangeDutyCycle(20)
            self.bpwm1.ChangeDutyCycle(20)
            self.bpwm3.ChangeDutyCycle(20)
            time.sleep(slow_time)

        #结束动作
        self.apwm1.stop()
        self.apwm3.stop()
        self.bpwm1.stop()
        self.bpwm3.stop()
        GPIO.output(self.ain2, GPIO.LOW)
        GPIO.output(self.ain4, GPIO.LOW)
        GPIO.output(self.bin2, GPIO.LOW)
        GPIO.output(self.bin4, GPIO.LOW)

    ##PWM初始化
    def init_move(self, act_type, duration, duty_ratio, hz_num):

        if act_type == 'forward':
            hpin1 = self.ain1
            lpin1 = self.ain2
            hpin2 = self.ain3
            lpin2 = self.ain4
            hpin3 = self.bin1
            lpin3 = self.bin2
            hpin4 = self.bin3
            lpin4 = self.bin4
        elif act_type == 'backward':
            hpin1 = self.ain2
            lpin1 = self.ain1
            hpin2 = self.ain4
            lpin2 = self.ain3
            hpin3 = self.bin2
            lpin3 = self.bin1
            hpin4 = self.bin4
            lpin4 = self.bin3
        elif act_type == 'turn_left':
            hpin1 = self.ain1  
            lpin1 = self.ain2  #右前电机前进 pin2低电平则前进
            hpin2 = self.ain3
            lpin2 = self.ain4  #右后电机前进
            hpin3 = self.bin2
            lpin3 = self.bin1  #左前电机后退 pin2高电平则后退
            hpin4 = self.bin4
            lpin4 = self.bin3  #左后电机后退
        elif act_type == 'turn_right':
            hpin1 = self.ain2
            lpin1 = self.ain1  #右前电机后退  pin2高电平则后退
            hpin2 = self.ain4
            lpin2 = self.ain3  #右后电机后退
            hpin3 = self.bin1
            lpin3 = self.bin2  #左前电机前进  pin2高电平则前进
            hpin4 = self.bin3
            lpin4 = self.bin4  #左后电机前进
        else:
            print "不支持的类型"
            pass

        #挨个实例化每个电机的PWM实例
        self.apwm1 = GPIO.PWM(hpin1, hz_num) #实例PWM 并可自定义hz
        self.apwm1.start(0)           #初始占空比为0
        GPIO.output(hpin1, GPIO.HIGH) #设置单个电机一个高电压
        GPIO.output(lpin1, GPIO.LOW)  #另一个低电压
        self.apwm1.ChangeDutyCycle(duty_ratio) #设置用户自定义占空比

        #驱动第二个电机
        self.apwm3 = GPIO.PWM(hpin2, hz_num)
        self.apwm3.start(0)
        GPIO.output(hpin2, GPIO.HIGH)
        GPIO.output(lpin2, GPIO.LOW)
        self.apwm3.ChangeDutyCycle(duty_ratio)

        #驱动第三个电机
        self.bpwm1 = GPIO.PWM(hpin3, hz_num)
        self.bpwm1.start(0)
        GPIO.output(hpin3, GPIO.HIGH)
        GPIO.output(lpin3, GPIO.LOW)
        self.bpwm1.ChangeDutyCycle(duty_ratio)

        #驱动第四个电机
        self.bpwm3 = GPIO.PWM(hpin4, hz_num)
        self.bpwm3.start(0)
        GPIO.output(hpin4, GPIO.HIGH)
        GPIO.output(lpin4, GPIO.LOW)
        self.bpwm3.ChangeDutyCycle(duty_ratio)

    ##前进
    def act_forward(self, duration, duty_ratio, hz_num=50, close_slow=False):
        self.init_move('forward', duration, duty_ratio, hz_num)

        if close_slow:
            slow_time = 0
        else:
            slow_time = 0.15

        #停止动作 并执行缓冲
        self.act_stop(duration, slow_time)

    ##后退
    def act_backward(self, duration, duty_ratio, hz_num):
        self.init_move('backward', duration, duty_ratio, hz_num)
        #停止动作 并缓冲执行
        self.act_stop(duration)

    ##向左转
    def turn_left(self, duration, duty_ratio, hz_num, serial=False):
        self.init_move('turn_left', duration, duty_ratio, hz_num) #左转执行
        slow_time = 0.05  #减速时间
        if serial==True:
            slow_time = 0
        self.act_stop(duration, slow_time)  #动作停止

    ##向右转
    def turn_right(self, duration, duty_ratio, hz_num, serial=False):
        self.init_move('turn_right', duration, duty_ratio, hz_num) #右转执行
        slow_time = 0.05  #减速时间
        if serial==True:
            slow_time = 0 #连续不减速
        self.act_stop(duration, slow_time)  #动作停止

    ##刹车
    def act_break(self):
        GPIO.output(self.ain1, GPIO.HIGH)
        GPIO.output(self.ain2, GPIO.HIGH)
        GPIO.output(self.ain3, GPIO.HIGH)
        GPIO.output(self.ain4, GPIO.HIGH)

        GPIO.output(self.bin1, GPIO.HIGH)
        GPIO.output(self.bin2, GPIO.HIGH)
        GPIO.output(self.bin3, GPIO.HIGH)
        GPIO.output(self.bin4, GPIO.HIGH)
    如上代码可见,封装了直流电机驱动类baseAct,以及直行、后退、左转、右转和刹车等方法;实例化类后便可直接调用,其中ain1、ain2、ain3、ain4为左侧电机驱动板引脚,bin1、bin2、bin3、bin4为右侧电机驱动板引脚,分别对应即可。
#参考文章:https://www.shumeijiang.com/2020/05/04/直流电机驱动变速实验/

jiujiang

评论已关闭。