├── .DS_Store ├── Schematic.pdf ├── .gitattributes ├── User_Setup.h ├── AI_Camera_Code └── AI_Camera_Code.ino └── lv_conf.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/AI-Camera/main/.DS_Store -------------------------------------------------------------------------------- /Schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/AI-Camera/main/Schematic.pdf -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /User_Setup.h: -------------------------------------------------------------------------------- 1 | // USER DEFINED SETTINGS 2 | // Set driver type, fonts to be loaded, pins used and SPI control method etc 3 | // 4 | // See the User_Setup_Select.h file if you wish to be able to define multiple 5 | // setups and then easily select which setup file is used by the compiler. 6 | // 7 | // If this file is edited correctly then all the library example sketches should 8 | // run without the need to make any more changes for a particular hardware setup! 9 | // Note that some sketches are designed for a particular TFT pixel width/height 10 | 11 | 12 | // ################################################################################## 13 | // 14 | // Section 1. Call up the right driver file and any options for it 15 | // 16 | // ################################################################################## 17 | 18 | // Define STM32 to invoke optimised processor support (only for STM32) 19 | //#define STM32 20 | 21 | // Defining the STM32 board allows the library to optimise the performance 22 | // for UNO compatible "MCUfriend" style shields 23 | //#define NUCLEO_64_TFT 24 | //#define NUCLEO_144_TFT 25 | 26 | // STM32 8 bit parallel only: 27 | // If STN32 Port A or B pins 0-7 are used for 8 bit parallel data bus bits 0-7 28 | // then this will improve rendering performance by a factor of ~8x 29 | //#define STM_PORTA_DATA_BUS 30 | //#define STM_PORTA_DATA_BUS 31 | 32 | // Tell the library to use 8 bit parallel mode (otherwise SPI is assumed) 33 | //#define TFT_PARALLEL_8_BIT 34 | 35 | // Display type - only define if RPi display 36 | //#define RPI_DISPLAY_TYPE // 20MHz maximum SPI 37 | 38 | // Only define one driver, the other ones must be commented out 39 | //#define ILI9341_DRIVER 40 | //#define ST7735_DRIVER // Define additional parameters below for this display 41 | //#define ILI9163_DRIVER // Define additional parameters below for this display 42 | //#define S6D02A1_DRIVER 43 | //#define RPI_ILI9486_DRIVER // 20MHz maximum SPI 44 | //#define HX8357D_DRIVER 45 | //#define ILI9481_DRIVER 46 | //#define ILI9486_DRIVER 47 | #define ILI9488_DRIVER // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high) 48 | //#define ST7789_DRIVER // Full configuration option, define additional parameters below for this display 49 | //#define ST7789_2_DRIVER // Minimal configuration option, define additional parameters below for this display 50 | //#define R61581_DRIVER 51 | //#define RM68140_DRIVER 52 | //#define ST7796_DRIVER 53 | //#define SSD1963_480_DRIVER // Untested 54 | //#define SSD1963_800_DRIVER // Untested 55 | //#define SSD1963_800ALT_DRIVER // Untested 56 | 57 | // Some displays support SPI reads via the MISO pin, other displays have a single 58 | // bi-directional SDA pin and the library will try to read this via the MOSI line. 59 | // To use the SDA line for reading data from the TFT uncomment the following line: 60 | 61 | // #define TFT_SDA_READ // This option is for ESP32 ONLY, tested with ST7789 display only 62 | 63 | // For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display 64 | // Try ONE option at a time to find the correct colour order for your display 65 | 66 | // #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue 67 | // #define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red 68 | 69 | // For M5Stack ESP32 module with integrated ILI9341 display ONLY, remove // in line below 70 | 71 | // #define M5STACK 72 | 73 | // For ST7789, ST7735 and ILI9163 ONLY, define the pixel width and height in portrait orientation 74 | // #define TFT_WIDTH 80 75 | // #define TFT_WIDTH 128 76 | // #define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320 77 | // #define TFT_HEIGHT 160 78 | // #define TFT_HEIGHT 128 79 | // #define TFT_HEIGHT 240 // ST7789 240 x 240 80 | // #define TFT_HEIGHT 320 // ST7789 240 x 320 81 | 82 | // For ST7735 ONLY, define the type of display, originally this was based on the 83 | // colour of the tab on the screen protector film but this is not always true, so try 84 | // out the different options below if the screen does not display graphics correctly, 85 | // e.g. colours wrong, mirror images, or tray pixels at the edges. 86 | // Comment out ALL BUT ONE of these options for a ST7735 display driver, save this 87 | // this User_Setup file, then rebuild and upload the sketch to the board again: 88 | 89 | // #define ST7735_INITB 90 | // #define ST7735_GREENTAB 91 | // #define ST7735_GREENTAB2 92 | // #define ST7735_GREENTAB3 93 | // #define ST7735_GREENTAB128 // For 128 x 128 display 94 | // #define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset) 95 | // #define ST7735_REDTAB 96 | // #define ST7735_BLACKTAB 97 | // #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset 98 | 99 | // If colours are inverted (white shows as black) then uncomment one of the next 100 | // 2 lines try both options, one of the options should correct the inversion. 101 | 102 | // #define TFT_INVERSION_ON 103 | // #define TFT_INVERSION_OFF 104 | 105 | 106 | // ################################################################################## 107 | // 108 | // Section 2. Define the pins that are used to interface with the display here 109 | // 110 | // ################################################################################## 111 | 112 | // If a backlight control signal is available then define the TFT_BL pin in Section 2 113 | // below. The backlight will be turned ON when tft.begin() is called, but the library 114 | // needs to know if the LEDs are ON with the pin HIGH or LOW. If the LEDs are to be 115 | // driven with a PWM signal or turned OFF/ON then this must be handled by the user 116 | // sketch. e.g. with digitalWrite(TFT_BL, LOW); 117 | 118 | // #define TFT_BL 32 // LED back-light control pin 119 | // #define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW) 120 | 121 | 122 | 123 | // We must use hardware SPI, a minimum of 3 GPIO pins is needed. 124 | // Typical setup for ESP8266 NodeMCU ESP-12 is : 125 | // 126 | // Display SDO/MISO to NodeMCU pin D6 (or leave disconnected if not reading TFT) 127 | // Display LED to NodeMCU pin VIN (or 5V, see below) 128 | // Display SCK to NodeMCU pin D5 129 | // Display SDI/MOSI to NodeMCU pin D7 130 | // Display DC (RS/AO)to NodeMCU pin D3 131 | // Display RESET to NodeMCU pin D4 (or RST, see below) 132 | // Display CS to NodeMCU pin D8 (or GND, see below) 133 | // Display GND to NodeMCU pin GND (0V) 134 | // Display VCC to NodeMCU 5V or 3.3V 135 | // 136 | // The TFT RESET pin can be connected to the NodeMCU RST pin or 3.3V to free up a control pin 137 | // 138 | // The DC (Data Command) pin may be labeled AO or RS (Register Select) 139 | // 140 | // With some displays such as the ILI9341 the TFT CS pin can be connected to GND if no more 141 | // SPI devices (e.g. an SD Card) are connected, in this case comment out the #define TFT_CS 142 | // line below so it is NOT defined. Other displays such at the ST7735 require the TFT CS pin 143 | // to be toggled during setup, so in these cases the TFT_CS line must be defined and connected. 144 | // 145 | // The NodeMCU D0 pin can be used for RST 146 | // 147 | // 148 | // Note: only some versions of the NodeMCU provide the USB 5V on the VIN pin 149 | // If 5V is not available at a pin you can use 3.3V but backlight brightness 150 | // will be lower. 151 | 152 | 153 | // ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ###### 154 | 155 | // For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation 156 | //// Reset pin (could connect to NodeMCU RST, see next line) 157 | //#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V 158 | 159 | //#define TFT_BL PIN_D1 // LED back-light (only for ST7789 with backlight control pin) 160 | 161 | //#define TOUCH_CS PIN_D2 // Chip select pin (T_CS) of touch screen 162 | 163 | //#define TFT_WR PIN_D2 // Write strobe for modified Raspberry Pi TFT only 164 | 165 | 166 | // ###### FOR ESP8266 OVERLAP MODE EDIT THE PIN NUMBERS IN THE FOLLOWING LINES ###### 167 | 168 | // Overlap mode shares the ESP8266 FLASH SPI bus with the TFT so has a performance impact 169 | // but saves pins for other functions. It is best not to connect MISO as some displays 170 | // do not tristate that line wjen chip select is high! 171 | // On NodeMCU 1.0 SD0=MISO, SD1=MOSI, CLK=SCLK to connect to TFT in overlap mode 172 | // On NodeMCU V3 S0 =MISO, S1 =MOSI, S2 =SCLK 173 | // In ESP8266 overlap mode the following must be defined 174 | 175 | //#define TFT_SPI_OVERLAP 176 | 177 | // In ESP8266 overlap mode the TFT chip select MUST connect to pin D3 178 | //#define TFT_CS PIN_D3 179 | //#define TFT_DC PIN_D5 // Data Command control pin 180 | //#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line) 181 | //#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V 182 | 183 | 184 | // ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP ###### 185 | 186 | // For ESP32 Dev board (only tested with ILI9341 display) 187 | // The hardware SPI can be mapped to any pins 188 | 189 | //#define TFT_MISO 19 190 | //#define TFT_MOSI 23 191 | //#define TFT_SCLK 18 192 | //#define TFT_CS 15 // Chip select control pin 193 | //#define TFT_DC 2 // Data Command control pin 194 | //#define TFT_RST 4 // Reset pin (could connect to RST pin) 195 | //#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST 196 | 197 | //#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen 198 | 199 | //#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only 200 | 201 | // For the M5Stack module use these #define lines 202 | //#define TFT_MISO 19 203 | //#define TFT_MOSI 23 204 | //#define TFT_SCLK 18 205 | //#define TFT_CS 14 // Chip select control pin 206 | //#define TFT_DC 27 // Data Command control pin 207 | //#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin) 208 | //#define TFT_BL 32 // LED back-light (required for M5Stack) 209 | 210 | // ###### EDIT THE PINs BELOW TO SUIT YOUR ESP32 PARALLEL TFT SETUP ###### 211 | 212 | // The library supports 8 bit parallel TFTs with the ESP32, the pin 213 | // selection below is compatible with ESP32 boards in UNO format. 214 | // Wemos D32 boards need to be modified, see diagram in Tools folder. 215 | // Only ILI9481 and ILI9341 based displays have been tested! 216 | 217 | // Parallel bus is only supported for the STM32 and ESP32 218 | // Example below is for ESP32 Parallel interface with UNO displays 219 | 220 | // Tell the library to use 8 bit parallel mode (otherwise SPI is assumed) 221 | //#define TFT_PARALLEL_8_BIT 222 | 223 | // The ESP32 and TFT the pins used for testing are: 224 | 225 | 226 | #define TFT_RST 0 // Connect to RESET 227 | #define TOUCH_CS 2 228 | #define TFT_CS 12 229 | #define TFT_DC 13 // Connect to DC (RS) 230 | #define TFT_SCLK 14 // Connect to CS 231 | #define TOUCH_DO 15 232 | #define TFT_MISO 15// Connect to SDI (MOSI) of the display 233 | #define TFT_MOSI 16 234 | #define TFT_BL -1 // Backlight (set to -1 if always on) 235 | 236 | //#define TFT_CS 33 // Chip select control pin (library pulls permanently low 237 | //#define TFT_DC 15 // Data Command control pin - must use a pin in the range 0-31 238 | //#define TFT_RST 32 // Reset pin, toggles on startup 239 | 240 | //#define TFT_WR 4 // Write strobe control pin - must use a pin in the range 0-31 241 | //#define TFT_RD 2 // Read strobe control pin 242 | 243 | //#define TFT_D0 12 // Must use pins in the range 0-31 for the data bus 244 | //#define TFT_D1 13 // so a single register write sets/clears all bits. 245 | //#define TFT_D2 26 // Pins can be randomly assigned, this does not affect 246 | //#define TFT_D3 25 // TFT screen update performance. 247 | //#define TFT_D4 17 248 | //#define TFT_D5 16 249 | //#define TFT_D6 27 250 | //#define TFT_D7 14 251 | 252 | // ###### EDIT THE PINs BELOW TO SUIT YOUR STM32 SPI TFT SETUP ###### 253 | 254 | // The TFT can be connected to SPI port 1 or 2 255 | //#define TFT_SPI_PORT 1 // SPI port 1 maximum clock rate is 55MHz 256 | //#define TFT_MOSI PA7 257 | //#define TFT_MISO PA6 258 | //#define TFT_SCLK PA5 259 | 260 | //#define TFT_SPI_PORT 2 // SPI port 2 maximum clock rate is 27MHz 261 | //#define TFT_MOSI PB15 262 | //#define TFT_MISO PB14 263 | //#define TFT_SCLK PB13 264 | 265 | // Can use Ardiuno pin references, arbitrary allocation, TFT_eSPI controls chip select 266 | //#define TFT_CS D5 // Chip select control pin to TFT CS 267 | //#define TFT_DC D6 // Data Command control pin to TFT DC (may be labelled RS = Register Select) 268 | //#define TFT_RST D7 // Reset pin to TFT RST (or RESET) 269 | // OR alternatively, we can use STM32 port reference names PXnn 270 | //#define TFT_CS PE11 // Nucleo-F767ZI equivalent of D5 271 | //#define TFT_DC PE9 // Nucleo-F767ZI equivalent of D6 272 | //#define TFT_RST PF13 // Nucleo-F767ZI equivalent of D7 273 | 274 | //#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to processor reset 275 | // Use an Arduino pin for initial testing as connecting to processor reset 276 | // may not work (pulse too short at power up?) 277 | 278 | // ################################################################################## 279 | // 280 | // Section 3. Define the fonts that are to be used here 281 | // 282 | // ################################################################################## 283 | 284 | // Comment out the #defines below with // to stop that font being loaded 285 | // The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not 286 | // normally necessary. If all fonts are loaded the extra FLASH space required is 287 | // about 17Kbytes. To save FLASH space only enable the fonts you need! 288 | 289 | #define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH 290 | #define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters 291 | #define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters 292 | #define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm 293 | #define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-. 294 | #define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. 295 | //#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT 296 | #define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts 297 | 298 | // Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded 299 | // this will save ~20kbytes of FLASH 300 | #define SMOOTH_FONT 301 | 302 | 303 | // ################################################################################## 304 | // 305 | // Section 4. Other options 306 | // 307 | // ################################################################################## 308 | 309 | // Define the SPI clock frequency, this affects the graphics rendering speed. Too 310 | // fast and the TFT driver will not keep up and display corruption appears. 311 | // With an ILI9341 display 40MHz works OK, 80MHz sometimes fails 312 | // With a ST7735 display more than 27MHz may not work (spurious pixels and lines) 313 | // With an ILI9163 display 27 MHz works OK. 314 | 315 | // #define SPI_FREQUENCY 1000000 316 | // #define SPI_FREQUENCY 5000000 317 | // #define SPI_FREQUENCY 10000000 318 | // #define SPI_FREQUENCY 20000000 319 | //#define SPI_FREQUENCY 27000000 320 | #define SPI_FREQUENCY 40000000 321 | // #define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz) 322 | // #define SPI_FREQUENCY 80000000 323 | 324 | // Optional reduced SPI frequency for reading TFT 325 | #define SPI_READ_FREQUENCY 20000000 326 | 327 | // The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here: 328 | #define SPI_TOUCH_FREQUENCY 2500000 329 | 330 | // The ESP32 has 2 free SPI ports i.e. VSPI and HSPI, the VSPI is the default. 331 | // If the VSPI port is in use and pins are not accessible (e.g. TTGO T-Beam) 332 | // then uncomment the following line: 333 | //#define USE_HSPI_PORT 334 | 335 | // Comment out the following #define if "SPI Transactions" do not need to be 336 | // supported. When commented out the code size will be smaller and sketches will 337 | // run slightly faster, so leave it commented out unless you need it! 338 | 339 | // Transaction support is needed to work with SD library but not needed with TFT_SdFat 340 | // Transaction support is required if other SPI devices are connected. 341 | 342 | // Transactions are automatically enabled by the library for an ESP32 (to use HAL mutex) 343 | // so changing it here has no effect 344 | 345 | // #define SUPPORT_TRANSACTIONS 346 | -------------------------------------------------------------------------------- /AI_Camera_Code/AI_Camera_Code.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The Code was test with 4 | 5 | Arduino 1.8.13 6 | ESP32 BOARD PACKAGE 1.0.6 7 | TJpg_Decoder By Bodmer 0.0.3 8 | TFT_SPI By Bodmer 2.3.4 9 | lvgl By kisvegabor 7.8.1 10 | 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "esp_camera.h" 19 | #include 20 | 21 | const char* ssid = "SSID"; 22 | const char* password = "PASS"; 23 | 24 | const String apiKey = "YOUR GPT-4o API KEY"; 25 | 26 | #define PWDN_GPIO_NUM 32 27 | #define RESET_GPIO_NUM -1 28 | #define XCLK_GPIO_NUM 0 29 | #define SIOD_GPIO_NUM 26 30 | #define SIOC_GPIO_NUM 27 31 | #define Y9_GPIO_NUM 35 32 | #define Y8_GPIO_NUM 34 33 | #define Y7_GPIO_NUM 39 34 | #define Y6_GPIO_NUM 36 35 | #define Y5_GPIO_NUM 21 36 | #define Y4_GPIO_NUM 19 37 | #define Y3_GPIO_NUM 18 38 | #define Y2_GPIO_NUM 5 39 | #define VSYNC_GPIO_NUM 25 40 | #define HREF_GPIO_NUM 23 41 | #define PCLK_GPIO_NUM 22 42 | #define FLASH_GPIO_NUM 4 // Flash pin (if using external flash) 43 | #define BUZZER_PIN 3 // Buzzer connected to GPIO3 (for sound indication) 44 | #define BUTTON_PIN 1 // Button pin for triggering capture (GPIO 1) 45 | 46 | 47 | TFT_eSPI tft = TFT_eSPI(); 48 | static lv_disp_buf_t disp_buf; // Buffer to hold pixel data for LVGL 49 | static lv_color_t buf[LV_HOR_RES_MAX * 10]; // Buffer to store pixel data for LVGL 50 | 51 | // Declare pointers for LVGL keyboard and text area objects 52 | static lv_obj_t* kb; 53 | static lv_obj_t* ta; 54 | 55 | String userInputText = ""; // Holds the text entered by the user 56 | String capturedImageBase64 = ""; // Holds the Base64-encoded image data 57 | 58 | bool flashOn = false; // Track flash state 59 | bool isCaptureMode = false; // Indicates if the system is in capture mode 60 | bool isResponseDisplayed = false; // Indicates if a response has been displayed 61 | 62 | camera_fb_t* capturedFrameBuffer = nullptr; // Holds the captured frame buffer 63 | 64 | 65 | // Function to encode image to Base64 66 | String encodeImageToBase64(uint8_t* imageData, size_t imageSize) { 67 | return base64::encode((const uint8_t*)imageData, imageSize); 68 | } 69 | 70 | 71 | void setup() { 72 | Serial.begin(115200); 73 | 74 | displayInit(); 75 | drawBorders(); 76 | 77 | pinMode(BUZZER_PIN, OUTPUT); 78 | pinMode(BUTTON_PIN, INPUT_PULLUP); 79 | pinMode(FLASH_GPIO_NUM, OUTPUT); 80 | digitalWrite(FLASH_GPIO_NUM, LOW); // Ensure flash is off initially 81 | 82 | displayLargeCenteredMessage("AI CAMERA BY TECHIESMS"); 83 | delay(1000); 84 | 85 | WiFi.begin(ssid, password); 86 | 87 | 88 | displayLargeCenteredMessage("Connecting to WiFi..."); 89 | delay(500); 90 | Serial.println("Connecting to WiFi..."); 91 | while (WiFi.status() != WL_CONNECTED) { 92 | delay(500); 93 | Serial.println("..."); 94 | } 95 | Serial.println("WiFi Connected!"); 96 | Serial.println("IP Address: " + WiFi.localIP().toString()); 97 | displayLargeCenteredMessage("WiFi Connected!"); 98 | delay(500); 99 | 100 | cameraInit(); // Initialize camera 101 | lvglInit(); // Initialize LVGL (LittlevGL) graphics library 102 | lv_layout(); // Initialize LVGL layout and interface 103 | } 104 | 105 | 106 | // Initializes the TFT display and sets up touch calibration and image decoder 107 | void displayInit() { 108 | tft.begin(); 109 | tft.setRotation(1); // Set display rotation (1 is usually landscape mode) 110 | tft.fillScreen(TFT_BLACK); 111 | 112 | uint16_t calData[5] = { 292, 3562, 332, 3384, 7 }; // Calibration data for the touch screen 113 | tft.setTouch(calData); // Set the touch calibration data for the screen 114 | 115 | drawBorders(); 116 | 117 | TJpgDec.setJpgScale(1); // Set the scale of the JPEG image (1 means no scaling) 118 | TJpgDec.setSwapBytes(true); // Set byte swapping to handle different color formats correctly 119 | TJpgDec.setCallback(tft_output); // Set the callback function to draw the image on TFT display 120 | } 121 | 122 | 123 | // LVGL display flush callback function for rendering the display buffer on the screen 124 | void my_disp_flush(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) { 125 | uint32_t w = (area->x2 - area->x1 + 1); 126 | uint32_t h = (area->y2 - area->y1 + 1); 127 | 128 | tft.startWrite(); 129 | tft.setAddrWindow(area->x1, area->y1, w, h); 130 | tft.pushColors(&color_p->full, w * h, true); 131 | tft.endWrite(); 132 | 133 | lv_disp_flush_ready(disp); 134 | } 135 | 136 | 137 | // Callback function used by the JPEG decoder to draw an image on the TFT screen 138 | bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) { 139 | if (y >= tft.height()) return 0; 140 | tft.pushImage(x, y, w, h, bitmap); 141 | return 1; 142 | } 143 | 144 | 145 | // Captures and displays a camera feed on the TFT display 146 | void displayCameraFeed() { 147 | camera_fb_t* fb = esp_camera_fb_get(); // Capture a frame from the camera 148 | if (!fb) { 149 | Serial.println("Camera Capture Failed: Frame buffer is NULL!"); 150 | return; 151 | } 152 | 153 | // Check if the captured frame is in the correct format (JPEG) 154 | if (fb->format != PIXFORMAT_JPEG) { 155 | Serial.println("Camera Capture Failed: Incorrect format!"); 156 | esp_camera_fb_return(fb); 157 | return; 158 | } 159 | 160 | // Draw the captured JPEG image on the screen using the JPEG decoder 161 | TJpgDec.drawJpg(80, 5, (const uint8_t*)fb->buf, fb->len); 162 | esp_camera_fb_return(fb); 163 | drawBorders(); 164 | } 165 | 166 | 167 | void cameraInit() { 168 | camera_config_t config; 169 | config.ledc_channel = LEDC_CHANNEL_0; 170 | config.ledc_timer = LEDC_TIMER_0; 171 | config.pin_d0 = Y2_GPIO_NUM; 172 | config.pin_d1 = Y3_GPIO_NUM; 173 | config.pin_d2 = Y4_GPIO_NUM; 174 | config.pin_d3 = Y5_GPIO_NUM; 175 | config.pin_d4 = Y6_GPIO_NUM; 176 | config.pin_d5 = Y7_GPIO_NUM; 177 | config.pin_d6 = Y8_GPIO_NUM; 178 | config.pin_d7 = Y9_GPIO_NUM; 179 | config.pin_xclk = XCLK_GPIO_NUM; 180 | config.pin_pclk = PCLK_GPIO_NUM; 181 | config.pin_vsync = VSYNC_GPIO_NUM; 182 | config.pin_href = HREF_GPIO_NUM; 183 | config.pin_sscb_sda = SIOD_GPIO_NUM; 184 | config.pin_sscb_scl = SIOC_GPIO_NUM; 185 | config.pin_pwdn = PWDN_GPIO_NUM; 186 | config.pin_reset = RESET_GPIO_NUM; 187 | config.xclk_freq_hz = 9000000; 188 | config.pixel_format = PIXFORMAT_JPEG; 189 | config.frame_size = FRAMESIZE_QVGA; 190 | config.jpeg_quality = 12; 191 | config.fb_count = 1; 192 | 193 | if (esp_camera_init(&config) != ESP_OK) { 194 | displayMessage("Camera Initialization Failed!"); 195 | return; 196 | } 197 | displayLargeCenteredMessage("Camera Initialized!"); 198 | delay(500); 199 | drawBorders(); 200 | } 201 | 202 | 203 | void lvglInit() { 204 | lv_init(); // Initialize LVGL 205 | 206 | lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); // Initialize the display buffer and driver 207 | 208 | lv_disp_drv_t disp_drv; 209 | lv_disp_drv_init(&disp_drv); 210 | disp_drv.hor_res = 480; 211 | disp_drv.ver_res = 320; 212 | disp_drv.flush_cb = my_disp_flush; // Custom flush function to update screen 213 | disp_drv.buffer = &disp_buf; 214 | lv_disp_drv_register(&disp_drv); 215 | 216 | // Initialize touch input device driver 217 | lv_indev_drv_t indev_drv; 218 | lv_indev_drv_init(&indev_drv); 219 | indev_drv.type = LV_INDEV_TYPE_POINTER; 220 | indev_drv.read_cb = my_touchpad_read; // Custom touchpad read function 221 | lv_indev_drv_register(&indev_drv); 222 | 223 | // Initialize layout 224 | lv_layout(); 225 | } 226 | 227 | void lv_layout() { 228 | // Create a material theme for consistency 229 | 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); 230 | 231 | lv_obj_t* scr = lv_obj_create(NULL, NULL); 232 | lv_scr_load(scr); 233 | 234 | // Flash button 235 | lv_obj_t* flashBtn = lv_btn_create(scr, NULL); 236 | lv_obj_set_pos(flashBtn, 412, 55); // Adjust as needed 237 | lv_obj_set_size(flashBtn, 50, 50); 238 | lv_obj_set_event_cb(flashBtn, flash_btn_event_cb); 239 | lv_obj_t* flashLabel = lv_label_create(flashBtn, NULL); 240 | lv_label_set_text(flashLabel, "Flash"); 241 | 242 | // Capture button 243 | lv_obj_t* captureBtn = lv_btn_create(scr, NULL); 244 | lv_obj_set_pos(captureBtn, 408, 125); // Adjust as needed 245 | lv_obj_set_size(captureBtn, 70, 65); 246 | lv_obj_set_event_cb(captureBtn, capture_btn_event_cb); 247 | lv_obj_t* captureLabel = lv_label_create(captureBtn, NULL); 248 | lv_label_set_text(captureLabel, "Capture"); 249 | 250 | // Bottom message label 251 | lv_obj_t* messageLabel = lv_label_create(scr, NULL); 252 | lv_label_set_text(messageLabel, "Press the button to capture a new image"); 253 | // Position the label at the bottom 254 | lv_obj_align(messageLabel, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -30); 255 | } 256 | 257 | 258 | void flash_btn_event_cb(lv_obj_t* btn, lv_event_t event) { 259 | if (event == LV_EVENT_CLICKED) { 260 | flashOn = !flashOn; 261 | digitalWrite(FLASH_GPIO_NUM, flashOn ? HIGH : LOW); 262 | Serial.println(flashOn ? "Flash ON" : "Flash OFF"); 263 | } 264 | } 265 | 266 | 267 | void capture_btn_event_cb(lv_obj_t* btn, lv_event_t event) { 268 | if (event == LV_EVENT_CLICKED) { 269 | Serial.println("Button clicked, capturing image..."); 270 | displayLargeCenteredMessage("Capturing Image..."); 271 | delay(100); 272 | captureAndProcessImage(); 273 | } 274 | } 275 | 276 | 277 | void createKeyboard() { 278 | 279 | // Create a new screen for the keyboard and text area 280 | lv_obj_t* keyboard_screen = lv_obj_create(NULL, NULL); 281 | lv_scr_load(keyboard_screen); // Load the new screen 282 | lv_obj_set_style_local_bg_opa(keyboard_screen, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER); 283 | lv_obj_set_style_local_bg_color(keyboard_screen, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); 284 | 285 | // Create the text area 286 | lv_obj_t* ta_question = lv_textarea_create(keyboard_screen, NULL); 287 | lv_obj_set_size(ta_question, 400, 100); 288 | lv_obj_align(ta_question, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); 289 | lv_textarea_set_placeholder_text(ta_question, "Enter your question:"); 290 | lv_textarea_set_text(ta_question, ""); 291 | 292 | // Create the keyboard 293 | lv_obj_t* kb = lv_keyboard_create(keyboard_screen, NULL); 294 | lv_obj_set_size(kb, LV_HOR_RES, LV_VER_RES / 2); 295 | lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); 296 | lv_keyboard_set_cursor_manage(kb, true); 297 | 298 | // Apply keyboard styles 299 | static lv_style_t kb_style; 300 | lv_style_init(&kb_style); 301 | lv_style_set_bg_color(&kb_style, LV_STATE_DEFAULT, LV_COLOR_GRAY); 302 | lv_style_set_bg_opa(&kb_style, LV_STATE_DEFAULT, LV_OPA_COVER); 303 | lv_style_set_border_width(&kb_style, LV_STATE_DEFAULT, 0); 304 | 305 | lv_obj_add_style(kb, LV_OBJ_PART_MAIN, &kb_style); 306 | 307 | lv_keyboard_set_textarea(kb, ta_question); 308 | lv_obj_set_event_cb(kb, keyboard_event_cb); // Attach event callback 309 | } 310 | 311 | void keyboard_event_cb(lv_obj_t* kb, lv_event_t event) { 312 | lv_keyboard_def_event_cb(kb, event); // Handle default keyboard behavior 313 | 314 | if (event == LV_EVENT_APPLY) { 315 | // Retrieve the text from the text area linked to the keyboard 316 | lv_obj_t* ta_question = lv_keyboard_get_textarea(kb); 317 | const char* text = lv_textarea_get_text(ta_question); 318 | 319 | userInputText = String(text); // Store user input 320 | Serial.println("User Input: " + userInputText); 321 | 322 | // Process the input with the captured image 323 | if (!capturedImageBase64.isEmpty()) { 324 | exampleVisionQuestionWithImage(userInputText, capturedImageBase64); 325 | } else { 326 | displayMessage("Error: Failed to encode image."); 327 | } 328 | } 329 | 330 | if (event == LV_EVENT_CANCEL) { 331 | 332 | 333 | // Retrieve the text area linked to the keyboard 334 | lv_obj_t* ta_question = lv_keyboard_get_textarea(kb); 335 | 336 | if (ta_question) { 337 | // Clear the text area content (you can set an empty string) 338 | lv_textarea_set_text(ta_question, ""); 339 | } 340 | } 341 | } 342 | 343 | void captureAndProcessImage() { 344 | 345 | 346 | // Capture the image from the camera 347 | capturedFrameBuffer = esp_camera_fb_get(); 348 | 349 | if (!capturedFrameBuffer) { 350 | Serial.println("Camera capture failed"); 351 | displayMessage("Error: Camera capture failed"); 352 | } 353 | 354 | // Encode the captured image to Base64 355 | capturedImageBase64 = encodeImageToBase64(capturedFrameBuffer->buf, capturedFrameBuffer->len); 356 | 357 | // Immediately turn off the flash when the button is pressed 358 | if (flashOn) { 359 | digitalWrite(FLASH_GPIO_NUM, LOW); // Turn off flash (GPIO 4) 360 | flashOn = false; 361 | Serial.println("Flash OFF"); 362 | } 363 | 364 | 365 | beep(); 366 | 367 | if (capturedImageBase64.isEmpty()) { 368 | Serial.println("Failed to encode the image!"); 369 | displayMessage("Error: Image encoding failed"); 370 | 371 | esp_camera_fb_return(capturedFrameBuffer); // Return the frame buffer 372 | capturedFrameBuffer = nullptr; 373 | } 374 | 375 | Serial.println("Image encoded to Base64"); 376 | 377 | 378 | // Stop the live feed by setting isCaptureMode to true 379 | isCaptureMode = true; 380 | 381 | // Display the captured image 382 | tft.fillScreen(TFT_BLACK); // Clear the screen 383 | drawBorders(); // Draw borders around the screen 384 | 385 | if (capturedFrameBuffer) { 386 | TJpgDec.drawJpg(80, 5, capturedFrameBuffer->buf, capturedFrameBuffer->len); 387 | } 388 | 389 | displayLargeCenteredMessage("Opening the keyboard..."); 390 | 391 | delay(3000); // Wait for 3 seconds 392 | 393 | // Show the keyboard for user input 394 | createKeyboard(); 395 | 396 | drawBorders(); 397 | } 398 | 399 | void exampleVisionQuestionWithImage(const String& userInputText, const String& base64Image) { 400 | String url = "data:image/jpeg;base64," + base64Image; 401 | 402 | DynamicJsonDocument doc(4096); 403 | doc["model"] = "gpt-4o"; 404 | JsonArray messages = doc.createNestedArray("messages"); 405 | JsonObject message = messages.createNestedObject(); 406 | message["role"] = "user"; 407 | JsonArray content = message.createNestedArray("content"); 408 | 409 | JsonObject textContent = content.createNestedObject(); 410 | textContent["type"] = "text"; 411 | textContent["text"] = userInputText; // User question 412 | 413 | JsonObject imageContent = content.createNestedObject(); 414 | imageContent["type"] = "image_url"; 415 | JsonObject imageUrlObject = imageContent.createNestedObject("image_url"); 416 | imageUrlObject["url"] = url; 417 | imageContent["image_url"]["detail"] = "auto"; 418 | 419 | doc["max_tokens"] = 400; 420 | String payload; 421 | serializeJson(doc, payload); 422 | 423 | Serial.println("Sending request to ChatGPT..."); 424 | Serial.println("User Input: " + userInputText); 425 | Serial.println("Base64 Image Size: " + String(base64Image.length())); 426 | 427 | // Clear the screen 428 | tft.fillScreen(TFT_BLACK); 429 | drawBorders(); 430 | 431 | // Display the captured image 432 | if (capturedFrameBuffer) { 433 | TJpgDec.drawJpg(80, 5, capturedFrameBuffer->buf, capturedFrameBuffer->len); 434 | } 435 | 436 | // Display the "Sending request" message 437 | displayLargeCenteredMessage("Sending request to ChatGPT..."); 438 | 439 | String result; 440 | if (sendPostRequest(payload, result)) { 441 | displayCapturedImageAndResponse(result); 442 | Serial.println("Response received from ChatGPT:"); 443 | Serial.println(result); 444 | } else { 445 | Serial.println("Error: Unable to get a response from ChatGPT"); 446 | displayCapturedImageAndResponse("Error: Unable to get response from ChatGPT"); 447 | } 448 | } 449 | 450 | 451 | bool sendPostRequest(const String& payload, String& result) { 452 | HTTPClient http; 453 | http.begin("https://api.openai.com/v1/chat/completions"); 454 | http.addHeader("Content-Type", "application/json"); 455 | http.addHeader("Authorization", "Bearer " + apiKey); 456 | 457 | int httpCode = http.POST(payload); 458 | if (httpCode > 0) { 459 | if (httpCode == HTTP_CODE_OK) { 460 | result = http.getString(); 461 | http.end(); 462 | return true; 463 | } else { 464 | Serial.println("HTTP Error Code: " + String(httpCode)); 465 | } 466 | } else { 467 | Serial.println("POST request failed."); 468 | } 469 | http.end(); 470 | return false; 471 | } 472 | 473 | 474 | 475 | void displayCapturedImageAndResponse(const String& result) { 476 | // Parse the ChatGPT response 477 | StaticJsonDocument<2000> doc; 478 | DeserializationError error = deserializeJson(doc, result); 479 | const char* response = "Error: Parsing failed"; // Default message if parsing fails 480 | if (!error) { 481 | response = doc["choices"][0]["message"]["content"]; 482 | } 483 | 484 | // Display the captured image 485 | if (capturedFrameBuffer) { 486 | TJpgDec.drawJpg(80, 5, capturedFrameBuffer->buf, capturedFrameBuffer->len); 487 | } 488 | 489 | 490 | // Display the response message 491 | displayMessage(response); // Custom function for displaying message 492 | 493 | while (!isResponseDisplayed) { 494 | uint16_t touchX = 0, touchY = 0; 495 | if (tft.getTouch(&touchX, &touchY, 600)) { // If touch detected 496 | Serial.println("Touch detected, reinitializing display..."); 497 | isResponseDisplayed = 1; 498 | } 499 | delay(10); 500 | } 501 | 502 | if (isResponseDisplayed) { 503 | isResponseDisplayed = 0; 504 | reinitializeDisplay(); // Reinitialize display on touch 505 | } 506 | } 507 | 508 | 509 | void reinitializeDisplay() { 510 | // Clear the screen and reset the display 511 | tft.fillScreen(TFT_WHITE); // Clear the screen 512 | drawBorders(); // Draw borders around the screen 513 | 514 | // Reinitialize any required settings or layouts 515 | capturedFrameBuffer = nullptr; 516 | capturedImageBase64 = ""; 517 | isCaptureMode = false; 518 | 519 | Serial.println("Display reinitialized successfully"); 520 | 521 | // Load the initial layout for the interface (if you are using a layout function) 522 | lv_layout(); // This should load the layout you want to display 523 | } 524 | 525 | 526 | void loop() { 527 | static unsigned long lastPressTime = 0; // Debounce button press 528 | unsigned long currentMillis = millis(); 529 | 530 | // Handle button press for toggling flash and capturing image 531 | if (digitalRead(BUTTON_PIN) == LOW) { 532 | // Check debounce time (ignores multiple button presses in quick succession) 533 | if (currentMillis - lastPressTime > 200) { 534 | lastPressTime = currentMillis; 535 | 536 | 537 | // Proceed with capturing the image 538 | displayLargeCenteredMessage("Capturing Image..."); 539 | captureAndProcessImage(); 540 | } 541 | 542 | // Wait until the button is released to avoid multiple triggers 543 | while (digitalRead(BUTTON_PIN) == LOW) { 544 | delay(10); // Debounce and wait for release 545 | } 546 | } 547 | 548 | // Show live camera feed if not in capture mode and not displaying the response 549 | if (!isCaptureMode && !isResponseDisplayed) { 550 | displayCameraFeed(); 551 | } 552 | 553 | // Check for touch event only after the image and response have been displayed 554 | if (isResponseDisplayed) { 555 | uint16_t touchX = 0, touchY = 0; 556 | if (tft.getTouch(&touchX, &touchY, 600)) { // If touch detected 557 | Serial.println("Touch detected, reinitializing display..."); 558 | reinitializeDisplay(); // Reinitialize display on touch 559 | isResponseDisplayed = false; // Reset the flag after reinitialization 560 | } 561 | } 562 | 563 | lv_task_handler(); // Handle LVGL tasks 564 | delay(5); // Small delay to balance responsiveness and CPU usage 565 | } 566 | 567 | 568 | // Function to handle touchpad input for LVGL 569 | bool my_touchpad_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data) { 570 | uint16_t touchX, touchY; 571 | 572 | bool touched = tft.getTouch(&touchX, &touchY, 600); // Get touch input from the screen, with a threshold of 600 (sensitivity) 573 | 574 | if (!touched) { 575 | data->state = LV_INDEV_STATE_REL; 576 | } else { 577 | data->state = LV_INDEV_STATE_PR; // Set the state as "pressed" (touch detected) 578 | data->point.x = touchX; 579 | data->point.y = touchY; 580 | } 581 | 582 | return false; 583 | } 584 | 585 | 586 | void drawBorders() { 587 | tft.drawRect(78, 2, 324, 246, TFT_WHITE); 588 | tft.drawRect(3, tft.height() - 70, 472, 68, TFT_WHITE); 589 | } 590 | 591 | void displayMessage(const String& message) { 592 | tft.fillRect(5, tft.height() - 65, 464, 60, TFT_BLACK); // Reserve bottom section for messages with black background 593 | tft.setTextColor(TFT_WHITE, TFT_BLACK); // White text on black background 594 | tft.setTextSize(1); 595 | tft.setCursor(5, tft.height() - 65); 596 | 597 | int cursorX = 5, cursorY = tft.height() - 65; 598 | String currentWord; 599 | 600 | for (char c : message) { 601 | if (c == ' ' || c == '\n') { 602 | if (cursorX + tft.textWidth(currentWord) > tft.width() - 5) { 603 | cursorX = 5; 604 | cursorY += 10; 605 | } 606 | if (cursorY >= tft.height() - 5) break; 607 | tft.setCursor(cursorX, cursorY); 608 | tft.print(currentWord); 609 | cursorX += tft.textWidth(currentWord) + tft.textWidth(" "); 610 | currentWord = ""; 611 | } else { 612 | currentWord += c; 613 | } 614 | } 615 | 616 | if (!currentWord.isEmpty()) { 617 | if (cursorX + tft.textWidth(currentWord) > tft.width() - 5) { 618 | cursorX = 5; 619 | cursorY += 10; 620 | } 621 | tft.setCursor(cursorX, cursorY); 622 | tft.print(currentWord); 623 | } 624 | } 625 | 626 | void displayLargeCenteredMessage(const String& message) { 627 | tft.fillRect(0, tft.height() - 70, tft.width(), 70, TFT_BLACK); // Clear the message area with black background 628 | tft.setTextSize(2); 629 | tft.setTextColor(TFT_WHITE, TFT_BLACK); // White text on black background 630 | 631 | int x = (tft.width() - tft.textWidth(message)) / 2; 632 | int y = tft.height() - 50; // Ensure this doesn't overlap with buttons 633 | 634 | tft.setCursor(x, y); 635 | tft.print(message); 636 | drawBorders(); 637 | } 638 | 639 | void beep() { 640 | digitalWrite(3, HIGH); 641 | delay(300); 642 | digitalWrite(3, LOW); 643 | } 644 | -------------------------------------------------------------------------------- /lv_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lv_conf.h 3 | * Configuration file for v7.8.1-dev 4 | */ 5 | 6 | /* 7 | * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER 8 | */ 9 | 10 | #if 1 /*Set it to "1" to enable content*/ 11 | 12 | #ifndef LV_CONF_H 13 | #define LV_CONF_H 14 | /* clang-format off */ 15 | 16 | #include 17 | 18 | /*==================== 19 | Graphical settings 20 | *====================*/ 21 | 22 | /* Maximal horizontal and vertical resolution to support by the library.*/ 23 | #define LV_HOR_RES_MAX (480) 24 | #define LV_VER_RES_MAX (320) 25 | 26 | /* Color depth: 27 | * - 1: 1 byte per pixel 28 | * - 8: RGB332 29 | * - 16: RGB565 30 | * - 32: ARGB8888 31 | */ 32 | #define LV_COLOR_DEPTH 16 33 | 34 | /* Swap the 2 bytes of RGB565 color. 35 | * Useful if the display has a 8 bit interface (e.g. SPI)*/ 36 | #define LV_COLOR_16_SWAP 0 37 | 38 | /* 1: Enable screen transparency. 39 | * Useful for OSD or other overlapping GUIs. 40 | * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ 41 | #define LV_COLOR_SCREEN_TRANSP 0 42 | 43 | /*Images pixels with this color will not be drawn (with chroma keying)*/ 44 | #define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ 45 | 46 | /* Enable anti-aliasing (lines, and radiuses will be smoothed) */ 47 | #define LV_ANTIALIAS 1 48 | 49 | /* Default display refresh period. 50 | * Can be changed in the display driver (`lv_disp_drv_t`).*/ 51 | #define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ 52 | 53 | /* Dot Per Inch: used to initialize default sizes. 54 | * E.g. a button with width = LV_DPI / 2 -> half inch wide 55 | * (Not so important, you can adjust it to modify default sizes and spaces)*/ 56 | #define LV_DPI 130 /*[px]*/ 57 | 58 | /* The the real width of the display changes some default values: 59 | * default object sizes, layout of examples, etc. 60 | * According to the width of the display (hor. res. / dpi) 61 | * the displays fall in 4 categories. 62 | * The 4th is extra large which has no upper limit so not listed here 63 | * The upper limit of the categories are set below in 0.1 inch unit. 64 | */ 65 | #define LV_DISP_SMALL_LIMIT 30 66 | #define LV_DISP_MEDIUM_LIMIT 50 67 | #define LV_DISP_LARGE_LIMIT 70 68 | 69 | /* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ 70 | typedef int16_t lv_coord_t; 71 | 72 | /*========================= 73 | Memory manager settings 74 | *=========================*/ 75 | 76 | /* LittelvGL's internal memory manager's settings. 77 | * The graphical objects and other related data are stored here. */ 78 | 79 | /* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ 80 | #define LV_MEM_CUSTOM 0 81 | #if LV_MEM_CUSTOM == 0 82 | /* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ 83 | # define LV_MEM_SIZE (32U * 1024U) 84 | 85 | /* Compiler prefix for a big array declaration */ 86 | # define LV_MEM_ATTR 87 | 88 | /* Set an address for the memory pool instead of allocating it as an array. 89 | * Can be in external SRAM too. */ 90 | # define LV_MEM_ADR 0 91 | 92 | /* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ 93 | # define LV_MEM_AUTO_DEFRAG 1 94 | #else /*LV_MEM_CUSTOM*/ 95 | # define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ 96 | # define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ 97 | # define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ 98 | #endif /*LV_MEM_CUSTOM*/ 99 | 100 | /* Use the standard memcpy and memset instead of LVGL's own functions. 101 | * The standard functions might or might not be faster depending on their implementation. */ 102 | #define LV_MEMCPY_MEMSET_STD 0 103 | 104 | /* Garbage Collector settings 105 | * Used if lvgl is binded to higher level language and the memory is managed by that language */ 106 | #define LV_ENABLE_GC 0 107 | #if LV_ENABLE_GC != 0 108 | # define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ 109 | # define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ 110 | # define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ 111 | #endif /* LV_ENABLE_GC */ 112 | 113 | /*======================= 114 | Input device settings 115 | *=======================*/ 116 | 117 | /* Input device default settings. 118 | * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ 119 | 120 | /* Input device read period in milliseconds */ 121 | #define LV_INDEV_DEF_READ_PERIOD 30 122 | 123 | /* Drag threshold in pixels */ 124 | #define LV_INDEV_DEF_DRAG_LIMIT 10 125 | 126 | /* Drag throw slow-down in [%]. Greater value -> faster slow-down */ 127 | #define LV_INDEV_DEF_DRAG_THROW 10 128 | 129 | /* Long press time in milliseconds. 130 | * Time to send `LV_EVENT_LONG_PRESSED`) */ 131 | #define LV_INDEV_DEF_LONG_PRESS_TIME 400 132 | 133 | /* Repeated trigger period in long press [ms] 134 | * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ 135 | #define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 136 | 137 | 138 | /* Gesture threshold in pixels */ 139 | #define LV_INDEV_DEF_GESTURE_LIMIT 50 140 | 141 | /* Gesture min velocity at release before swipe (pixels)*/ 142 | #define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 143 | 144 | /*================== 145 | * Feature usage 146 | *==================*/ 147 | 148 | /*1: Enable the Animations */ 149 | #define LV_USE_ANIMATION 1 150 | #if LV_USE_ANIMATION 151 | 152 | /*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ 153 | typedef void * lv_anim_user_data_t; 154 | 155 | #endif 156 | 157 | /* 1: Enable shadow drawing on rectangles*/ 158 | #define LV_USE_SHADOW 1 159 | #if LV_USE_SHADOW 160 | /* Allow buffering some shadow calculation 161 | * LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, 162 | * where shadow size is `shadow_width + radius` 163 | * Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ 164 | #define LV_SHADOW_CACHE_SIZE 0 165 | #endif 166 | 167 | /*1: enable outline drawing on rectangles*/ 168 | #define LV_USE_OUTLINE 1 169 | 170 | /*1: enable pattern drawing on rectangles*/ 171 | #define LV_USE_PATTERN 1 172 | 173 | /*1: enable value string drawing on rectangles*/ 174 | #define LV_USE_VALUE_STR 1 175 | 176 | /* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ 177 | #define LV_USE_BLEND_MODES 1 178 | 179 | /* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/ 180 | #define LV_USE_OPA_SCALE 1 181 | 182 | /* 1: Use image zoom and rotation*/ 183 | #define LV_USE_IMG_TRANSFORM 1 184 | 185 | /* 1: Enable object groups (for keyboard/encoder navigation) */ 186 | #define LV_USE_GROUP 1 187 | #if LV_USE_GROUP 188 | typedef void * lv_group_user_data_t; 189 | #endif /*LV_USE_GROUP*/ 190 | 191 | /* 1: Enable GPU interface*/ 192 | #define LV_USE_GPU 1 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */ 193 | #define LV_USE_GPU_STM32_DMA2D 0 194 | /*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor 195 | e.g. "stm32f769xx.h" or "stm32f429xx.h" */ 196 | #define LV_GPU_DMA2D_CMSIS_INCLUDE 197 | 198 | /*1: Use PXP for CPU off-load on NXP RTxxx platforms */ 199 | #define LV_USE_GPU_NXP_PXP 0 200 | 201 | /*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) 202 | * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS 203 | * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. 204 | *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() 205 | * */ 206 | #define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 207 | 208 | /*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */ 209 | #define LV_USE_GPU_NXP_VG_LITE 0 210 | 211 | /* 1: Enable file system (might be required for images */ 212 | #define LV_USE_FILESYSTEM 1 213 | #if LV_USE_FILESYSTEM 214 | /*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ 215 | typedef void * lv_fs_drv_user_data_t; 216 | #endif 217 | 218 | /*1: Add a `user_data` to drivers and objects*/ 219 | #define LV_USE_USER_DATA 0 220 | 221 | /*1: Show CPU usage and FPS count in the right bottom corner*/ 222 | #define LV_USE_PERF_MONITOR 0 223 | 224 | /*1: Use the functions and types from the older API if possible */ 225 | #define LV_USE_API_EXTENSION_V6 1 226 | #define LV_USE_API_EXTENSION_V7 1 227 | 228 | /*======================== 229 | * Image decoder and cache 230 | *========================*/ 231 | 232 | /* 1: Enable indexed (palette) images */ 233 | #define LV_IMG_CF_INDEXED 1 234 | 235 | /* 1: Enable alpha indexed images */ 236 | #define LV_IMG_CF_ALPHA 1 237 | 238 | /* Default image cache size. Image caching keeps the images opened. 239 | * If only the built-in image formats are used there is no real advantage of caching. 240 | * (I.e. no new image decoder is added) 241 | * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. 242 | * However the opened images might consume additional RAM. 243 | * LV_IMG_CACHE_DEF_SIZE must be >= 1 */ 244 | #define LV_IMG_CACHE_DEF_SIZE 1 245 | 246 | /*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ 247 | typedef void * lv_img_decoder_user_data_t; 248 | 249 | /*===================== 250 | * Compiler settings 251 | *====================*/ 252 | 253 | /* For big endian systems set to 1 */ 254 | #define LV_BIG_ENDIAN_SYSTEM 0 255 | 256 | /* Define a custom attribute to `lv_tick_inc` function */ 257 | #define LV_ATTRIBUTE_TICK_INC 258 | 259 | /* Define a custom attribute to `lv_task_handler` function */ 260 | #define LV_ATTRIBUTE_TASK_HANDLER 261 | 262 | /* Define a custom attribute to `lv_disp_flush_ready` function */ 263 | #define LV_ATTRIBUTE_FLUSH_READY 264 | 265 | /* Required alignment size for buffers */ 266 | #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 267 | 268 | /* With size optimization (-Os) the compiler might not align data to 269 | * 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes. 270 | * This alignment will be explicitly applied where needed. 271 | * LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size. 272 | * E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */ 273 | #define LV_ATTRIBUTE_MEM_ALIGN 274 | 275 | /* Attribute to mark large constant arrays for example 276 | * font's bitmaps */ 277 | #define LV_ATTRIBUTE_LARGE_CONST 278 | 279 | /* Prefix performance critical functions to place them into a faster memory (e.g RAM) 280 | * Uses 15-20 kB extra memory */ 281 | #define LV_ATTRIBUTE_FAST_MEM 282 | 283 | /* Export integer constant to binding. 284 | * This macro is used with constants in the form of LV_ that 285 | * should also appear on lvgl binding API such as Micropython 286 | * 287 | * The default value just prevents a GCC warning. 288 | */ 289 | #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning 290 | 291 | /* Prefix variables that are used in GPU accelerated operations, often these need to be 292 | * placed in RAM sections that are DMA accessible */ 293 | #define LV_ATTRIBUTE_DMA 294 | 295 | /*=================== 296 | * HAL settings 297 | *==================*/ 298 | 299 | /* 1: use a custom tick source. 300 | * It removes the need to manually update the tick with `lv_tick_inc`) */ 301 | #define LV_TICK_CUSTOM 1 302 | #if LV_TICK_CUSTOM == 1 303 | #define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ 304 | #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ 305 | #endif /*LV_TICK_CUSTOM*/ 306 | 307 | typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ 308 | typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ 309 | 310 | /*================ 311 | * Log settings 312 | *===============*/ 313 | 314 | /*1: Enable the log module*/ 315 | #define LV_USE_LOG 0 316 | #if LV_USE_LOG 317 | /* How important log should be added: 318 | * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information 319 | * LV_LOG_LEVEL_INFO Log important events 320 | * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem 321 | * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail 322 | * LV_LOG_LEVEL_NONE Do not log anything 323 | */ 324 | # define LV_LOG_LEVEL LV_LOG_LEVEL_WARN 325 | 326 | /* 1: Print the log with 'printf'; 327 | * 0: user need to register a callback with `lv_log_register_print_cb`*/ 328 | # define LV_LOG_PRINTF 0 329 | #endif /*LV_USE_LOG*/ 330 | 331 | /*================= 332 | * Debug settings 333 | *================*/ 334 | 335 | /* If Debug is enabled LittelvGL validates the parameters of the functions. 336 | * If an invalid parameter is found an error log message is printed and 337 | * the MCU halts at the error. (`LV_USE_LOG` should be enabled) 338 | * If you are debugging the MCU you can pause 339 | * the debugger to see exactly where the issue is. 340 | * 341 | * The behavior of asserts can be overwritten by redefining them here. 342 | * E.g. #define LV_ASSERT_MEM(p) 343 | */ 344 | #define LV_USE_DEBUG 1 345 | #if LV_USE_DEBUG 346 | 347 | /*Check if the parameter is NULL. (Quite fast) */ 348 | #define LV_USE_ASSERT_NULL 1 349 | 350 | /*Checks is the memory is successfully allocated or no. (Quite fast)*/ 351 | #define LV_USE_ASSERT_MEM 1 352 | 353 | /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ 354 | #define LV_USE_ASSERT_MEM_INTEGRITY 0 355 | 356 | /* Check the strings. 357 | * Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow) 358 | * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ 359 | #define LV_USE_ASSERT_STR 0 360 | 361 | /* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow) 362 | * If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */ 363 | #define LV_USE_ASSERT_OBJ 0 364 | 365 | /*Check if the styles are properly initialized. (Fast)*/ 366 | #define LV_USE_ASSERT_STYLE 0 367 | 368 | #endif /*LV_USE_DEBUG*/ 369 | 370 | /*================== 371 | * FONT USAGE 372 | *===================*/ 373 | 374 | /* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. 375 | * The symbols are available via `LV_SYMBOL_...` defines 376 | * More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html 377 | * To create a new font go to: https://lvgl.com/ttf-font-to-c-array 378 | */ 379 | 380 | /* Montserrat fonts with bpp = 4 381 | * https://fonts.google.com/specimen/Montserrat */ 382 | #define LV_FONT_MONTSERRAT_8 0 383 | #define LV_FONT_MONTSERRAT_10 0 384 | #define LV_FONT_MONTSERRAT_12 0 385 | #define LV_FONT_MONTSERRAT_14 1 386 | #define LV_FONT_MONTSERRAT_16 0 387 | #define LV_FONT_MONTSERRAT_18 0 388 | #define LV_FONT_MONTSERRAT_20 0 389 | #define LV_FONT_MONTSERRAT_22 0 390 | #define LV_FONT_MONTSERRAT_24 0 391 | #define LV_FONT_MONTSERRAT_26 0 392 | #define LV_FONT_MONTSERRAT_28 0 393 | #define LV_FONT_MONTSERRAT_30 0 394 | #define LV_FONT_MONTSERRAT_32 0 395 | #define LV_FONT_MONTSERRAT_34 0 396 | #define LV_FONT_MONTSERRAT_36 0 397 | #define LV_FONT_MONTSERRAT_38 0 398 | #define LV_FONT_MONTSERRAT_40 0 399 | #define LV_FONT_MONTSERRAT_42 0 400 | #define LV_FONT_MONTSERRAT_44 0 401 | #define LV_FONT_MONTSERRAT_46 0 402 | #define LV_FONT_MONTSERRAT_48 0 403 | 404 | /* Demonstrate special features */ 405 | #define LV_FONT_MONTSERRAT_12_SUBPX 0 406 | #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ 407 | #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/ 408 | #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ 409 | 410 | /*Pixel perfect monospace font 411 | * http://pelulamu.net/unscii/ */ 412 | #define LV_FONT_UNSCII_8 0 413 | #define LV_FONT_UNSCII_16 0 414 | 415 | /* Optionally declare your custom fonts here. 416 | * You can use these fonts as default font too 417 | * and they will be available globally. E.g. 418 | * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ 419 | * LV_FONT_DECLARE(my_font_2) 420 | */ 421 | #define LV_FONT_CUSTOM_DECLARE 422 | 423 | /* Enable it if you have fonts with a lot of characters. 424 | * The limit depends on the font size, font face and bpp 425 | * but with > 10,000 characters if you see issues probably you need to enable it.*/ 426 | #define LV_FONT_FMT_TXT_LARGE 0 427 | 428 | /* Enables/disables support for compressed fonts. If it's disabled, compressed 429 | * glyphs cannot be processed by the library and won't be rendered. 430 | */ 431 | #define LV_USE_FONT_COMPRESSED 1 432 | 433 | /* Enable subpixel rendering */ 434 | #define LV_USE_FONT_SUBPX 1 435 | #if LV_USE_FONT_SUBPX 436 | /* Set the pixel order of the display. 437 | * Important only if "subpx fonts" are used. 438 | * With "normal" font it doesn't matter. 439 | */ 440 | #define LV_FONT_SUBPX_BGR 0 441 | #endif 442 | 443 | /*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ 444 | typedef void * lv_font_user_data_t; 445 | 446 | /*================ 447 | * THEME USAGE 448 | *================*/ 449 | 450 | /*Always enable at least on theme*/ 451 | 452 | /* No theme, you can apply your styles as you need 453 | * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ 454 | #define LV_USE_THEME_EMPTY 1 455 | 456 | /*Simple to the create your theme based on it 457 | * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ 458 | #define LV_USE_THEME_TEMPLATE 1 459 | 460 | /* A fast and impressive theme. 461 | * Flags: 462 | * LV_THEME_MATERIAL_FLAG_LIGHT: light theme 463 | * LV_THEME_MATERIAL_FLAG_DARK: dark theme 464 | * LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations) 465 | * LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state) 466 | * */ 467 | #define LV_USE_THEME_MATERIAL 1 468 | 469 | /* Mono-color theme for monochrome displays. 470 | * If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the 471 | * texts and borders will be black and the background will be 472 | * white. Else the colors are inverted. 473 | * No flags. Set LV_THEME_DEFAULT_FLAG 0 */ 474 | #define LV_USE_THEME_MONO 1 475 | 476 | #define LV_THEME_DEFAULT_INCLUDE /*Include a header for the init. function*/ 477 | #define LV_THEME_DEFAULT_INIT lv_theme_material_init 478 | #define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0x01a2b1) 479 | #define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0x44d1b6) 480 | #define LV_THEME_DEFAULT_FLAG LV_THEME_MATERIAL_FLAG_LIGHT 481 | #define LV_THEME_DEFAULT_FONT_SMALL &lv_font_montserrat_14 482 | #define LV_THEME_DEFAULT_FONT_NORMAL &lv_font_montserrat_14 483 | #define LV_THEME_DEFAULT_FONT_SUBTITLE &lv_font_montserrat_14 484 | #define LV_THEME_DEFAULT_FONT_TITLE &lv_font_montserrat_14 485 | 486 | /*================= 487 | * Text settings 488 | *=================*/ 489 | 490 | /* Select a character encoding for strings. 491 | * Your IDE or editor should have the same character encoding 492 | * - LV_TXT_ENC_UTF8 493 | * - LV_TXT_ENC_ASCII 494 | * */ 495 | #define LV_TXT_ENC LV_TXT_ENC_UTF8 496 | 497 | /*Can break (wrap) texts on these chars*/ 498 | #define LV_TXT_BREAK_CHARS " ,.;:-_" 499 | 500 | /* If a word is at least this long, will break wherever "prettiest" 501 | * To disable, set to a value <= 0 */ 502 | #define LV_TXT_LINE_BREAK_LONG_LEN 0 503 | 504 | /* Minimum number of characters in a long word to put on a line before a break. 505 | * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ 506 | #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 507 | 508 | /* Minimum number of characters in a long word to put on a line after a break. 509 | * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ 510 | #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 511 | 512 | /* The control character to use for signalling text recoloring. */ 513 | #define LV_TXT_COLOR_CMD "#" 514 | 515 | /* Support bidirectional texts. 516 | * Allows mixing Left-to-Right and Right-to-Left texts. 517 | * The direction will be processed according to the Unicode Bidirectional Algorithm: 518 | * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ 519 | #define LV_USE_BIDI 0 520 | #if LV_USE_BIDI 521 | /* Set the default direction. Supported values: 522 | * `LV_BIDI_DIR_LTR` Left-to-Right 523 | * `LV_BIDI_DIR_RTL` Right-to-Left 524 | * `LV_BIDI_DIR_AUTO` detect texts base direction */ 525 | #define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO 526 | #endif 527 | 528 | /* Enable Arabic/Persian processing 529 | * In these languages characters should be replaced with 530 | * an other form based on their position in the text */ 531 | #define LV_USE_ARABIC_PERSIAN_CHARS 0 532 | 533 | /*Change the built in (v)snprintf functions*/ 534 | #define LV_SPRINTF_CUSTOM 0 535 | #if LV_SPRINTF_CUSTOM 536 | # define LV_SPRINTF_INCLUDE 537 | # define lv_snprintf snprintf 538 | # define lv_vsnprintf vsnprintf 539 | #else /*!LV_SPRINTF_CUSTOM*/ 540 | # define LV_SPRINTF_DISABLE_FLOAT 1 541 | #endif /*LV_SPRINTF_CUSTOM*/ 542 | 543 | /*=================== 544 | * LV_OBJ SETTINGS 545 | *==================*/ 546 | 547 | #if LV_USE_USER_DATA 548 | /*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ 549 | typedef void * lv_obj_user_data_t; 550 | /*Provide a function to free user data*/ 551 | #define LV_USE_USER_DATA_FREE 0 552 | #if LV_USE_USER_DATA_FREE 553 | # define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/ 554 | /* Function prototype : void user_data_free(lv_obj_t * obj); */ 555 | # define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/ 556 | #endif 557 | #endif 558 | 559 | /*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/ 560 | #define LV_USE_OBJ_REALIGN 1 561 | 562 | /* Enable to make the object clickable on a larger area. 563 | * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature 564 | * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) 565 | * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) 566 | */ 567 | #define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY 568 | 569 | /*================== 570 | * LV OBJ X USAGE 571 | *================*/ 572 | /* 573 | * Documentation of the object types: https://docs.lvgl.com/#Object-types 574 | */ 575 | 576 | /*Arc (dependencies: -)*/ 577 | #define LV_USE_ARC 1 578 | 579 | /*Bar (dependencies: -)*/ 580 | #define LV_USE_BAR 1 581 | 582 | /*Button (dependencies: lv_cont*/ 583 | #define LV_USE_BTN 1 584 | 585 | /*Button matrix (dependencies: -)*/ 586 | #define LV_USE_BTNMATRIX 1 587 | 588 | /*Calendar (dependencies: -)*/ 589 | #define LV_USE_CALENDAR 1 590 | #if LV_USE_CALENDAR 591 | # define LV_CALENDAR_WEEK_STARTS_MONDAY 0 592 | #endif 593 | 594 | /*Canvas (dependencies: lv_img)*/ 595 | #define LV_USE_CANVAS 1 596 | 597 | /*Check box (dependencies: lv_btn, lv_label)*/ 598 | #define LV_USE_CHECKBOX 1 599 | 600 | /*Chart (dependencies: -)*/ 601 | #define LV_USE_CHART 1 602 | #if LV_USE_CHART 603 | # define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256 604 | #endif 605 | 606 | /*Container (dependencies: -*/ 607 | #define LV_USE_CONT 1 608 | 609 | /*Color picker (dependencies: -*/ 610 | #define LV_USE_CPICKER 1 611 | 612 | /*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ 613 | #define LV_USE_DROPDOWN 1 614 | #if LV_USE_DROPDOWN != 0 615 | /*Open and close default animation time [ms] (0: no animation)*/ 616 | # define LV_DROPDOWN_DEF_ANIM_TIME 200 617 | #endif 618 | 619 | /*Gauge (dependencies:lv_bar, lv_linemeter)*/ 620 | #define LV_USE_GAUGE 1 621 | 622 | /*Image (dependencies: lv_label*/ 623 | #define LV_USE_IMG 1 624 | 625 | /*Image Button (dependencies: lv_btn*/ 626 | #define LV_USE_IMGBTN 1 627 | #if LV_USE_IMGBTN 628 | /*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ 629 | # define LV_IMGBTN_TILED 0 630 | #endif 631 | 632 | /*Keyboard (dependencies: lv_btnm)*/ 633 | #define LV_USE_KEYBOARD 1 634 | 635 | /*Label (dependencies: -*/ 636 | #define LV_USE_LABEL 1 637 | #if LV_USE_LABEL != 0 638 | /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ 639 | # define LV_LABEL_DEF_SCROLL_SPEED 25 640 | 641 | /* Waiting period at beginning/end of animation cycle */ 642 | # define LV_LABEL_WAIT_CHAR_COUNT 3 643 | 644 | /*Enable selecting text of the label */ 645 | # define LV_LABEL_TEXT_SEL 0 646 | 647 | /*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ 648 | # define LV_LABEL_LONG_TXT_HINT 0 649 | #endif 650 | 651 | /*LED (dependencies: -)*/ 652 | #define LV_USE_LED 1 653 | #if LV_USE_LED 654 | # define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/ 655 | # define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/ 656 | #endif 657 | 658 | /*Line (dependencies: -*/ 659 | #define LV_USE_LINE 1 660 | 661 | /*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ 662 | #define LV_USE_LIST 1 663 | #if LV_USE_LIST != 0 664 | /*Default animation time of focusing to a list element [ms] (0: no animation) */ 665 | # define LV_LIST_DEF_ANIM_TIME 100 666 | #endif 667 | 668 | /*Line meter (dependencies: *;)*/ 669 | #define LV_USE_LINEMETER 1 670 | #if LV_USE_LINEMETER 671 | /* Draw line more precisely at cost of performance. 672 | * Useful if there are lot of lines any minor are visible 673 | * 0: No extra precision 674 | * 1: Some extra precision 675 | * 2: Best precision 676 | */ 677 | # define LV_LINEMETER_PRECISE 1 678 | #endif 679 | 680 | /*Mask (dependencies: -)*/ 681 | #define LV_USE_OBJMASK 1 682 | 683 | /*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ 684 | #define LV_USE_MSGBOX 1 685 | 686 | /*Page (dependencies: lv_cont)*/ 687 | #define LV_USE_PAGE 1 688 | #if LV_USE_PAGE != 0 689 | /*Focus default animation time [ms] (0: no animation)*/ 690 | # define LV_PAGE_DEF_ANIM_TIME 400 691 | #endif 692 | 693 | /*Preload (dependencies: lv_arc, lv_anim)*/ 694 | #define LV_USE_SPINNER 1 695 | #if LV_USE_SPINNER != 0 696 | # define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/ 697 | # define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/ 698 | # define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC 699 | #endif 700 | 701 | /*Roller (dependencies: lv_ddlist)*/ 702 | #define LV_USE_ROLLER 1 703 | #if LV_USE_ROLLER != 0 704 | /*Focus animation time [ms] (0: no animation)*/ 705 | # define LV_ROLLER_DEF_ANIM_TIME 200 706 | 707 | /*Number of extra "pages" when the roller is infinite*/ 708 | # define LV_ROLLER_INF_PAGES 7 709 | #endif 710 | 711 | /*Slider (dependencies: lv_bar)*/ 712 | #define LV_USE_SLIDER 1 713 | 714 | /*Spinbox (dependencies: lv_ta)*/ 715 | #define LV_USE_SPINBOX 1 716 | 717 | /*Switch (dependencies: lv_slider)*/ 718 | #define LV_USE_SWITCH 1 719 | 720 | /*Text area (dependencies: lv_label, lv_page)*/ 721 | #define LV_USE_TEXTAREA 1 722 | #if LV_USE_TEXTAREA != 0 723 | # define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ 724 | # define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ 725 | #endif 726 | 727 | /*Table (dependencies: lv_label)*/ 728 | #define LV_USE_TABLE 1 729 | #if LV_USE_TABLE 730 | # define LV_TABLE_COL_MAX 12 731 | # define LV_TABLE_CELL_STYLE_CNT 4 732 | #endif 733 | 734 | 735 | /*Tab (dependencies: lv_page, lv_btnm)*/ 736 | #define LV_USE_TABVIEW 1 737 | # if LV_USE_TABVIEW != 0 738 | /*Time of slide animation [ms] (0: no animation)*/ 739 | # define LV_TABVIEW_DEF_ANIM_TIME 300 740 | #endif 741 | 742 | /*Tileview (dependencies: lv_page) */ 743 | #define LV_USE_TILEVIEW 1 744 | #if LV_USE_TILEVIEW 745 | /*Time of slide animation [ms] (0: no animation)*/ 746 | # define LV_TILEVIEW_DEF_ANIM_TIME 300 747 | #endif 748 | 749 | /*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ 750 | #define LV_USE_WIN 1 751 | 752 | /*================== 753 | * Non-user section 754 | *==================*/ 755 | 756 | #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ 757 | # define _CRT_SECURE_NO_WARNINGS 758 | #endif 759 | 760 | /*--END OF LV_CONF_H--*/ 761 | 762 | #endif /*LV_CONF_H*/ 763 | 764 | #endif /*End of "Content enable"*/ 765 | --------------------------------------------------------------------------------