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))
