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: Untitled.c Select all
[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"