这几天我用树莓派实现了一个模仿车库遥控门的设备,分享给大家。(优酷视频 http://v.youku.com/v_show/id_XMTU3ODk1NDY2OA==.html )
一、遥控模块
首先介绍一下我用的遥控器和接收板,这种遥控模块在中国随处可以买到,基本都是长这样的。很多卷帘门、车库门都是用这种遥控模块的。做无线电实验购买的是非锁的版本,注意最好同时购买天线。天线用的是50欧姆单芯导线,其实就是个铜丝,注意购买时候要看好频率,中国大陆的无线电许可频率是315MHz,国外也有用443MHz的,我买的遥控器是315MHz。注意遥控器发射频率和接收频率要匹配就行。遥控接收端芯片是PT2272-M4,M4的意思是点动模式,即按住遥控器按钮输出高电平,松开停止输出。遥控板的ANT端焊接天线,方向要是竖直向上的(相对你的设备)。
遥控板的接口有7个:
接口 |
含义 |
GND |
电源负极 |
5V |
5V电源输入 |
D0 |
对应遥控器按钮 |
D1 |
对应遥控器按钮 |
D2 |
对应遥控器按钮 |
D3 |
对应遥控器按钮 |
VT |
有效信号输出 |
其中,D0-D3对应遥控器上的A,B,C,D四个按钮。至于哪个是哪个,每个型号的模块不太一样,需要自己做试验。VT会在D0-D3中任何一个有信号的情况下输出高电平。也就是按下遥控器上的任意按钮,VT都会输出。
要格外注意的是,D0-D3,以及VT输出的电压都是5V。然而树莓派的GPIO端口接收电压是3.3V,所以要根据电压分配定律用2个电阻分压到3.3V。
电压分配定律是指在串联电路中,各负载分到的电压与其阻抗成正比关系。依此原理所实作的电路又被称为分压器。
在只有两个阻抗的串联电路中,电压分配定律公式如下:
所以,我采用一个4.7K和一个10K电阻,代入公式:
Vout = 5 x (10000 / (4700 + 10000))
约等于3.4v,是树莓派可以接受的。
二、步进电机
我用的步进电机驱动板是ULN2003的,步进电机型号是28BYJ-48,之前在博客上已经写过一篇ULN2003驱动步进电机的文章了,可以点击此处阅读。所以这里就不再叙述如何使用了。
三、物理连接
简要概括,ULN2003遥控板的IN1-4对应GPIO端口5,6,13,19。遥控板的VT对应GPIO04。树莓派上的2个5V输出分别给遥控板和步进电机供电。连接如下图:
步进电机需要自己做个支架,我用的是M3口径的电钻,在雪糕棒上打孔做的。
四、爆代码
首先,要用到一个这篇文章里的Uln2003驱动类,把它引入工程。
定义一个枚举类型,表示门的开关状态,还要定义一个bool类型表示电机是否正在操作中。
public bool IsBusy { get; set; } private DoorStatus Status { get; set; } enum DoorStatus { Open, Closed }
定义GPIO控制器、ULN2003步进电机驱动、遥控器VT端GPIO端口等
public GpioController Controller { get; set; } public GpioPin PinVT { get; set; } public Uln2003Driver Uln2003Driver { get; set; } public CancellationTokenSource Cts { get; private set; }
定义开门、关门的方法:
private async Task OpenDoorAsync() { Cts = new CancellationTokenSource(); await LogMessageAsync("Opening Door..."); await Uln2003Driver.TurnAsync(90, TurnDirection.Left, Cts.Token); Status = DoorStatus.Open; await LogMessageAsync("Door is Open."); } private async Task CloseDoorAsync() { Cts = new CancellationTokenSource(); await LogMessageAsync("Closing Door..."); await Uln2003Driver.TurnAsync(90, TurnDirection.Right, Cts.Token); Status = DoorStatus.Closed; await LogMessageAsync("Door is Closed."); }
主要逻辑:
Controller = GpioController.GetDefault(); if (null != Controller) { TxtMessage.Text += "[OK] GPIO Controller Initialized." + Environment.NewLine; Uln2003Driver = new Uln2003Driver(Controller, 5, 6, 13, 19); TxtMessage.Text += "[OK] Uln2003Driver Initialized on 5,6,13,19." + Environment.NewLine; Status = DoorStatus.Closed; PinVT = Controller.OpenPin(4); PinVT.SetDriveMode(GpioPinDriveMode.Input); TxtMessage.Text += "[OK] VT Initialized on GPIO 04." + Environment.NewLine; PinVT.ValueChanged += async (sender, args) => { if (!IsBusy && PinVT.Read() == GpioPinValue.High && Status != DoorStatus.Open) { IsBusy = true; await LogMessageAsync("Remote Signal Received on VT."); await OpenDoorAsync(); await Task.Delay(2000); await CloseDoorAsync(); IsBusy = false; } }; }
完整工程在我的GitHub上:https://github.com/EdiWang/Windows-IoT-Projects/tree/master/Edi.RPi.RemoteDoorControl
五、运行
按下遥控器任意按键,雪糕棒勃起。2秒后自动降下。
你好,请问你的树莓派是从哪里买的,可以给个店铺链接吗?想跟着你的博客学习一下