Daily Archives: 2015 年 07 月 30 日

Hello World 软硬兼施

树莓派控制直流电机

使用树莓派控制直流电机,包括控制转速和转向,这里使用的是L293D驱动芯片,简单易用
芯片接线方式如下图所示

L293D可以控制两路直流电机,这里做个简单演示,只控制一路,所以只用到了一侧的管脚
需要树莓派的三个gpio口,分别连L293D的1、2、7
1是使能信号,写死成高电平就行了
2是pwm,“脉冲宽度调制”,也就是宽边宽度的方波,7需要的信号与2相同
2、7的区别是,2或7有pwm信号是,电机转向是相反的
呵呵,偷个懒,继续简化,这里在用到2,将接2的线头改插到7上,电机如果翻转,也就成功了
也就是说,实际演示树莓派只用了2个gpio口~~嘻嘻

然后再看怎么用树莓派产生pwm信号~很简单:

1
2
3
4
5
6
GPIO.setup(gpiox, GPIO.OUT)
p = GPIO.PWM(gpiox, frequency) #创建一个 PWM 实例:
p.start(dc)   # dc 代表占空比(范围:0.0 <= dc >= 100.0)
p.ChangeFrequency(freq)   # freq 为设置的新频率,单位为 Hz
p.ChangeDutyCycle(dc)  # 修改占空比,范围:0.0 <= dc >= 100.0
p.stop() 停止 PWM:

好了,下面是整体的测试代码~~~其实是在一个“呼吸灯”的基础上加了一个使能信号,对应的,看到的是电机加速-减速-加速的过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#coding:utf-8 脉宽调制(PWM)输出
import time
import RPi.GPIO as GPIO
 
def init(pwm, en):
    GPIO.setmode(GPIO.BCM)
    #使能信号
    GPIO.setup(en, GPIO.OUT)
    GPIO.output(en, True)
    GPIO.setup(pwm, GPIO.OUT)
    p = GPIO.PWM(pwm, 50)
    p.start(0)
    try:
        while 1: #周期性修改占空比
            for dc in range(0, 101, 5):
                p.ChangeDutyCycle(dc);
                time.sleep(0.1)
            for dc in range(100, -1, -5):
                p.ChangeDutyCycle(dc);
                time.sleep(0.1)
    except KeyboardInterrupt:
        pass
    p.stop()
    GPIO.cleanup()
 
if __name__ == '__main__':
    init(20, 16)  # gpio20接L293D的2或7管脚,gpio16接1管脚

接线图如下(有点乱,电机的电源是一块12v的电池,没有出现在画面中,另外,呼吸灯还保留着)
另外,电机两极最好并联一个陶瓷电容,转动会更平滑:


————–over
———————-后记
如何用树莓派控制电机,进而控制小车的前进、后退、转向,这个问题困扰了我半个多月
大学四年,唯一值得炫耀的,是大三暑假时参加的电子设计大赛集训,后来还拿了一等奖,也是在那次的比赛作品中,接触到了可变频宽方波控制功率输出的思路,貌似现在满街跑的电动车也是这么控制车速的
这样,树莓派产生这种方波就行了,当时还不知道树莓派有专门的pmw输出,想的还是程序写循环、通过不同的sleep长度、输出方波。。。
然后下一个问题,方波信号是3.3v,怎么控制12v的电机?
开始的想法是继电器,但是继电器这东西,连变频方波,肯定不连续,估计效果会很差
两一个思路是三极管、场效应管放大,拿手头的三极管搭了一个两级的放大电路,不成功,而且第二级管子发热特别厉害~~这个思路肯定是通的,L293D内部也就是这玩意,只是咱水平不够
于是继续搜索解决方案,然后在“极客范”找到了类似功能的文章,不过它讲的貌似是老版的树莓派,产生pmw信号的方法很麻烦;然后最后找到一篇树莓派pmw信号实现呼吸灯的介绍,于是二者结合,有了上面的方案
~~呵呵,作为已有近10年没怎么搞过硬件的人,能搞得这个程度,自己还算满意 :)