硬件准备
需要以下硬件:
- 可以工作的树莓派一个
- 母对母1P杜邦线6根
- DC 5V4相28YBJ-48步进电机一个
- UL2003芯片步进电机驱动板一块
安装
按下图将步进电机接到驱动板上,也就是白色的接口
步进电机电源
步进电机需要5V电压驱动,而树莓派的GPIO接口中已有5V输出,将图中的Pin 2(最右上角那个)5V,接到驱动板的5V正极,Pin 6接到5V负级,电源部分则搞定。
步进电机驱动线路
驱动板上有IN1, IN2, IN3, IN4四个接口,根据资料得知这四个接口依次设置为低电平就可以驱动,我们分别用杜邦线将GPIO 17(Pin 11),GPIO 18(Pin 12), GPIO 21(Pin 13), GPIO 22(Pin 15)和IN1,IN2,IN3,IN4一一相连。 注意不同的GPIO驱动程序对端口的编号不一定一样(至少有三种叫法:Board,Broadcom,GPIO)
驱动原理:(每次将四个GPIO端口按下表依次设置好电平后,可以sleep几十毫秒来控制转速)
序列 | GPIO 17 | GPIO 18 | GPIO 21 | GPIO 22 |
---|---|---|---|---|
0 | LOW | HIGH | HIGH | HIGH |
1 | HIGH | LOW | HIGH | HIGH |
2 | HIGH | HIGH | LOW | HIGH |
3 | HIGH | HIGH | HIGH | LOW |
4 | LOW | HIGH | HIGH | HIGH |
… |
安装摄像头
本来是希望用3D打印机来制作齿轮和支架来完成这部分工作的,但因为打印机还没到货,所以先用乐高积木来做了, 刚好乐高积木可以插在步进电机中轴上,而且很牢靠,还不用密封带了。
摄像头如下图用两根导线固定在乐高积木上:
然后用各种积木搭个底座把电机固定起来,并留两个洞口可以将驱动线和摄像头的USB线穿出,这样表面上比较整齐,USB线也不会因为牵扯影响转动。
驱动示例代码
这里使用的是Python GPIO库,注意这里的端口命名是按树莓派的Board叫法(Pin 11, 12, 13, 15)
root@raspberrypi2 ~/projects/step_motor # cat motor.py
import RPi.GPIO as GPIO
import time
import sys
from array import *
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
steps = int(sys.argv[1]);
clockwise = int(sys.argv[2]);
arr = [0,1,2,3];
if clockwise!=1:
arr = [3,2,1,0];
ports = [11,12,13,15]
for p in ports:
GPIO.setup(p,GPIO.OUT)
for x in range(0,steps):
for j in arr:
time.sleep(0.01)
for i in range(0,4):
if i == j:
GPIO.output(ports[i],True)
else:
GPIO.output(ports[i],False)
执行python motor.py 90 0
可以顺时针转动大约80度。
执行python motor.py 90 1
则可逆时针转动大约80度。
转动效果视频
连续转动拍摄代码实现
这次使用webiopi把控制程序转换成REST API,这样方便网页调用。
root@raspberrypi2 ~/projects/gpio_server # cat webiopi_custom.py
# Imports
import webiopi
import time
# Retrieve GPIO lib
GPIO = webiopi.GPIO
# -------------------------------------------------- #
# Macro definition part #
# -------------------------------------------------- #
# A custom macro which prints out the arg received and return OK
def myMacroWithArgs(arg1, arg2, arg3):
print("myMacroWithArgs(%s, %s, %s)" % (arg1, arg2, arg3))
return "OK"
# A custom macro without args which return nothing
def myMacroWithoutArgs():
print("myMacroWithoutArgs()")
# Example loop which toggle GPIO 7 each 5 seconds
def loop():
time.sleep(5)
def turnLed(port_str, ms):
port = int(port_str)
GPIO.setFunction(port,GPIO.OUT)
GPIO.output(port,GPIO.LOW)
time.sleep(float(ms)/1000)
GPIO.output(port,GPIO.HIGH)
def turnWebcam(steps_str, clockwise_str):
steps = int(steps_str);
clockwise = int(clockwise_str);
arr = [0,1,2,3];
if clockwise!=1:
arr = [3,2,1,0];
ports = [17,18,27,22]
for p in ports:
GPIO.setFunction(p,GPIO.OUT)
for x in range(0,steps):
for j in arr:
time.sleep(0.01)
for i in range(0,4):
if i == j:
GPIO.output(ports[i],GPIO.LOW)
else:
GPIO.output(ports[i],GPIO.HIGH)
# -------------------------------------------------- #
# Initialization part #
# -------------------------------------------------- #
# Setup GPIOs
# -------------------------------------------------- #
# Main server part #
# -------------------------------------------------- #
# Instantiate the server on the port 8000, it starts immediately in its own thread
server = webiopi.Server(port=8001, login="pi", password="pi")
# or webiopi.Server(port=8000, passwdfile="/etc/webiopi/passwd")
# Register the macros so you can call it with Javascript and/or REST API
server.addMacro(turnWebcam)
server.addMacro(turnLed)
# -------------------------------------------------- #
# Loop execution part #
# -------------------------------------------------- #
# Run our loop until CTRL-C is pressed or SIGTERM received
webiopi.runLoop()
# If no specific loop is needed and defined above, just use
# webiopi.runLoop()
# here instead
# -------------------------------------------------- #
# Termination part #
# -------------------------------------------------- #
# Cleanly stop the server
server.stop()
执行python webiopi_custom.py
后启动GPIO REST API服务器
转动命令是:curl --data "" "http://pi:pi@raspberrypi2:8001/macros/turnWebcam/90,0
拍照命令是:/usr/bin/fswebcam -v -r 640x480 --no-banner /var/www/fswebcam/foo.jpg
于是我们可以用以下方法来实现连续拍摄:
- 执行拍照命令, 生成right.jpg
- 顺时转80度
- 执行拍照命令, 生成middle.jpg
- 顺时转80度
- 执行拍照命令, 生成left.jpg
- 逆时针转160度归位
将命令通过网页执行后,就可以在外面看房间里的情况了,今天出去外面采草莓在iPhone上试了一下,结果符合预期。
拍摄图片效果
在手机上看到的页面:点Reload会重新连拍三张
总共花了不到2小时就可以搞定这个了,还是非常好玩的~ 后面还可以用OpenCV库来合成照片到真正的全景图