mirror of
https://github.com/0015/ThatProject.git
synced 2026-01-12 17:27:43 +03:00
Toy Camera = ESP32CAM + ILI9488 + LVGL7 | Part 2, LVGL Configure #ESP32CAM #TOYCAM
This commit is contained in:
112
ESP32_CAM_TOY_CAMERA/PART2/LVGL_TEST/LVGL_TEST.ino
Normal file
112
ESP32_CAM_TOY_CAMERA/PART2/LVGL_TEST/LVGL_TEST.ino
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#include <lvgl.h>
|
||||||
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
|
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
|
||||||
|
static lv_disp_buf_t disp_buf;
|
||||||
|
static lv_color_t buf[LV_HOR_RES_MAX * 10];
|
||||||
|
|
||||||
|
#if USE_LV_LOG != 0
|
||||||
|
/* Serial debugging */
|
||||||
|
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
|
||||||
|
{
|
||||||
|
|
||||||
|
Serial.printf("%s@%d->%s\r\n", file, line, dsc);
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200); /* prepare for possible serial debug */
|
||||||
|
|
||||||
|
lv_init();
|
||||||
|
|
||||||
|
#if USE_LV_LOG != 0
|
||||||
|
lv_log_register_print_cb(my_print); /* register print function for debugging */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tft.begin(); /* TFT init */
|
||||||
|
tft.setRotation(1); /* Landscape orientation */
|
||||||
|
|
||||||
|
uint16_t calData[5] = { 277, 3584, 252, 3468, 7 };
|
||||||
|
tft.setTouch(calData);
|
||||||
|
|
||||||
|
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_obj_t* btn = lv_btn_create(lv_scr_act(), NULL);
|
||||||
|
lv_obj_set_pos(btn, 10, 10);
|
||||||
|
lv_obj_set_size(btn, 100, 50);
|
||||||
|
lv_obj_set_event_cb(btn, btn_event_cb);
|
||||||
|
|
||||||
|
lv_obj_t* label = lv_label_create(btn, NULL);
|
||||||
|
lv_label_set_text(label, "Button");
|
||||||
|
}
|
||||||
|
|
||||||
|
void btn_event_cb(lv_obj_t* btn, lv_event_t event){
|
||||||
|
if(event == LV_EVENT_CLICKED){
|
||||||
|
Serial.println("Clicked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
lv_task_handler(); /* let the GUI do its work */
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
@@ -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*/
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//Original Source Code
|
||||||
|
//Bodmer TFT_eSPI
|
||||||
|
//https://github.com/Bodmer/TFT_eSPI/blob/master/examples/480%20x%20320/Touch_Controller_Demo/Touch_Controller_Demo.ino
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <TFT_eSPI.h>
|
||||||
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
|
||||||
|
void setup(void) {
|
||||||
|
uint16_t calibrationData[5];
|
||||||
|
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("starting");
|
||||||
|
|
||||||
|
tft.init();
|
||||||
|
|
||||||
|
tft.setRotation(1);
|
||||||
|
tft.fillScreen((0xFFFF));
|
||||||
|
|
||||||
|
tft.setCursor(20, 0, 2);
|
||||||
|
tft.setTextColor(TFT_BLACK, TFT_WHITE); tft.setTextSize(1);
|
||||||
|
tft.println("calibration run");
|
||||||
|
|
||||||
|
tft.calibrateTouch(calibrationData, TFT_WHITE, TFT_RED, 15);
|
||||||
|
for(int i=0; i<5; i++){
|
||||||
|
Serial.printf("%d, %d\n", i,calibrationData[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
tft.fillScreen((0xFFFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
uint16_t x, y;
|
||||||
|
static uint16_t color;
|
||||||
|
|
||||||
|
if (tft.getTouch(&x, &y)) {
|
||||||
|
|
||||||
|
tft.setCursor(5, 5, 2);
|
||||||
|
tft.printf("x: %i ", x);
|
||||||
|
tft.setCursor(5, 20, 2);
|
||||||
|
tft.printf("y: %i ", y);
|
||||||
|
|
||||||
|
tft.drawPixel(x, y, color);
|
||||||
|
color += 155;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,8 @@ Implement your project in an exquisite combination of hardware and software.
|
|||||||
|
|
||||||
* [Youtube ESP32 Project](https://www.youtube.com/playlist?list=PLnq7JUnBumAyhSBBp95MsQ5-chBAYheZw)
|
* [Youtube ESP32 Project](https://www.youtube.com/playlist?list=PLnq7JUnBumAyhSBBp95MsQ5-chBAYheZw)
|
||||||
|
|
||||||
|
* [Toy Camera = ESP32CAM + ILI9488 + LVGL7 | Part 2, LVGL Configure #ESP32CAM #TOYCAM][[Video]](https://youtu.be/K4VEvUVOkG0)[[Source Code]](https://github.com/0015/IdeasNProjects/tree/master/ESP32_CAM_TOY_CAMERA/PART2)
|
||||||
|
|
||||||
* [Toy Camera = ESP32CAM + ILI9488 + LVGL7 | Part 1, Live Feed Display #ESP32CAM #TOYCAM][[Video]](https://youtu.be/K5Tr0AjK-Uc)[[Source Code]](https://github.com/0015/IdeasNProjects/tree/master/ESP32_CAM_TOY_CAMERA/PART1)
|
* [Toy Camera = ESP32CAM + ILI9488 + LVGL7 | Part 1, Live Feed Display #ESP32CAM #TOYCAM][[Video]](https://youtu.be/K5Tr0AjK-Uc)[[Source Code]](https://github.com/0015/IdeasNProjects/tree/master/ESP32_CAM_TOY_CAMERA/PART1)
|
||||||
|
|
||||||
* [ESP32 | MPU6050 | MahonyAHRS - Adding BLE module(ft. String vs Float)][[Video]](https://youtu.be/lpnG7K0-E88)[[Source Code]](https://github.com/0015/IdeasNProjects/tree/master/Esp32_MPU6050_MahonyARHS)
|
* [ESP32 | MPU6050 | MahonyAHRS - Adding BLE module(ft. String vs Float)][[Video]](https://youtu.be/lpnG7K0-E88)[[Source Code]](https://github.com/0015/IdeasNProjects/tree/master/Esp32_MPU6050_MahonyARHS)
|
||||||
|
|||||||
Reference in New Issue
Block a user