网络摄像机+舵机+继电器+AD

网络摄像机+舵机+继电器+AD

基于 FlexLua 低代码单片机技术,脱离复杂单片机C语言开发正逐渐成为一种快速高效的 IoT 硬件开发方式。即使新手不懂单片机开发也可很快很容易用FlexLua零门槛开发各种 IoT 硬件,更多教程请参考 FlexLua 官网。

一、本例程实现功能

一、本例程实现功能

让开发板在局域网环境变成一台网络摄像机,不仅可以通过电脑或手机 Web 浏览器查看实时视频流,还可以控制舵机的旋转角度,继电器的开闭合,以及获取开发板上 AD 电压采集值并在网页上实时显示。需要注意的是电脑或手机也需要是在此局域网内。

打开网易新闻 查看精彩图片

二、举一反三

二、举一反三

基于本例程还可以很容易衍生出一些更实用的方案:

  1. 远程视频监控+远程继电器控制
  2. 远程视频监控+远程舵机控制
  3. 远程视频监控+远程传感器数据读取
  4. 远程视频监控+ IO 读取
三、CAM 底板硬件介绍

三、CAM 底板硬件介绍

  1. 供电:USB 5v 供电或 5v 引脚供电
  2. 可板载 ESP32-CAM 摄像头模块、SHT30 IIc 温湿度模块、以及 ShineBlink Mini 开发板
  3. 支持 8 路 IO 控制、4 路 AD 电压采集、1 路 Uar t串口通信、1 路 IIc 通信扩展

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

四、CAM底板结构图

四、CAM底板结构图

打开网易新闻 查看精彩图片

五、材料清单

五、材料清单

  1. 自制 Cam PCB 底板(开源资料请参考 《CAM 底板开源硬件资料》文件)
  2. ShineBlink Mini 开发板(自带AD电压采集功能)
  3. 舵机模块
  4. 继电器模块
六、完整代码

六、完整代码

(1)ShineBlink Mini 开发板 Lua 源代码如下:

HW =
{
"1103",--Wifi账号
"123321123",--Wifi密码
"FRAMESIZE_SVGA",--摄像头采集图片尺寸为SVGA,SVGA:800*600,尽量不要高于SVGA
"12"--摄像头采集图片的质量为12,必须为"1"~"63",其中"1"质量最高
}
IP =
{
"Dynamic",--表示动态IP模式,动态IP模式下,忽略下面5项,"Static"时需要配置下面5项
"0.0.0.0",--本机IP地址
"0.0.0.0",--gateway地址
"0.0.0.0",--subnet地址
"0.0.0.0",--首选DNS地址
"0.0.0.0"--次选DNS地址
}
SERVER =
{
"80",--本机视频流Web http Server端口号
"81"--本机视频流服务端口号
}
H1 = --Http server vedio stream response H1
{
"multipart/x-mixed-replace;boundary=123456789000000000987654321"
}
H2 = --Http server vedio stream response H2
{
"Content-Type: image/jpeg\r\nContent-Length: %d\r\n\r\n"
}
--注意:上面H2中的%d占位符一定不要去掉,它会自动计算每次发送的图片尺寸大小并填充进去。
H3 = "\r\n--123456789000000000987654321\r\n" --H3 stream boundary
--计时器变量
Timer10MsCnt=0
Timer10MsCnt1=0
AD0=0.0
--定义10毫秒定时器的回调函数,函数名字必须是LIB_10msTimerCallback
function LIB_10msTimerCallback()
Timer10MsCnt = Timer10MsCnt + 10
Timer10MsCnt1 = Timer10MsCnt1 + 10
end
--使能USB串口打印
LIB_UsbConfig("CDC")
--配置D8 Wifi Led指示灯(Core电路板上的LED1灯和D8端口是固定连接的)
LIB_GpioOutputConfig("D8","STANDARD")
--LED1上电以后没人初始状态为熄灭
LIB_GpioWrite("D8",1)
--配置D5 接口为输出,用于控制继电器开闭
LIB_GpioOutputConfig("D5","STANDARD")
--配置D0 口为PWM功能用于控制舵机,周期20ms,高电平有效
LIB_PwmConfig1(20000,1)
LIB_PwmUpdate1(500) --D0口输出的PWM高电平脉宽为0.5ms(即舵机位置默认为0度)
--配置A0-A3这四个通道同时开始工作,当每个通道采集满50个点时缓存满,每个点的采集时间间隔为10ms
LIB_ADConfig(50,10000) --本例程中只用到A0一个通道
--初始化,Vedio Web Server开始工作
Res,Info=LIB_EspCamOp("Config","WEB_VEDIO_ENHANCE","UART0",HW,IP,SERVER,H1,H2,H3)
if Res == 0 then
print(Info) --打印初始化失败原因
end
--使能系统10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
--开始大循环
while(GC(1) == true)
do
A0_full_flag, A0_tab = LIB_ADCheckBufFull("A0")
--每当A0通道的缓存满以后,计算缓存内的50个元素的平均值,并换算成电压值print输出
if A0_full_flag == 1 then
SUM = 0
for i = 1, #A0_tab do --此处#A0_tab的值是50,表示A0_tab表内的元素个数
SUM = SUM + A0_tab[i]
end
AVER = SUM / #A0_tab
--将A0通道的AD值转换成实际电压
AD0 = AVER*3.6/4096.0
print(string.format("A0=%.2fv\r\n", AD0))
end
--每200ms更新一次传感器值,这样Web客户端就能看到传感器值的变化,并且能及时收到客户端发来的命令
if Timer10MsCnt1 > 200 then
Timer10MsCnt1 = 0
Res,Info=LIB_EspCamOp("WebserverUpdate",string.format("{\"AD0\":\"%.2f\"}", AD0))
if Res == 1 then
if Info ~= "null" then --收到客户端发来的cmd命令
print(Info)
--网页端上的按钮按下后发来的Info字符串的形式如:"xxx=yyy"
if Info == "cmd=0" then
LIB_PwmUpdate1(500) --舵机输出0度
elseif Info == "cmd=45" then
LIB_PwmUpdate1(1000) --舵机输出45度
elseif Info == "cmd=90" then
LIB_PwmUpdate1(1500) --舵机输出90度
elseif Info == "cmd=135" then
LIB_PwmUpdate1(2000) --舵机输出135度
elseif Info == "cmd=on" then
LIB_GpioWrite("D5",0) --打开继电器
elseif Info == "cmd=off" then
LIB_GpioWrite("D5",1) --关闭继电器
else
end
end
end
end
--每三秒查询一次WIFI连接状态
if Timer10MsCnt > 3000 then
Timer10MsCnt = 0
Res,Info=LIB_EspCamOp("WifiStatus")
if Res == 1 then
WifiIsConnect = 1
print(Info) --打印IP
LIB_GpioWrite("D8",0)--WIFI连接时,开发板上的Led1灯亮
else
LIB_GpioWrite("D8",1)--WIFI未连接时,开发板上的Led1灯灭
print(Info) --打印WIFI未连接时的状态
end
end
end

如果感兴趣,上面代码中出现的LIB开头的库函数可以在 API文档 中通过Ctrl+F查询。

(2)除了需将以上代码下载到 ShineBlink Mini 开发板,还需要将 index.html 文件放入 ESP32-CAM 摄像头模块板子上的TF卡中。index.html中的代码没做过前端开发的同学可能会比较陌生,但并不难,花几分钟仔细看一下应该能看懂,看懂了稍微修改一下,即可很容易改出各种定制化的页面和项目。

index.html 文件放在{FlexLua开源网盘}->{Hardware}->{OTHERS}->{ESPCAM} 文件夹中。

七、代码运行结果

七、代码运行结果

代码运行之后,我们可以通过串口调试助手看到开发板被动态分配的IP地址:

打开网易新闻 查看精彩图片

然后在处于同一局域网内的电脑浏览器上输入这个192.168.43.224 IP地址即可访问视频和控制页面,在页面中不仅可以看到视频流,还可以控制舵机的旋转角度,继电器的开闭合,以及AD电压的实时采集值。

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

八、如何实现外网访问局域网内的摄像头+Webserver

八、如何实现外网访问局域网内的摄像头+Webserver

在上面的举一反三中已经提到如何通过外网访问内网:

  1. 花生壳内网穿透。
  2. 路由器WAN口带公网IP地址。

在此之前开发者还需要将开发板的IP地址由动态分配方式改成静态IP,实现方式很简单,只需改动Lua代码中的IP配置table列表中的内容即可,类似改动如下,请结合自己的局域网配置更改,下面的只是个参考例子:

IP =
{
"Static",
"192.168.43.55",--本机IP地址
"192.168.43.1",--gateway地址
"255.255.255.0",--subnet地址
"8.8.8.8",--首选DNS地址
"114.114.114.114"--次选DNS地址
}