ESP32 cam and tft producing vertical stripes

I am trying to stream video from an ESP32-wrover cam dev board to a round tft 240x240 board. I can get the web stream example to work ok and tft_espi graphics examples to work, but am have trouble getting the camera to stream to the tft. The camera and tft initialize ok and the loading... text on the screen works, but then there are only vertical strips. It seems the camera is only buffering part of the image - (see serial print below). Any ideas to fix my problem?
I am using ESP board manager 2.0.17

#include "esp_camera.h"
#include <Arduino.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>



// Camera pin definitions
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM     21
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       19
#define Y4_GPIO_NUM       18
#define Y3_GPIO_NUM        5
#define Y2_GPIO_NUM        4
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library
TFT_eSprite spr = TFT_eSprite(&tft);

camera_config_t config;






void setup() {
    Serial.begin(115200);
    Serial.setDebugOutput(true);



       // Initialize the TFT screen
    tft.init();
    tft.setRotation(0);
      tft.fillScreen(TFT_NAVY);
    delay(200);
    tft.fillScreen(TFT_BLACK);
    delay(100);

    // Initialize the camera
    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_240X240;
    config.pixel_format = PIXFORMAT_RGB565;

    config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
    config.fb_location = CAMERA_FB_IN_PSRAM;
    config.jpeg_quality = 16;
    config.fb_count = 1;

    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK) {
        Serial.printf("Camera init failed with error 0x%x\n", err);
        return;
    }

    Serial.println("Camera initialized successfully");
delay(100);

    // Create a sprite
    if (spr.createSprite(240, 240) == nullptr) {
        Serial.println("Failed to create sprite buffer. Not enough memory.");
        return;
    }

    Serial.println("Sprite initialized successfully");

    delay(1000);

   tft.setTextColor(TFT_WHITE);
    tft.drawString("Loading...", 105, 105, 2);
    delay(2000);

}

void loop() {
    Serial.println("Loop start");

    // Take a picture
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
        Serial.println("Camera capture failed");
        return;
    }

    Serial.println("Camera capture successful");

    // Process the image data here
        uint16_t *spritePtr = (uint16_t *)spr.getPointer();
    

      // Render the image to the sprite
    for (size_t i = 0; i < 240 * 240; i++) {
              spritePtr[i] = fb->buf[i * 2 + 1] << 8 | fb->buf[i * 2];


    } 

    // Debug: Print first few pixels to verify data
    for (size_t i = 0; i < 30; i++) {
        Serial.printf("Pixel %d: 0x%04x\n", i, spritePtr[i]);
    }

    spr.pushSprite(0, 0);

    // Return the frame buffer back to the driver for reuse
    esp_camera_fb_return(fb);

   

    Serial.println("Loop end");
    //delay(1000);
}

Serial print

Camera initialized successfully
Sprite initialized successfully
Loop start
Camera capture successful
Pixel 0: 0x0000
Pixel 1: 0x0000
Pixel 2: 0x0000
Pixel 3: 0x0000
Pixel 4: 0x0800
Pixel 5: 0x8c88
Pixel 6: 0xffee
Pixel 7: 0xffff
Pixel 8: 0x0000
Pixel 9: 0x0000
Pixel 10: 0x0000
Pixel 11: 0x0000
Pixel 12: 0x0000
Pixel 13: 0x0000
Pixel 14: 0x0000
Pixel 15: 0x0000
Pixel 16: 0x0000
Pixel 17: 0x0000
Pixel 18: 0x0000
Pixel 19: 0x0800
Pixel 20: 0xcc88
Pixel 21: 0xffee
Pixel 22: 0xffff
Pixel 23: 0xffff
Pixel 24: 0x0000
Pixel 25: 0x0000
Pixel 26: 0x0000
Pixel 27: 0x0000
Pixel 28: 0x0000
Pixel 29: 0x0000

I am using this dev board

and this tft display

What is the purpose of the sprite code?

the sprite contains the image.

If I reduce the frame size down to 96 x96 my code works correctly, But I should have enough memory for 240x240

Since you have access to the raw image data, try sending the data directly to the display.
The problem sounds like boundary violation of some internal buffer in the sprite library code.

It appears the I’m not allocating the psram heap correctly and the sketch is ignoring it.
I believe I need to use ps_malloc/ malloc to address this.

Heap free: 4464927
PSRAM free: 4192123
Heap largest free block: 4128756
Heap total free space: 4464927
Heap total allocated space: 34328

you might want to take a look into this

Thanks - I am looking into it- That post is 6 years old, so I would suspect that particular issue has been resolved. I have worked out how to allocate more heaped space using ps_malloc, but the esp arduino core library doesnt seem to use psram properly in the camera drivers and it appears to be something that espiff have changed at some stage as alot of examples from 2 + years ago are now broken. E (943) cam_hal: cam_dma_config(301): frame buffer malloc failed
E (943) cam_hal: cam_config(385): cam_dma_config failed
E (943) camera: Camera config failed with error 0xffffffff

Hi im also doing this project using ov7725. The thought I have right now is that the initiation of gca901 affects the correct camera capture. You can try without begin the tft and get buffer output, it will show the correct image data. Unfortunately I still dont have solution now. still trying

I have another code which works with ov2640. But since according to datasheet the ov7725 is like 4 times more sensitive in low light than ov2640, so I want to do the same thing using ov7725. Also the same as you, I got striped image using ov7725 and tft, and always get 0..0AFFF for the first 10 pixels.. I found the tft initiation might be a issue because I tried the camerawebserver and output the frame buffer data, it is differernt from the one when I use the ov7725 with tft. Using the Camerawebserver code I can get correct buffer data.

I made it work, now im happy.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.