I am working on a robot using video stream.
My components:
- ESP32-DevKitC-32E V4 (ESP32-WROOM-32E)
- Camera module ArduCam OV2640, 2 MPx, 20 pins
I have a problem with video image. On the picture are black blinking pixels.
Screanshot:
Connection diagram:
Code:
- #include "esp_camera.h"
- #include <Arduino.h>
- #include <WiFi.h>
- #include <AsyncTCP.h>
- #include <ESPAsyncWebServer.h>
- #include <iostream>
- #include <sstream>
- //Camera related constants
- #define PWDN_GPIO_NUM -1
- #define RESET_GPIO_NUM 17
- #define XCLK_GPIO_NUM 27
- #define SIOD_GPIO_NUM 21
- #define SIOC_GPIO_NUM 22
- #define Y9_GPIO_NUM 19
- #define Y8_GPIO_NUM 36
- #define Y7_GPIO_NUM 18
- #define Y6_GPIO_NUM 39
- #define Y5_GPIO_NUM 5
- #define Y4_GPIO_NUM 34
- #define Y3_GPIO_NUM 35
- #define Y2_GPIO_NUM 32
- #define VSYNC_GPIO_NUM 25
- #define HREF_GPIO_NUM 26
- #define PCLK_GPIO_NUM 23
- const char* ssid = "MyWiFiCar";
- const char* password = "12345678";
- AsyncWebServer server(80);
- AsyncWebSocket wsCamera("/Camera");
- uint32_t cameraClientId = 0;
- const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <style>
- </style>
- </head>
- <body align="center">
- <table id="mainTable" style="width:400px;margin:auto;table-layout:fixed" CELLSPACING=10>
- <tr>
- <img id="cameraImage" src="" style="width:400px;height:250px"></td>
- </tr>
- </table>
- <script>
- var webSocketCameraUrl = "ws:\/\/" + window.location.hostname + "/Camera";
- var websocketCamera;
- function initCameraWebSocket()
- {
- websocketCamera = new WebSocket(webSocketCameraUrl);
- websocketCamera.binaryType = 'blob';
- websocketCamera.onopen = function(event){};
- websocketCamera.onclose = function(event){setTimeout(initCameraWebSocket, 2000);};
- websocketCamera.onmessage = function(event)
- {
- var imageId = document.getElementById("cameraImage");
- imageId.src = URL.createObjectURL(event.data);
- };
- }
- function initWebSocket()
- {
- initCameraWebSocket ();
- }
- window.onload = initWebSocket;
- document.getElementById("mainTable").addEventListener("touchend", function(event){
- event.preventDefault()
- });
- </script>
- </body>
- </html>
- )HTMLHOMEPAGE";
- void handleRoot(AsyncWebServerRequest *request)
- {
- request->send_P(200, "text/html", htmlHomePage);
- }
- void handleNotFound(AsyncWebServerRequest *request)
- {
- request->send(404, "text/plain", "File Not Found");
- }
- void onCameraWebSocketEvent(AsyncWebSocket *server,
- AsyncWebSocketClient *client,
- AwsEventType type,
- void *arg,
- uint8_t *data,
- size_t len)
- {
- switch (type)
- {
- case WS_EVT_CONNECT:
- Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
- cameraClientId = client->id();
- break;
- case WS_EVT_DISCONNECT:
- Serial.printf("WebSocket client #%u disconnected\n", client->id());
- cameraClientId = 0;
- break;
- case WS_EVT_DATA:
- break;
- case WS_EVT_PONG:
- case WS_EVT_ERROR:
- break;
- default:
- break;
- }
- }
- void setupCamera()
- {
- 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.pixel_format = PIXFORMAT_JPEG;
- config.frame_size = FRAMESIZE_VGA;
- config.jpeg_quality = 12;
- config.fb_count = 1;
- 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;
- }
- if (psramFound())
- {
- heap_caps_malloc_extmem_enable(20000);
- Serial.printf("PSRAM initialized. malloc to take memory from Psram above this size");
- }
- }
- void sendCameraPicture()
- {
- if (cameraClientId == 0)
- {
- return;
- }
- unsigned long startTime1 = millis();
- //capture a frame
- camera_fb_t * fb = esp_camera_fb_get();
- if (!fb)
- {
- Serial.println("Frame buffer could not be acquired");
- return;
- }
- unsigned long startTime2 = millis();
- wsCamera.binary(cameraClientId, fb->buf, fb->len);
- esp_camera_fb_return(fb);
- //Wait for message to be delivered
- while (true)
- {
- AsyncWebSocketClient * clientPointer = wsCamera.client(cameraClientId);
- if (!clientPointer || !(clientPointer->queueIsFull()))
- {
- break;
- }
- delay(1);
- }
- unsigned long startTime3 = millis();
- //Serial.printf("Time taken Total: %d|%d|%d\n",startTime3 - startTime1, startTime2 - startTime1, startTime3-startTime2 );
- }
- void setup(void)
- {
- Serial.begin(115200);
- WiFi.softAP(ssid, password);
- IPAddress IP = WiFi.softAPIP();
- Serial.print("AP IP address: ");
- Serial.println(IP);
- server.on("/", HTTP_GET, handleRoot);
- server.onNotFound(handleNotFound);
- wsCamera.onEvent(onCameraWebSocketEvent);
- server.addHandler(&wsCamera);
- server.begin();
- Serial.println("HTTP server started");
- setupCamera();
- }
- void loop()
- {
- wsCamera.cleanupClients();
- sendCameraPicture();
- //Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
- }
Thanks for answer