单片机快速实现网络摄像机+PWM舵机+继电器+AD电压采集

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

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

一、本例程实现功能

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

1523effc4b15b1be5d5c9bae6f058c8b.jpeg

二、举一反三

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

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

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

    ab44470b96e83e0f1b4895d488940f93.jpeg

    四、CAM底板结构图

    f95f3399385219c16a57941b58f8e93c.jpeg

    五、材料清单

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

    (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地址:

    65be59e0a1430f51015c9ce83ddfc3fd.jpeg

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

    37141991d307e008982934ff47080bd7.jpeg

    f2372e25adc117192d0df94d71db3084.jpeg

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

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

  • 花生壳内网穿透。
  • 路由器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地址
    }

    作者:FlexLua

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机快速实现网络摄像机+PWM舵机+继电器+AD电压采集

    发表回复