In this post, I will tell you, how to interface ILI9341 with ESP32, and then I will use the DHT11 sensor to get the temperature and humidity data and plot this data on the ILI9341display, but for plotting I will be using "lv_chart" objects provided by LVGL, LVGL stands for Light and Versatile Embedded Graphics Library, this is the most popular free and open-source embedded graphics library to create beautiful UIs for any MCU, MPU and display type.
Temperature and Humidity Graph using ESP32 and ILI9341
We will do the same thing which we have done in the post on STM32 and LVGL integration, and if you compare both the code you can see that basically there is very less difference. So, in this project, we will do the following.
Display VIBGYOR Colors for 4 seconds
Display Red, Green, and Blue Sliders, and by changing the value of these sliders, the rectangle color is updated
Once all slider value reaches 255 value the software switches to the next screen.
In this screen, the temperature and humidity values taken from the DHT11 sensor are plotted on the graph using the "lv_chart" object.
The difference between the previous post and this post is that here I will be plotting temperature and humidity data, while in the previous post, I was just plotting the temperature value.
Project Setup
For this project, I will be using Arduino framework for ESP32, but instead of using Arduino IDE, I will be using PlatformIO with Visual Studio Code, as it has more advantages as compared to Arduino IDE, and for me, the following are some of the main advantages.
PlatformIO with Visual Studio Code Extension is much faster in compiling the code as compared to the Arduino IDE (I don't the exact reason, but I read somewhere that PlatformIO utilizes all cores of our processor, I don't know how true this statement is, but for me, it is absolutely much faster)
The auto-Completion feature is missing in Arduino IDE
Libraries are added to individual projects rather than to all projects.
In PlatformIO whenever we add a library it is added to only that project, and all the changes done to our project are specific to our project, while for Arduino IDE, if we have to customize something we have to do that in the libraries folder and that usually creates a mess in most of the cases, this project is also an example of this, because here also we have to modify some of the library files.
We can see the content of the Library just inside the Visual Studio Code, which is not available on Arduino IDE
The schematic diagram or connection diagram for this project is as below.
Connection Diagram
From the above picture, the pinout is not visible properly, so you use the below-mentioned table for the connections.
ESP32 ILI9341 DHT11 Pin Out
After doing this, we have to install three libraries, one is for the DHT11 sensor, the second is for SPI communication and the other one is the LVGL library, this can be done by going into the PlatformIO libraries section.
Install DHT11 Sensor Library.
Installing DHT11 Sensor Library
Install the TFT_eSPI library by Bodmer.
Install LVGL Library by LVGL.
Install LVGL Library
Once all three libraries are installed the "platformio.ini" file will look something like this.
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps =
lvgl/lvgl@^8.3.4
bodmer/TFT_eSPI@^2.4.79
adafruit/Adafruit Unified Sensor@^1.1.7
adafruit/DHT sensor library@^1.4.4
monitor_speed = 115200
Configuring SPI
The "TFT_eSPI" library is a generic library, and we have to configure this library for our project as per the connections.
If PlatformIO is used, then this library is present inside the "*.pio" folder as shown in the below image.
TFT_eSPI Library with PlatformIO
And if Arduino IDE is used then this library is usually installed under the "Arduino\libraries\TFT_eSPI" path, as shown in the below image.
TFT_eSPI Library with Arduino IDE
In both cases, we have to modify the "User_Setup.h" file, as shown below.
First select the correct driver, in my case it is "ILI9341_DRIVER"
// Only define one driver, the other ones must be commented out
#defineILI9341_DRIVER // Generic driver for common displays
//#define ILI9341_2_DRIVER // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
//#define ST7735_DRIVER // Define additional parameters below for this display
//#define ILI9163_DRIVER // Define additional parameters below for this display
//#define S6D02A1_DRIVER
The second step is to configure the SPI pins, as shown below.
#defineTFT_RST-1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
If on the hardware, if you have connected the "TFT_RST" with some ESP32 pin, then specify that pin here, else specify "-1" as I have done in my case.
The next step is to specify the Touch Chip Select pin, which in my case is "2" pin.
#defineTOUCH_CS2 // Chip select pin (T_CS) of touch screen
Note: You can change "TFT_CS" which is the chip select pin, "TFT_DC" pin which is TFT Data or Command Mode control signal pin, "TFT_RST" pin which is the reset pin, and "TOUCH_CS" which is Touch Chip Select Pin, but for SPI pins always select the pins specified here.
Make sure this piece of code is also like this.
#defineLOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#defineLOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#defineLOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#defineLOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#defineLOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#defineLOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#defineLOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#defineSMOOTH_FONT
And then configure the SPI Frequency to be used, for TFT I am using 40MHz, for Reading 20MHz and for Touch 25MHz, as shown below.
// Define the SPI clock frequency, this affects the graphics rendering speed. Too
// fast and the TFT driver will not keep up and display corruption appears.
// With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
// With an ILI9163 display 27 MHz works OK.
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 27000000
#defineSPI_FREQUENCY40000000
// #define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY 80000000
// Optional reduced SPI frequency for reading TFT
#defineSPI_READ_FREQUENCY20000000
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#defineSPI_TOUCH_FREQUENCY2500000
Calibrating Touch
Once the above step is done, the next step is to get the calibration data for the Touch Screen, which can be get easily by using the Example Sketch. The path of this example sketch is as follows.
Examples\TFT_eSPI\Generic\Touch_calibrate
And the touch calibration project is as below.
/*
Sketch to generate the setup() calibration values, these are reported
to the Serial Monitor.
The sketch has been tested on the ESP8266 and screen with XPT2046 driver.
Then we can configure the memory allocated to lvgl, which should be greater than 2 kilobytes as shown below it is set to 48 kilobytes.
/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
#defineLV_MEM_CUSTOM0
#ifLV_MEM_CUSTOM==0
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
#defineLV_MEM_SIZE (48U * 1024U) /*[bytes]*/
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#defineLV_MEM_ADR0 /*0: unused*/
/*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
#ifLV_MEM_ADR==0
#undef LV_MEM_POOL_INCLUDE
#undef LV_MEM_POOL_ALLOC
#endif
#else /*LV_MEM_CUSTOM*/
Then the next step is to configure the tick source, I will set it to 1 for Arduino-based platforms as shown below. This removes the need to manually update the tick with the function call "lv_tick_inc".
/*Use a custom tick source that tells the elapsed time in milliseconds.
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
#defineLV_TICK_CUSTOM1
#ifLV_TICK_CUSTOM
#defineLV_TICK_CUSTOM_INCLUDE"Arduino.h" /*Header for the system time function*/
#defineLV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
#endif /*LV_TICK_CUSTOM*/
This step is optional, by setting LV_USE_LOG, we can log different types of the log messages, at the moment I have set it to "LV_LOG_LEVEL_WARN".
#defineLV_USE_LOG1
#ifLV_USE_LOG
/*How important log should be added:
*LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
*LV_LOG_LEVEL_INFO Log important events
*LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/
#defineLV_LOG_LEVEL LV_LOG_LEVEL_WARN
/*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/
#defineLV_LOG_PRINTF0
/*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
#defineLV_LOG_TRACE_MEM1
#defineLV_LOG_TRACE_TIMER1
#defineLV_LOG_TRACE_INDEV1
#defineLV_LOG_TRACE_DISP_REFR1
#defineLV_LOG_TRACE_EVENT1
#defineLV_LOG_TRACE_OBJ_CREATE1
#defineLV_LOG_TRACE_LAYOUT1
#defineLV_LOG_TRACE_ANIM1
#endif /*LV_USE_LOG*/
And finally, we can enable and disable the fonts as shown below, I have enabled MONTSERRAT_12, 14, and 16 fonts. Again this is an optional step.
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
I have shown the important and tricky configuration steps, and the rest of the part is really simple just copy and paste after running the above code from GitHub you will see the following screens on the display.
No comments:
Post a Comment