玩具横道升降杆
娃对车库出入口的横道升降杆非常感兴趣,每天都会在小区车库出入口驻足观看1-2小时,甚至在家会用他的玩具拖把当做升降杆抬高高。因此萌生做个玩具横道升降杆让他在家玩儿。
说到做到马上开始查找资料,起初想通过光电接近开关+步进电机+PLC解决。发现这套系统太大且需要外接供电。无意中发现舵机可以直接实现0-90度的转动,且可以使用Arduino来控制,着实方便不少。搜索发现还有更便宜的ESP32也能实现相应的功能,同样可以采用Arduino来编程。探头就用HC-SR04超声波测距模块,外壳就利用淘汰的小米路由器2硬盘版,完美!~
设备清单
名称 | 参数 | 备注 |
---|---|---|
安信可ESP32模块 | MicroUSB供电电压5V,22个IO口 | 有CP2102和CH340串口转USB模块,听说CP2102更方便使用就买它 |
MG995舵机 | 180度,3-7.2V,重量:55g,扭矩:13kg/cm | 扭矩过剩,SG90舵机已经够用了 |
HC-SR04 超声波测距模块 | 电压5V,探测距离:2cm-600cm,精度:0.1cm±1% | 很便宜 |
5号充电电池 | 电压1.2V | 用4节电池应该一次充电可以撑很久 |
安信可ESP32模块
ESP模块手册请参见:Nodemcu-32s 开发板
MG995舵机
舵机的工作原理可以参考:秒懂舵机角度控制原理
简单来说舵机有三根线:电源线(+5V,红色),地线(GND黑色)和PWM控制线(黄色或白色)。
当我们给PWM一个特定的脉冲宽度时,舵机就会旋转到相应的角度,其有如下对应关系:
脉冲宽度 | 角度 |
---|---|
0.5ms | 0° |
1ms | 45° |
1.5ms | 90° |
2ms | 135° |
2.5ms | 180° |
HC-SR04 超声波测距模块
工作原理:
(1)采用IO触发测距10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.
测试距离=(高电平时间*声速(340M/S))/2;
接线
接线如下图所示,额外加了个LED灯,需串联几百欧的电阻。
自己先在面包板上做测试,折腾了半天发现没反应,各种排查,万用表测量,发现买的面包板连接线内部断线,还是在淘宝找了家大店铺买的,这不是坑人么。
程序
因官方原生Arduino编辑器下载ESP32库文件很慢或失连,因此采用VSCode+PlatFormIO IDE编写Arduino,参考链接:ESP32使用与环境配置介绍
Arduino程序相对比较简单易懂,第一次用,依瓢画葫芦程序参考:
ESP32驱动SG90舵机
Arduino 驱动 HC-SR04 超声波测距模块
成品图
舵机用自攻螺丝固定,探头和电池盒等用热熔胶固定。
代码如下
#include <Arduino.h>
int trigPin = 4; //Trig
int echoPin = 18; //Echo
long duration, cm, inches;
int freq = 50; // 频率(20ms周期)
int channel = 8; // 通道(高速通道(0 ~ 7)由80MHz时钟驱动,低速通道(8 ~ 15)由 1MHz 时钟驱动。)
int resolution = 8; // 分辨率,单位是bit,8表示有256种选择,即0~255,0为代表高电平的持续时间占比是0,255为1,是ledcWrite()函数调用时的范围
const int led = 32; //舵机输出的IO点位
//0-180度
//20ms周期,高电平0.5-2.5ms,对应0-180度角度
double deadZone = 6.4; //对应0.5ms(0.5ms/(20ms/256)),就是舵机0度位置。
double top = 19.2; //对应1.5ms(1.5/20*256=32),就是舵机90度位置。
double deadZone1 = 32; //对应2.5ms(2.5/20*256=32),就是舵机180度位置。
void setup()
{
//Serial Port begin
Serial.begin (9600);
//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
ledcSetup(channel, freq, resolution); // 设置通道,频率,分辨率
ledcAttachPin(led, channel); // 将通道与对应的引脚连接
pinMode(19, OUTPUT); //定义LED灯输出点位
}
void loop()
{
// The sensor is triggered by a HIGH pulse of 10 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the signal from the sensor: a HIGH pulse whose
// duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
duration = pulseIn(echoPin, HIGH);
// convert the time into a distance
cm = (duration/2) / 29.1;
inches = (duration/2) / 74;
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
if ( cm <18 )
{
ledcWrite(channel, deadZone); // 输出PWM
digitalWrite(19, HIGH);
}
else
{
delay(1000);
ledcWrite(channel, top);
digitalWrite(19, LOW);
}
delay(1000);
}
[...]ESP32模块见前述文章:玩具横道升降杆[...]