-
Notifications
You must be signed in to change notification settings - Fork 28
Description
I'm trying to stream my m5 x timer camera to record live video stream when it is unplugged from the computer so it relies on its battery but it doesn't seen to be working, any suggestions?
#include "M5TimerCAM.h"
#include <WiFi.h>
// WiFi credentials
const char* ssid =
const char* password =
WiFiServer server(80);
static void jpegStream(WiFiClient* client);
void setup() {
Serial.begin(115200);
TimerCAM.begin();
// Initialize the battery management system
TimerCAM.Power.begin();
if (!TimerCAM.Camera.begin()) {
Serial.println("Camera Init Fail");
while (true); // Halt if camera initialization fails
}
Serial.println("Camera Init Success");
TimerCAM.Camera.sensor->set_pixformat(TimerCAM.Camera.sensor, PIXFORMAT_JPEG);
TimerCAM.Camera.sensor->set_framesize(TimerCAM.Camera.sensor, FRAMESIZE_QVGA); // Lower resolution for power saving
TimerCAM.Camera.sensor->set_vflip(TimerCAM.Camera.sensor, 1);
TimerCAM.Camera.sensor->set_hmirror(TimerCAM.Camera.sensor, 0);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
WiFi.setSleep(false); // Ensure WiFi does not go to sleep
Serial.println("");
Serial.print("Connecting to ");
Serial.println(ssid);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a client connects
while (client.connected()) { // Loop while the client is connected
if (client.available()) { // If there are bytes to read from the client
jpegStream(&client);
}
}
// Close the connection
client.stop();
Serial.println("Client Disconnected.");
}
// Added delay to prevent the loop from running too fast and potentially causing issues
delay(10);
}
// Used for image streaming
#define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
static void jpegStream(WiFiClient* client) {
Serial.println("Image stream start");
client->println("HTTP/1.1 200 OK");
client->printf("Content-Type: %s\r\n", _STREAM_CONTENT_TYPE);
client->println("Content-Disposition: inline; filename=capture.jpg");
client->println("Access-Control-Allow-Origin: *");
client->println();
static int64_t last_frame = 0;
if (!last_frame) {
last_frame = esp_timer_get_time();
}
for (;;) {
if (TimerCAM.Camera.get()) {
TimerCAM.Power.setLed(255);
Serial.printf("pic size: %d\n", TimerCAM.Camera.fb->len);
client->print(_STREAM_BOUNDARY);
client->printf(_STREAM_PART, TimerCAM.Camera.fb->len);
int32_t to_sends = TimerCAM.Camera.fb->len;
int32_t now_sends = 0;
uint8_t* out_buf = TimerCAM.Camera.fb->buf;
uint32_t packet_len = 4 * 1024; // Reduce packet size to 4KB
while (to_sends > 0) {
now_sends = to_sends > packet_len ? packet_len : to_sends;
if (client->write(out_buf, now_sends) == 0) {
Serial.println("Client disconnected during stream.");
goto client_exit;
}
out_buf += now_sends;
to_sends -= now_sends; // Fix decrement error
}
int64_t fr_end = esp_timer_get_time();
int64_t frame_time = fr_end - last_frame;
last_frame = fr_end;
frame_time /= 1000;
Serial.printf("MJPG: %luKB %lums (%.1ffps)\r\n",
(long unsigned int)(TimerCAM.Camera.fb->len / 1024),
(long unsigned int)frame_time,
1000.0 / (long unsigned int)frame_time);
TimerCAM.Camera.free();
TimerCAM.Power.setLed(0);
} else {
// Log if the camera frame fetch fails
Serial.println("Failed to get frame from the camera.");
}
}
client_exit:
TimerCAM.Camera.free();
TimerCAM.Power.setLed(0);
client->stop();
Serial.printf("Image stream end\r\n");
}