LCD1602 not initializing properly
Posted: Fri Aug 16, 2024 5:52 am
I am writing a I2C Driver for the LCD1602 (with PCF8574) Module when connected to ESP32. I have read the I2C Seciion of the ESP32 Datasheet to understand the working of it in ESP32. I am using the 'i2c.h' inside the driver folder as the Hardware Abstraction Layer in my custom driver. So, I also have gone through the datasheet of the LCD1602 and PCF8574 to understand the peripheral allocation and timing constraints. Before you can send any data to be displayed on the LCD, it needs to be initilaized by sending it commands. The PCF8574 is a 8-bit I/O expander. However, the LCD1602 only operated in 4-bit, hence we need some set of commands for the LCD's initialization. I think my initialization maybe is not working correctly which I am unable to find why. Here is the snippet of my code:
Resources Used:
1.) ESP32 (I2C) : https://docs.espressif.com/projects/esp ... s/i2c.html
2.) PCF8574 Datasheet: "https://www.ti.com/lit/ds/symlink/pcf8574.pdf"
3.) LCD1602 Datasheet: "https://www.waveshare.com/datasheet/LCD ... CD1602.pdf"
- [code]#include <stdio.h>
- #include "driver/i2c.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "esp_intr_alloc.h"
- #include "esp_rom_sys.h"
- #define En 0b00000100 //Defining enable bit, 1<<2
- void i2c_Scan();
- void screen_init();
- void command(uint8_t data);
- void data_send(uint8_t data);
- void write_to_expander(uint8_t data);
- void strobe_enable(uint8_t data);
- uint8_t blVAL= 0x00;
- void app_main(void)
- {
- vTaskDelay(15 / portTICK_PERIOD_MS);
- i2c_Scan();
- }
- void i2c_Scan(){
- i2c_config_t conf = {0} ;
- conf.mode = I2C_MODE_MASTER;
- conf.sda_io_num = 21;
- conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
- conf.scl_io_num = 22;
- conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
- conf.master.clk_speed = 100000;
- i2c_param_config(I2C_NUM_0,&conf);
- i2c_driver_install(I2C_NUM_0,conf.mode,0,0,0);
- printf("Let's start the i2c communication \n");
- screen_init();
- }
- void screen_init(){
- vTaskDelay(15 / portTICK_PERIOD_MS);
- command(0x30); ///Interface is 8-bit
- vTaskDelay(4.1/portTICK_PERIOD_MS);
- command(0x30); //Interface is 8-bit
- esp_rom_delay_us(100);
- command(0x30); //Interface is 8-bit
- esp_rom_delay_us(150);
- command(0x20); //Interface is 4-bit
- command(0x28); //Setting Display Line and font size
- command(0x0c); //Display Set On, Cursor Off
- command(0x01); //Clear Display
- vTaskDelay(2/ portTICK_PERIOD_MS); //This extra delay is for Clearing
- command(0x06); //Set moving direction of cursor
- vTaskDelay(2/ portTICK_PERIOD_MS);
- blVAL = 0x01; //Turning backlight On
- command(0x02); //Cursor Return to Home.
- vTaskDelay(2/ portTICK_PERIOD_MS);
- }
- void command(uint8_t data){
- uint8_t top4 = (data & 0xf0);
- uint8_t bottom4 = ((data & 0x0f)<<4);
- //write_to_expander(top4);
- strobe_enable(top4);
- //write_to_expander(bottom4);
- strobe_enable(bottom4);
- }
- void strobe_enable(uint8_t data){
- write_to_expander(((data | En) | blVAL<<3));
- esp_rom_delay_us(1);
- write_to_expander(((data & (~En)) | blVAL<<3));
- esp_rom_delay_us(50);
- }
- void write_to_expander(uint8_t data){
- //Command is enable here and timed for 1000ns
- i2c_cmd_handle_t cmd = i2c_cmd_link_create();
- i2c_master_start(cmd);
- i2c_master_write_byte(cmd,(0x27<<1)|0,true);
- i2c_master_write_byte(cmd,data,true);
- i2c_master_stop(cmd);
- esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0,cmd,10/portTICK_PERIOD_MS);
- i2c_cmd_link_delete(cmd);
- if(ret == ESP_OK){
- printf("The i2c command has begun.\n");
- }
- }
- void data_send(uint8_t data){
- uint8_t top4 = (data & 0xf0);
- uint8_t bottom4 = ((data & 0x0f)<<4);
- write_to_expander(top4 | 1<<0);
- write_to_expander(bottom4 | 1<< 0);
- }[/code]
1.) ESP32 (I2C) : https://docs.espressif.com/projects/esp ... s/i2c.html
2.) PCF8574 Datasheet: "https://www.ti.com/lit/ds/symlink/pcf8574.pdf"
3.) LCD1602 Datasheet: "https://www.waveshare.com/datasheet/LCD ... CD1602.pdf"