mirror of
https://github.com/0015/ThatProject.git
synced 2026-01-13 01:37:43 +03:00
Toy Camera = ESP32CAM + ILI9488 + LVGL7 | Part 2, LVGL Configure #ESP32CAM #TOYCAM
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
#include "esp_camera.h"
|
||||
#include <lvgl.h>
|
||||
#include <SPI.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include <TJpg_Decoder.h>
|
||||
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#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 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10];
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
displayInit();
|
||||
lvglInit();
|
||||
cameraInit();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
showingImage();
|
||||
lv_task_handler();
|
||||
}
|
||||
|
||||
void cameraInit(){
|
||||
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;
|
||||
config.frame_size = FRAMESIZE_QVGA; //320x240
|
||||
config.jpeg_quality = 10;
|
||||
config.fb_count = 2;
|
||||
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void showingImage(){
|
||||
camera_fb_t* fb = esp_camera_fb_get();
|
||||
if(!fb || fb->format != PIXFORMAT_JPEG){
|
||||
Serial.println("Camera Capture Failed!");
|
||||
}else{
|
||||
Serial.println("Camera Image to Display Here!");
|
||||
TJpgDec.drawJpg(20, 40, (const uint8_t*)fb->buf, fb->len);
|
||||
}
|
||||
esp_camera_fb_return(fb);
|
||||
}
|
||||
|
||||
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap){
|
||||
if( y>= tft.height()) return 0;
|
||||
tft.pushImage(x, y, w, h, bitmap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void displayInit(){
|
||||
tft.begin();
|
||||
tft.setRotation(1);
|
||||
tft.fillScreen(TFT_WHITE);
|
||||
|
||||
uint16_t calData[5] = { 277, 3584, 252, 3468, 7 };
|
||||
tft.setTouch(calData);
|
||||
|
||||
TJpgDec.setJpgScale(1);
|
||||
TJpgDec.setSwapBytes(true);
|
||||
TJpgDec.setCallback(tft_output);
|
||||
}
|
||||
|
||||
void lvglInit(){
|
||||
lv_init();
|
||||
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
disp_drv.hor_res = 480;
|
||||
disp_drv.ver_res = 320;
|
||||
disp_drv.flush_cb = my_disp_flush;
|
||||
disp_drv.buffer = &disp_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
lv_layout();
|
||||
}
|
||||
|
||||
static void lv_layout(){
|
||||
lv_theme_t* th = lv_theme_material_init(LV_THEME_DEFAULT_COLOR_PRIMARY, LV_THEME_DEFAULT_COLOR_SECONDARY, LV_THEME_MATERIAL_FLAG_DARK, LV_THEME_DEFAULT_FONT_SMALL, LV_THEME_DEFAULT_FONT_NORMAL, LV_THEME_DEFAULT_FONT_SUBTITLE, LV_THEME_DEFAULT_FONT_TITLE);
|
||||
lv_obj_t* scr = lv_obj_create(NULL, NULL);
|
||||
lv_scr_load(scr);
|
||||
|
||||
lv_obj_t* btn = lv_btn_create(scr, NULL);
|
||||
lv_obj_set_pos(btn, 360, 100);
|
||||
lv_obj_set_size(btn, 100, 100);
|
||||
lv_obj_set_event_cb(btn, btn_event_cb);
|
||||
|
||||
lv_obj_t* label = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(label, "Shot");
|
||||
}
|
||||
|
||||
void btn_event_cb(lv_obj_t* btn, lv_event_t event){
|
||||
if(event == LV_EVENT_CLICKED){
|
||||
Serial.println("Clicked");
|
||||
}
|
||||
}
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
tft.startWrite();
|
||||
tft.setAddrWindow(area->x1, area->y1, w, h);
|
||||
tft.pushColors(&color_p->full, w * h, true);
|
||||
tft.endWrite();
|
||||
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
{
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
bool touched = tft.getTouch(&touchX, &touchY, 600);
|
||||
|
||||
if(!touched) {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touchX;
|
||||
data->point.y = touchY;
|
||||
|
||||
Serial.print("Data x");
|
||||
Serial.println(touchX);
|
||||
|
||||
Serial.print("Data y");
|
||||
Serial.println(touchY);
|
||||
}
|
||||
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
Reference in New Issue
Block a user