Last active
January 26, 2024 17:15
-
-
Save diramazioni/723cca91e0ce780c13f0690a207d46a0 to your computer and use it in GitHub Desktop.
esp32 send image with websocket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "esp_camera.h" | |
#include <WiFi.h> | |
#include <ArduinoWebsockets.h> | |
// #include <algorithm> | |
// #include "soc/soc.h" //disable brownout problems | |
// #include "soc/rtc_cntl_reg.h" //disable brownout problems | |
#define CAMERA_MODEL_ESP32S3_EYE | |
#include "camera_pins.h" | |
#define LED_BUILT_IN 2 | |
using namespace websockets; | |
WebsocketsClient client; | |
const char* ssid_Router = "xxxxxxxxxx"; | |
const char* password_Router = "xxxxxxxxxxxxxx"; | |
const char* ws_server_address = "wss://greenlab.unibo.it:443/ws"; | |
String deviceString = "eli"; | |
String endOfStreamMessage = "END_OF_STREAM-" + deviceString; | |
/* | |
To get the SSL certificate run: | |
openssl s_client -showcerts -connect socketsbay.com:443 | |
See https://github.com/gilmaimon/ArduinoWebsockets/issues/101 for details. | |
*/ | |
const char ssl_cert[] = \ | |
"-----BEGIN CERTIFICATE-----\n"\ | |
"MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/\n"\ | |
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"\ | |
"DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow\n"\ | |
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n"\ | |
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB\n"\ | |
"AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC\n"\ | |
"ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL\n"\ | |
"wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D\n"\ | |
"LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK\n"\ | |
"4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5\n"\ | |
"bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y\n"\ | |
"sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ\n"\ | |
"Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4\n"\ | |
"FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc\n"\ | |
"SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql\n"\ | |
"PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND\n"\ | |
"TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n"\ | |
"SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1\n"\ | |
"c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx\n"\ | |
"+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB\n"\ | |
"ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu\n"\ | |
"b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E\n"\ | |
"U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu\n"\ | |
"MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC\n"\ | |
"5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW\n"\ | |
"9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG\n"\ | |
"WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O\n"\ | |
"he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC\n"\ | |
"Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5\n"\ | |
"-----END CERTIFICATE-----\n"; | |
extern TaskHandle_t loopTaskHandle; | |
void setup() { | |
Serial.begin(115200); | |
Serial.setDebugOutput(true); | |
Serial.println(); | |
pinMode(LED_BUILT_IN, OUTPUT); | |
cameraSetup(); | |
init_wifi(); | |
init_ws(); | |
//disableCore0WDT(); | |
// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); | |
xTaskCreateUniversal(loopTask_Cmd, "loopTask_Cmd", 8192, NULL, 1, &loopTaskHandle, 0); //loopTask_Cmd uses core 0. | |
//xTaskCreateUniversal(loopTask_Blink, "loopTask_Blink", 8192, NULL, 1, &loopTaskHandle, 0);//loopTask_Blink uses core 0. | |
} | |
//task loop uses core 1. | |
void loop() { | |
client.poll(); | |
delay(1000); | |
} | |
void loopTask_Cmd(void *pvParameters) { | |
Serial.println("Task send image with websocket starting ... "); | |
while (1) { | |
if (client.available()) { | |
camera_fb_t * fb = NULL; | |
// camera_fb_t *fb = esp_camera_fb_get(); | |
fb = esp_camera_fb_get(); | |
if (fb != NULL) { | |
// Send binary frame header | |
// uint8_t header[4]; | |
// header[0] = 0b10000000 | 0b00000010; // FIN + Binary Opcode | |
// header[1] = fb->len < 126 ? fb->len : 126; // Payload length (7 bits) | |
// header[2] = fb->len >= 126 ? (fb->len >> 8) & 0xFF : 0; // Extended payload length (16 bits) | |
// header[3] = fb->len >= 126 ? fb->len & 0xFF : 0; // Extended payload length (16 bits) | |
// // Send frame header | |
// client.sendBinary((const char*)header, sizeof(header)); | |
// Send binary data in chunks | |
for (size_t i = 0; i < fb->len; i += 1024) { | |
size_t chunkSize = std::min(static_cast<size_t>(1024), static_cast<size_t>(fb->len - i)); | |
client.sendBinary((const char*)(fb->buf + i), chunkSize); | |
} | |
// Signal the end of the stream as bytes | |
//client.sendBinary("END_OF_STREAM", 13); | |
// Send the combined message as text | |
client.send(endOfStreamMessage); | |
esp_camera_fb_return(fb); | |
Serial.println("MJPG sent"); | |
delay(5000); | |
} else { | |
Serial.println("Camera capture failed"); | |
esp_camera_fb_return(fb); | |
ESP.restart(); | |
} | |
} else { | |
Serial.println("WS client not available"); | |
ESP.restart(); | |
} | |
client.poll(); | |
delay(1000); | |
} | |
} | |
void loopTask_Blink(void *pvParameters) { | |
Serial.println("Task Blink is starting ... "); | |
while (1) { | |
digitalWrite(LED_BUILT_IN, !digitalRead(LED_BUILT_IN)); | |
delay(1000); | |
} | |
} | |
void init_wifi() { | |
WiFi.begin(ssid_Router, password_Router); | |
Serial.print("Connecting "); | |
Serial.print(ssid_Router); | |
while (WiFi.isConnected() != true) { | |
delay(500); | |
Serial.print("."); | |
//WiFi.begin(ssid_Router, password_Router); | |
} | |
Serial.println(""); | |
Serial.println("WiFi connected"); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
void init_ws() { | |
client.setCACert(ssl_cert); | |
Serial.println("WebSocket: Connecting "); | |
bool connected = client.connect(ws_server_address); | |
if (connected) { | |
Serial.println("WebSocket connected"); | |
} else { | |
Serial.println("WebSocket connection failed."); | |
} | |
client.onMessage([&](WebsocketsMessage message) { | |
Serial.print("Got Message: "); | |
Serial.println(message.data()); | |
}); | |
} | |
void cameraSetup() { | |
camera_config_t config; | |
config.ledc_channel = LEDC_CHANNEL_0; | |
config.ledc_timer = LEDC_TIMER_0; | |
config.pin_d0 = Y2_GPIO_NUM; | |
config.pin_d1 = Y3_GPIO_NUM; | |
config.pin_d2 = Y4_GPIO_NUM; | |
config.pin_d3 = Y5_GPIO_NUM; | |
config.pin_d4 = Y6_GPIO_NUM; | |
config.pin_d5 = Y7_GPIO_NUM; | |
config.pin_d6 = Y8_GPIO_NUM; | |
config.pin_d7 = Y9_GPIO_NUM; | |
config.pin_xclk = XCLK_GPIO_NUM; | |
config.pin_pclk = PCLK_GPIO_NUM; | |
config.pin_vsync = VSYNC_GPIO_NUM; | |
config.pin_href = HREF_GPIO_NUM; | |
config.pin_sscb_sda = SIOD_GPIO_NUM; | |
config.pin_sscb_scl = SIOC_GPIO_NUM; | |
config.pin_pwdn = PWDN_GPIO_NUM; | |
config.pin_reset = RESET_GPIO_NUM; | |
config.xclk_freq_hz = 20000000; | |
config.frame_size = FRAMESIZE_UXGA; | |
config.pixel_format = PIXFORMAT_JPEG; // for streaming | |
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; | |
config.fb_location = CAMERA_FB_IN_PSRAM; | |
config.jpeg_quality = 12; | |
config.fb_count = 1; | |
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality | |
// for larger pre-allocated frame buffer. | |
if(psramFound()){ | |
config.jpeg_quality = 10; | |
config.fb_count = 2; | |
config.grab_mode = CAMERA_GRAB_LATEST; | |
} else { | |
// Limit the frame size when PSRAM is not available | |
config.frame_size = FRAMESIZE_SVGA; | |
config.fb_location = CAMERA_FB_IN_DRAM; | |
} | |
// camera init | |
esp_err_t err = esp_camera_init(&config); | |
if (err != ESP_OK) { | |
Serial.printf("Camera init failed with error 0x%x", err); | |
return; | |
} | |
sensor_t * s = esp_camera_sensor_get(); | |
// initial sensors are flipped vertically and colors are a bit saturated | |
s->set_vflip(s, 1); // flip it back | |
s->set_brightness(s, 1); // up the brightness just a bit | |
s->set_saturation(s, 0); // lower the saturation | |
Serial.println("Camera configuration complete!"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment