网站首页 > 开源技术 正文
在本教程中,您将学习如何使用 MQTT(消息队列遥测传输)从 ESP32-CAM 板上发布图像到多个浏览器客户端。这个设置将使您能够创建一个类似于实时视频流的平台,可以被无限数量的用户查看。
先决条件
在深入学习之前,请确保您已完成以下先决条件教程:
- 您的第一个 Xedge32 项目:本教程涵盖了 ESP32 上运行 Xedge32 的基本设置和配置说明。
- 您的第一个 MQTT Lua 程序:本教程介绍了 MQTT 的基础知识以及如何编写一个简单的 Lua 程序来与 MQTT 进行交互。
通过在这些基础教程中获得的知识,您将更好地能够跟随本教程。
通过 MQTT 发布 ESP32-CAM 图像
在 MQTT CAM 代码中,我们的主要重点是发布图像而不订阅其他事件。这个发布操作由一个定时器事件管理,根据指定的间隔发布图像。
设置定时器
首先,让我们创建一个定时器对象。这个定时器将在特定间隔触发 publishImage 函数。
timer = ba.timer(publishImage)
要与 ESP32 相机进行交互,可以这样初始化一个相机对象:
cam = esp32.cam(cfg)
cfg 参数代表一个配置表。重要: 确保它与您特定的 ESP32-CAM 模块的设置匹配。有关详细信息,请参阅 Lua CAM API。
处理 MQTT 连接状态
要监视 MQTT 连接,使用以下回调函数:
local function onstatus(type, code, status)
if "mqtt" == type and "connect" == code and 0 == status.reasoncode then
timer:set(300, false, true) -- 每 300 毫秒激活定时器
return true -- 接受连接
end
timer:cancel()
return true -- 继续尝试
end
上述函数在成功建立 MQTT 连接时启动定时器。如果连接断开,它会取消定时器,但会继续尝试重新连接。
通过定时器回调发布图像
图像发布机制的核心是定时器回调函数 publishImage。这个函数使用相机对象捕获图像,并通过 MQTT 发布。定时器逻辑支持各种定时器类型。特别是,这个版本作为 Lua 协程(类似于线程)运行。在这个协程中,它不断循环并休眠,持续时间由 coroutine.yield(true) 定义。
function publishImage()
local busy = false
while true do
if mqtt:status() < 2 and not busy then
busy = true -- 线程忙碌
ba.thread.run(function()
local image = cam:read()
mqtt:publish(topic, image)
busy = false -- 不再运行
end)
end
coroutine.yield(true) -- 休眠
end
end
上述函数通过不在 MQTT 客户端的发送队列中填充两个图像来维护流程控制。cam:read 函数可能耗时,不是在人类时间上,而是在微控制器操作上。因此,我们将从 CAM 对象读取的任务转移到一个单独的线程。虽然这一步并不是严格必要的,但它增强了在从 CAM 读取的同时处理多个操作的应用程序的性能。要深入了解线程的复杂性,建议参考Barracuda App Server 关于线程的文档。
完整的 MQTT CAM 代码如下:
local topic = "/xedge32/espcam/USA/92629"
local broker = "broker.hivemq.com"
-- 'FREENOVE ESP32-S3 WROOM' CAM 板的设置
local cfg={
d0=11, d1=9, d2=8, d3=10, d4=12, d5=18, d6=17, d7=16,
xclk=15, pclk=13, vsync=6, href=7, sda=4, scl=5, pwdn=-1,
reset=-1, freq="20000000", frame="HD"
}
-- 打开相机
local cam,err=esp32.cam(cfg)
assert(cam, err) -- 如果 'cfg' 不正确,会抛出错误
local timer -- 定时器对象;在下面设置。
-- MQTT 连接/断开回调
local function onstatus(type,code,status)
-- 如果连接到代理成功
if "mqtt" == type and "connect" == code and 0 == status.reasoncode then
timer:set(300,false,true) -- 每 300 毫秒激活定时器
trace"Connected"
return true -- 接受连接
end
timer:cancel()
trace("Disconnect or connect failed",type,code)
return true -- 继续尝试
end
-- 创建 MQTT 客户端
local mqtt=require("mqttc").create(broker,onstatus)
-- 每 300 毫秒激活的定时器协程函数
function publishImage()
local busy=false
while true do
--trace(mqtt:status(), busy)
-- 流程控制:如果排队的 MQTT 消息少于 2 条
if mqtt:status() < 2 and not busy then
busy=true
ba.thread.run(function()
local image,err=cam:read()
if image then
mqtt:publish(topic,image)
else
trace("cam:read()",err)
end
busy=false
end)
end
coroutine.yield(true) -- 休眠
end
end
timer = ba.timer(publishImage)
虽然我们已经涵盖了程序的大部分功能,但还有一些方面尚未涉及:
- 主题和代理配置:local topic = "/xedge32/espcam/USA/92629":设置图像将被发布到的 MQTT 主题。将此主题更改为您的地址。local broker = "broker.hivemq.com":指定 MQTT 代理的地址。此示例中使用公共的 HiveMQ 代理。
- ESP32 相机配置(cfg): 这个块设置了 ESP32 CAM 板的特定引脚配置和设置。用适合您硬件的设置替换这些设置。
- 创建 MQTT 客户端: MQTT 客户端是通过 require("mqttc").create(broker, onstatus) 函数创建的,传入代理地址和 onstatus 回调。
- 为 publishImage 创建定时器对象: 通过调用 ba.timer 并传入 publishImage 回调来创建定时器,它将在固定间隔内激活。这是不断捕获和发布图像的机制。
使用 JavaScript 驱动的 HTML 客户端订阅 CAM 图像
要可视化由 ESP32 相机发布的图像,您可以使用一个 HTML 客户端。以下客户端将订阅相机发布图像的相同 MQTT 主题。该客户端纯粹在您的 Web 浏览器中运行,不需要任何服务器设置。
完整的 HTML 客户端代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cam Images Over MQTT</title>
<script data-fr-src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/5.0.0-beta.3/mqtt.min.js"></script>
<script>
const topic="/xedge32/espcam/USA/92629";
const broker="broker.hivemq.com";
window.addEventListener("load", (event) => {
let img = document.getElementById("image");
let msg = document.getElementById("msg");
let frameCounter=0;
const options = {
clean: true,
connectTimeout: 4000,
port: 8884 // 安全的 WebSocket 端口
};
const client = mqtt.connect("mqtts://"+broker+"/mqtt",options);
client.on('connect', function () {
msg.textContent="Connected; Waiting for images...";
client.subscribe(topic);
});
client.on("message", (topic, message) => {
const blob = new Blob([message], { type: 'image/jpeg' });
img.src = URL.createObjectURL(blob);
frameCounter++;
msg.textContent = `Frames: ${frameCounter}`;
});
});
</script>
</head>
<body>
<h2>Cam Images Over MQTT</h2>
<div id="image-container">
<img id="image"/>
</div>
<p id="msg">Connecting...</p>
</body>
</html>
MQTT JavaScript 客户端
在 HTML 文件的顶部,导入 MQTT JavaScript 库以启用 MQTT 功能。这在 <script data-fr-src=".......mqtt.min.js"></script> 行中找到。
页面布局
HTML 主体包含一个 id 为 "image-container" 的 <div> 元素,用于容纳传入的图像,以及一个 id 为 "msg" 的 <p> 元素,用作状态消息的占位符。
MQTT 配置
在 JavaScript 部分,定义了两个常量 topic 和 broker。这些必须与您的 mqttcam.xlua 文件中的主题和代理配置相对应。
连接到 MQTT 代理
客户端使用 mqtt.connect() 方法向指定的代理发起 MQTT 连接。它使用安全的 WebSocket 端口 8884 进行连接。
处理传入消息
在成功连接后,客户端订阅主题。预期在此主题上的任何传入消息都将是二进制 JPEG 图像。消息将被转换为 Blob,并显示为图像元素的源。
帧计数器
frameCounter 变量计算传入帧(或图像)的数量,并将此计数显示为图像下方的文本消息。
通过在 Web 浏览器中打开此 HTML 文件,您将能够实时可视化被发布到指定 MQTT 主题的图像。
准备代码
步骤 1:准备 Lua 脚本如下
- 如在教程您的第一个 Xedge32 项目中所述,当 Xedge32 驱动的 ESP32 运行时,使用浏览器导航到 Xedge IDE。
- 创建一个名为 "cam" 的新 Xedge 应用程序,并启用 LSP。
- 展开左侧面板树视图中可见的 cam 应用程序。
- 右键单击 cam 应用程序,然后在上下文菜单中单击 新建文件。
- 输入 camtest.lsp,然后点击 Enter。
- 打开 GitHub 上的 camtest.lsp 文件,然后单击 复制原始文件 按钮。
- 转到 Xedge IDE 浏览器窗口,将内容粘贴到 camtest.lsp 文件中。
- 重要: 调整 camtest.lsp 中的 cfg 设置,以匹配您特定的 ESP32 CAM 板设置。有关详细信息,请参阅 Lua CAM API。
- 点击保存,然后点击打开以测试您的相机设置。确保在继续之前看到 LSP 脚本生成的图像。
- 右键单击 cam 应用程序,然后在上下文菜单中单击 新建文件。
- 输入 mqttcam.xlua,然后点击 Enter。
- 打开 GitHub 上的 mqttcam.xlua 文件,然后单击 复制原始文件 按钮。
- 转到 Xedge IDE 浏览器窗口,将内容粘贴到 mqttcam.xlua 文件中。
- 使用 Xedge 编辑器,从 camtest.lsp 复制 cfg 设置,并将其替换为步骤 9 中测试的设置。
- 点击 保存并运行 按钮以保存并启动示例。
步骤 2:准备 HTML/JS 文件如下
- 下载 mqttcam.html,在任何编辑器中打开文件,并确保 HTML 文件中的主题与您在 Lua 脚本中设置的主题相匹配。
- 保存 mqttcam.html 文件。
- 打开 mqttcam.html:双击 mqttcam.html 文件,或将其拖放到浏览器中。注意:此文件设计为直接从文件系统打开。您不需要 Web 服务器来托管此文件。
- 观察输出:网页将显示由 ESP32 CAM 发布的图像。接收到的帧数将显示在图像下方。
SELECT * FROM potential_issues;
ESP32 CAM板的潜在问题及解决方案
ESP32 CAM板因其多功能性和价格实惠而广受认可。然而,它们并非没有挑战。用户在使用ESP32 CAM板时可能会面临的一个重要问题是摄像头读取操作与内置WiFi模块之间的干扰。让我们深入了解一下具体情况:
问题:干扰和WiFi信号衰减
当ESP32 CAM板在运行时,特别是在摄像头的读取操作期间,会产生噪音。这种噪音会干扰内置WiFi,导致:
- 信号范围减小: WiFi有效传输和接收数据的距离明显减少。
- 吞吐量降低: WiFi网络传输数据的速度和效率会受到相当大的影响。
解决方案
为了解决这些问题,请考虑以下解决方案:
- 使用带有外置天线的CAM板: 几种ESP32 CAM板配备了或支持使用外置天线。通过使用这样的板并连接外置天线,您可以增强WiFi信号强度和范围,减轻摄像头操作造成的一些干扰。
- 集成W5500以太网芯片: 如果您的应用需要稳定和强大的数据传输,请考虑集成W5500以太网芯片。通过使用以太网而不是WiFi,您可以有效地避开与ESP32 CAM板上的WiFi相关的干扰问题。Xedge32配备了集成的以太网驱动程序。当与支持它的硬件配对使用时,比如W5500芯片,它可以实现平稳且无干扰的数据传输,确保您的应用保持稳定和高效。
总之,虽然ESP32 CAM板是适用于多种应用的优秀工具,但了解其局限性并知道如何规避这些局限性以确保最佳性能是至关重要的。
参考资料
- Lua MQTT API
- Lua timer API
- Lua CAM API```
猜你喜欢
- 2024-09-14 unity3d开发教程-初始unity(unity3d游戏开发教程)
- 2024-09-14 lua程序在板块模型中的计算机仿真
- 2024-09-14 杨洋回应片酬和演技质疑:演戏是我一辈子的事情
- 2024-09-14 unity3d开发教程-开发环境搭建(unity3d 开发)
- 2024-09-14 c的包管理和构建工具xmake(c语言包管理器)
- 2024-09-14 Nginx内容缓存(nginx内存缓存)
- 2024-09-14 xmake从入门到精通1:安装和更新(xmake github)
- 2024-09-14 Lua 运算符(ll运算符)
- 2024-09-14 【LUA】只需花费你半天时间(我要花费半天的时间)
- 2024-09-14 在.NET Core 中收集数据的几种方式
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)