# Adafruit的树莓派教程第九课：控制一个直流电机

- URL: https://wuming.si/blog/683/
- Author: Aaron
- Published: 2014-06-16
- Language: zh-Hans
- Categories: Uncategorized
- Originally published at: https://blog.wo.ai/archives/683

#### 概览

这节课我们来学习如何使用Python和L293D芯片控制直流电机的速度和转向。

[![lesson9_1](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/d91617cf47_0226191347e60c44db21e4fc406f08bb.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/d91617cf47_0226191347e60c44db21e4fc406f08bb.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

在第八课里，我们学习了如何使用小派产生脉冲来控制伺服马达的位置。这节课我们将使用脉冲和L293D马达控制芯片来控制一个直流电机的转速并交替变换它的旋转方向。

#### 你需要的：

要完成这个项目，你需要下面一些东西。

1个树莓派  
[![lesson9_2](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/c6fcad3f4b_19a925d22e35be935b59faff228ec58d.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/c6fcad3f4b_19a925d22e35be935b59faff228ec58d.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

1个树莓派扩展板  
[![lesson9_3](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/188bd9e173_3bf119aa6a9e9d43f42daa19f5f5769e.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/188bd9e173_3bf119aa6a9e9d43f42daa19f5f5769e.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

一把公对公跳线  
[![lesson9_4](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/883bae20e7_23aba5cdacbff8c90cdcad62070f44ee.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/883bae20e7_23aba5cdacbff8c90cdcad62070f44ee.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

1个小块面包板  
[![lesson9_5](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/ba9b06f5c4_fc3a671207febe38e02578cadfab3a9e.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/ba9b06f5c4_fc3a671207febe38e02578cadfab3a9e.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

1个6V直流电机  
[![lesson9_6](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/f368e8bd32_1d7f34be9236d4bfc4560c8472c36636.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/f368e8bd32_1d7f34be9236d4bfc4560c8472c36636.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

L293D马达控制芯片  
[![lesson9_7](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/e379df4b23_2319303ab9e0b0c3b16b9d9152ef6811.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/e379df4b23_2319303ab9e0b0c3b16b9d9152ef6811.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

Adafruit Occidentalis 0.2及之后的操作系统  
[![lesson9_8](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/25ad045dbf_1845d1da2a2be9e38ed17de200e83dde.png)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/25ad045dbf_1845d1da2a2be9e38ed17de200e83dde.png "Adafruit的树莓派教程第九课：控制一个直流电机")

4节5号或7号电池盒及电池  
[![lesson8_8](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/024c4489dd_fdc37e246354f0b2234d47f151b1cea01.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/024c4489dd_fdc37e246354f0b2234d47f151b1cea01.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

#### PWM

PWM(Pulse Width Modulation，脉冲宽度调制)是一项用于控制电力的技术。在这里我们使用它来控制供给直流电机的电量及它的转速。

下面的图表展示了从树莓派的PWM针脚产生的脉冲信号。  
[![lesson9_10](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/ecc117768f_a266fc797cf865867897c32d1fd08457.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/ecc117768f_a266fc797cf865867897c32d1fd08457.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

PWM针每1/500秒产生一次脉冲。脉冲的长度控制了直流电机所能获得的电量。没有脉冲电机就不会转动，一次短脉冲会使电机以很慢的速度转动。如果脉冲持续总长度一半的时间，那么它就会获得总电量一半的电量。

#### PWM核心模块

Adafruit与Sean Cross一起编写了一个核心模块被包含在了[Occidentalis](http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2)发行版里。更多的细节请参照[这篇教程](http://www.geekfan.net/8808/ "Adafruit的树莓派教程第一课：为你的树莓派准备一张SD卡")。如果你想在Raspbian或者其他发行版上使用这个模块，参考[这里](http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2)来把模块安装到你的环境里。

你已经在第八课里使用过了PWM与伺服马达核心模块，用于控制伺服马达。这一次，你将使用相同的模块来控制电机的转速。

这个模块使用文件类型的接口，你可以通过读写这些特定的文件来控制针脚输出进一步控制伺服电机的行为。这使得使用Python或者其他语言来编写该接口十分容易。

**文件 – 描述**  
active – 1为激活，0为未激活。你可以通过读取它来查找输出针是否被激活，或者通过改写控制它的激活或未激活。  
delayed – 如果设置为1，你对其他文件的改动不会起作用直到你使用上面的active来激活输出针。  
mode – 改写文件来设置针脚是pwm，servo(伺服马达)还是audio(音频)。显然这里我们要设置为servo。注意这些针也会被小派的音频输出使用，所以你不能在使用声音的同时控制一个伺服马达。  
frequency – 每秒产生的脉冲次数。  
duty – 这个值应该介于0到100之间，代表了脉冲长度的百分比。数值越大，转速越快。

#### L293D

这是一个非常有用的芯片。它实际上可以独立控制两个电机。这节课我们将只使用芯片的一半针脚，在芯片右手边的大多数针脚用于控制第二个电机，但在树莓派上只有一个PWM输出针脚。

[![lesson9_11](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/d63a213482_09e9bf66c7634001bbbbb87ffae5371d.jpg)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/d63a213482_09e9bf66c7634001bbbbb87ffae5371d.jpg "Adafruit的树莓派教程第九课：控制一个直流电机")

L293D有两个+V的针脚(8和16)。+Vmotor(8)针为电机提供电力，+V(16)针作为芯片的逻辑针脚。我们将把第16针接到树莓派上然后把第8针接到电池盒上。

#### 硬件部分

为什么我们要在这个项目里使用L293D芯片？有两个原因。第一个原因是小派似乎还没有强大到能够直接驱动一个电机并且这样做可能会损坏树莓派。

第二个原因是，在这篇教程里，我们即要控制电机的转速，也要控制电机的转向。要达到这一点，需要反转电机的电流方向，而L239D恰好就是被设计用来达到这一目的的，我们可以通过两个电机控制针脚实现。

[![lesson9_12](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/f57834d23a_2797dd3d4a64c6fc84ce62dd11ebb9cc.png)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/f57834d23a_2797dd3d4a64c6fc84ce62dd11ebb9cc.png "Adafruit的树莓派教程第九课：控制一个直流电机")

一小块面包板的大小很适合这篇教程。

#### 软件部分

因为我们需要使用控制针脚(连接GPIO的第4针和第17针)，所以我们也需要用到GPIO库。更多细节请参考[第四课](http://www.geekfan.net/8972/ "Adafruit的树莓派教程第四课：GPIO配置")。

有很多种方法能把下面的展示的代码弄到你的树莓派里。最简单的方法可能是使用SSH连接到小派上(参见[第六课](http://www.geekfan.net/9128/ "Adafruit的树莓派教程第六课：使用SSH"))然后使用下面的命令打开一个编辑器：
    
    
    sudo nano motor.py

粘贴下面的代码，然后用Ctrl+X保存。

[![lesson9_13](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/9a2c3e9277_a11546da6e3eeab080d6cb3fb9b04d32.png)](https://blog.wo.ai/wp-content/plugins/wp-o-matic/cache/9a2c3e9277_a11546da6e3eeab080d6cb3fb9b04d32.png "Adafruit的树莓派教程第九课：控制一个直流电机")

代码在这：
    
    
    import RPi.GPIO as io
    io.setmode(io.BCM)
    
    in1_pin = 4
    in2_pin = 17
    
    io.setup(in1_pin, io.OUT)
    io.setup(in2_pin, io.OUT)
    
    def set(property, value):
        try:
            f = open("/sys/class/rpi-pwm/pwm0/" + property, 'w')
            f.write(value)
            f.close()	
        except:
            print("Error writing to: " + property + " value: " + value)
    
    set("delayed", "0")
    set("mode", "pwm")
    set("frequency", "500")
    set("active", "1")
    
    def clockwise():
        io.output(in1_pin, True)    
        io.output(in2_pin, False)
    
    def counter_clockwise():
        io.output(in1_pin, False)
        io.output(in2_pin, True)
    
    clockwise()
    
    while True:
        cmd = raw_input("Command, f/r 0..9, E.g. f5 :")
        direction = cmd[0]
        if direction == "f":
            clockwise()
        else: 
            counter_clockwise()
        speed = int(cmd[1]) * 11
        set("duty", str(speed))

这个Python程序首先把两个GPIO针设置为输出针。然后定义了一个与第八课里面一样的为了使用方便的方法(“set”)，用于写入PWM核心模块。后面我们将会用它设置PWM参数。

另外我们定义了两个方法，”clockwise”和”counter_clockwise”，它们通过控制输出针达到改变电机转向的目的。

如果两个输出针都置为高或者置为低，那么电机将会停止。如果一针为高一针为低那么电机将朝一个方向转动，如果两针的电平反转，那么电机的转向也将反转。程序循环等待用户输入一个字母(“f”或”r”)以及一个0到9之间的数字。字母设置了电机的转向数字设置了转速，数字将会乘以11然后变成一个0到99之间PWM库所期望的百分比值。

#### 测试&配置

要运行这个程序，你需要超级用户权限，所以使用下面的命令吧：
    
    
    sudo python motor.py

命令行将会提示你输入两个字符。试试下面的命令：
    
    
    $sudo python motor.py
    Command, f/r 0..9, E.g. f5 :f9
    Command, f/r 0..9, E.g. f5 :r4
    Command, f/r 0..9, E.g. f5 :

[Adafruit的树莓派教程第九课：控制一个直流电机](http://www.geekfan.net/9786/)，首发于[极客范 – GeekFan.net](http://www.geekfan.net)。
