Esp32cam e tft st7735, imagem não centralizada

Eu estou com um projeto de fazer uma câmera com feedback ao vivo usando esp32cam e st7735s (80x160). mas a imagem esta cortada em 1/3.
o codigo nao é meu, mas queria saber se alguem pode me ajudar

#include "esp_camera.h"

// Select camera model
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER

#include "camera_pins.h"

//##########################################################################
#define USE_DMA
// Include the jpeg decoder library
#include <TJpg_Decoder.h>

#ifdef USE_DMA
  uint16_t  dmaBuffer1[16*16]; // Toggle buffer for 16*16 MCU block, 512bytes
  uint16_t  dmaBuffer2[16*16]; // Toggle buffer for 16*16 MCU block, 512bytes
  uint16_t* dmaBufferPtr = dmaBuffer1;
  bool dmaBufferSel = 0;
#endif

// Include the TFT library https://github.com/Bodmer/TFT_eSPI
#include "SPI.h"
#include <TFT_eSPI.h>              // Hardware-specific library
TFT_eSPI tft = TFT_eSPI();         // Invoke custom library

// This next function will be called during decoding of the jpeg file to render each
// 16x16 or 8x8 image tile (Minimum Coding Unit) to the TFT.
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
   // Stop further decoding as image is running off bottom of screen
  if ( y >= tft.height() ) return 0;

  // STM32F767 processor takes 43ms just to decode (and not draw) jpeg (-Os compile option)
  // Total time to decode and also draw to TFT:
  // SPI 54MHz=71ms, with DMA 50ms, 71-43 = 28ms spent drawing, so DMA is complete before next MCU block is ready
  // Apparent performance benefit of DMA = 71/50 = 42%, 50 - 43 = 7ms lost elsewhere
  // SPI 27MHz=95ms, with DMA 52ms. 95-43 = 52ms spent drawing, so DMA is *just* complete before next MCU block is ready!
  // Apparent performance benefit of DMA = 95/52 = 83%, 52 - 43 = 9ms lost elsewhere
#ifdef USE_DMA
  // Double buffering is used, the bitmap is copied to the buffer by pushImageDMA() the
  // bitmap can then be updated by the jpeg decoder while DMA is in progress
  if (dmaBufferSel) dmaBufferPtr = dmaBuffer2;
  else dmaBufferPtr = dmaBuffer1;
  dmaBufferSel = !dmaBufferSel; // Toggle buffer selection
  //  pushImageDMA() will clip the image block at screen boundaries before initiating DMA
  tft.pushImageDMA(x, y, w, h, bitmap, dmaBufferPtr); // Initiate DMA - blocking only if last DMA is not complete
  // The DMA transfer of image block to the TFT is now in progress...
#else
  // Non-DMA blocking alternative
  tft.pushImage(x, y, w, h, bitmap);  // Blocking, so only returns when image block is drawn
#endif
  // Return 1 to decode next block.
  return 1;
}

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

  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 = 10000000;
  config.pixel_format = PIXFORMAT_JPEG;
  //init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_QVGA; //FRAMESIZE_QVGA 320x240
    config.jpeg_quality = 15; //< Quality of JPEG output. 0-63 lower means higher quality 
    config.fb_count = 2; //Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed)
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // 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();
  s->set_contrast(s, 2);       // -2 to 2
  s->set_saturation(s, -2);     // -2 to 2

  //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  // Initialise the TFT
  tft.begin();
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.setRotation(1);//1:landscape 3:inv. landscape

#ifdef USE_DMA
  tft.initDMA(); // To use SPI DMA you must call initDMA() to setup the DMA engine
#endif

  // The jpeg image can be scaled down by a factor of 1, 2, 4, or 8
  TJpgDec.setJpgScale(2);

  // The colour byte order can be swapped by the decoder
  // using TJpgDec.setSwapBytes(true); or by the TFT_eSPI library:
  tft.setSwapBytes(true);

  // The decoder must be given the exact name of the rendering function above
  TJpgDec.setCallback(tft_output);
}

//##########################################################################
//
//##########################################################################
void loop() {
  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;

  //uint32_t last = millis();
  
  fb = esp_camera_fb_get();
  if(!fb){
    Serial.println("Camera capture failed");
    esp_camera_fb_return(fb);
    return;
  }

  size_t fb_len = 0;
  if(fb->format != PIXFORMAT_JPEG){
    Serial.println("Non-JPEG data not implemented");
    return;
  }

  #ifdef USE_DMA
  // Must use startWrite first so TFT chip select stays low during DMA and SPI channel settings remain configured
  tft.startWrite();
  #endif

  // Draw the image, top left at 0,0 - DMA request is handled in the call-back tft_output() in this sketch
  //TJpgDec.drawJpg(0, 0, panda, sizeof(panda));
  TJpgDec.drawJpg(0, 0,  fb->buf, fb->len);

  #ifdef USE_DMA
  // Must use endWrite to release the TFT chip select and release the SPI channel
  tft.endWrite();
  #endif
  
  esp_camera_fb_return(fb);
}i

em resumo a imagem foi movida para baixo e fica uma barra preta preenchendo o local (tft.fillScreen(TFT_BLACK))

Olá! Bem vindo ao Forum.

O que eu vou fazer é dar um chute, rsrsrs. Eu até tenho um EPS32 CAM, mas eu uso ele para gravar fotos, ativado por um sensor PIR. Nunca experimentei projetar vídeo em um display TFT.

A minha hipótese é que há uma incompatibilidade entre o tamanho da sua imagem (320x240) e o tamanho do display (160x80).

Aqui você até reduz a imagem pela metade, mas ainda assim ela fica em 160x120. Eu esperaria um corte no JPG ao invés de uma faixa preta na tela, mas também não duvido que a incompatibilidade possa provocar o problema.

Que tal testar reduzir a imagem em 4 vezes, só para ver como ela vai aparecer no display?

valeu pela resposta, tentei 3 e 4, mas a imagem continua no mesmo lugar ou então vai parar no canto inferior direito.
pode ser um problema da biblioteca?

Acho pouco provável. Mais provável que seja algum parâmetro ou configuração, mas infelizmente vai além do que eu consigo ajudar.

Se você tiver conhecimento de língua inglesa, pode postar a mesma dúvida em inglês na parte internacional do Fórum e ver se mais alguém ajuda.

O projeto é interessante! Se você conseguir achar a solução, compartilhe conosco depois.

Certo, bom já tenho um norte agora, irei procurar telas em QVGA ou a metade para ver se resolvo o problema

o problema era a tela

1 Like

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