In this tutorial, you’ll learn how to publish images from an ESP32-CAM board to multiple browser clients using MQTT (Message Queuing Telemetry Transport). This setup will enable you to create a platform that functions similarly to a live video stream, viewable by an unlimited number of users.
Before diving in, make sure you have completed the following prerequisite tutorials:
By building on the knowledge gained from these foundational tutorials, you’ll be better equipped to follow along with this tutorial.
Publishing ESP32-CAM Images via MQTT
In the MQTT CAM code, our primary focus is publishing images without subscribing to other events. This publishing operation is managed by a timer event, which publishes images based on the intervals specified.
Setting Up the Timer
First, let’s create a timer object. This timer will trigger the
publishImage function at specific intervals.
timer = ba.timer(publishImage)
To interact with the ESP32 camera, initialize a camera object like so:
cam = esp32.cam(cfg)
cfg parameter represents a configuration table. Important: make sure it matches the settings for your particular ESP32-CAM module. See the Lua CAM API for details.
Handling MQTT Connection Status
For monitoring MQTT connections, use the following callback function:
local function onstatus(type, code, status) if "mqtt" == type and "connect" == code and 0 == status.reasoncode then timer:set(300, false, true) -- Activate timer every 300 milliseconds return true -- Accept connection end timer:cancel() return true -- Keep trying end
The above function starts the timer when a successful MQTT connection is made. If the connection drops, it cancels the timer but will keep attempting to reconnect.
Image Publishing via Timer Callback
The core of the image publishing mechanism is the timer callback function,
publishImage. This function captures an image using the camera object and publishes it via MQTT. The timer logic supports various timer types. Notably, this version operates as a Lua coroutine (akin to a thread). Within this coroutine, it continually loops and hibernates for the duration defined by the timer through
function publishImage() local busy = false while true do if mqtt:status() < 2 and not busy then busy = true -- thread busy ba.thread.run(function() local image = cam:read() mqtt:publish(topic, image) busy = false -- no longer running end) end coroutine.yield(true) -- sleep end end