I am trying to host a web server that returns the captured camera image, but the downloaded image shows weird artifacts.
The top half is normal, but the bottom half look like it is being overwritten or half written, with offset images and weird color banding.
I checked if PSRAM is insufficient, but there were plenty left.
Any help will be appreciated:)
The code is as following:
Code: Select all
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <esp_camera.h>
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"
const char *ssid = "";
const char *password = "";
AsyncWebServer server(80);
void initCamera() {
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_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.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
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 (config.pixel_format == PIXFORMAT_JPEG) {
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;
}
} else {
// Best option for face detection/recognition
config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
config.fb_count = 2;
#endif
}
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
ESP.restart();
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
initCamera();
server.on("/capture", HTTP_GET, [](AsyncWebServerRequest* request) {
Serial.printf("Free PSRAM: %d bytes\n", ESP.getFreePsram());
camera_fb_t* fb = esp_camera_fb_get(); // Capture a frame
if (!fb) {
Serial.println("Camera capture failed");
request->send(500, "text/plain", "Camera capture failed");
return;
}
AsyncWebServerResponse* response = request->beginResponse_P(200, "image/jpeg", fb->buf, fb->len);
response->addHeader("Content-Disposition", "inline; filename=capture.jpg");
request->send(response);
esp_camera_fb_return(fb);
});
server.begin();
}
void loop() {}