Programming i2c lcd and esp32

I’m trying to display sensor readings on my 20x4 I2C LCD using an ESP32. I have two push buttons connected with external pull-up resistors. The goal is that when I press the “Next” button, the LCD should switch to displaying readings from other sensors.

However, the system only works correctly for a few seconds. After that, the sensor readings start showing negative values unexpectedly. I’m confident that my circuit is correct. I’m using a PCF8574 I2C module, powered from the ESP32’s onboard 3.3V supply.

Below is my code:

// ========================================
// COMBINED SENSOR DISPLAY WITH NAVIGATION
// MQ7 Gas Sensor + BMP280 + LCD 20x4
// ========================================

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <LiquidCrystal_I2C.h>

// ========================================
// PIN CONFIGURATION
// ========================================
#define SDA_PIN 21
#define SCL_PIN 22
#define BUTTON_NEXT 16    // Next button pin
#define BUTTON_BACK 17    // Back button pin
#define MQ7_PIN 36        // MQ7 analog pin

// ========================================
// SENSOR SETTINGS
// ========================================
#define SEA_LEVEL_PRESSURE_HPA 1013.25

// ========================================
// HARDWARE OBJECTS
// ========================================
Adafruit_BMP085 bmp;              // BMP280/BMP180 sensor
LiquidCrystal_I2C lcd(0x27, 20, 4); // 20x4 LCD

// ========================================
// BUTTON VARIABLES
// ========================================
int buttonNextState = 0;
int buttonBackState = 0;
int lastButtonNextState = 0;
int lastButtonBackState = 0;
int currentScreen = 0;  // Current display screen
int totalScreens = 2;   // Total number of screens

// ========================================
// HELPER FUNCTION: Display text on LCD
// ========================================
void printLine(uint8_t row, const char *text) {
  char buffer[21];
  snprintf(buffer, sizeof(buffer), "%-20s", text);
  lcd.setCursor(0, row);
  lcd.print(buffer);
}

// ========================================
// SETUP: Initialize hardware
// ========================================
void setup() {
  // Start serial communication
  Serial.begin(115200);
  
  // Setup button pins
  pinMode(BUTTON_NEXT, INPUT);
  pinMode(BUTTON_BACK, INPUT);
  
  // Initialize I2C with custom pins
  Wire.begin(SDA_PIN, SCL_PIN);
  Wire.setClock(10000);
  
  // Initialize LCD
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  
  // Display startup message
  printLine(0, "Sensor Monitor");
  printLine(1, "Initializing...");
  
  // Check if BMP sensor is connected
  if (!bmp.begin()) {
    printLine(2, "BMP280 NOT FOUND!");
    printLine(3, "Check connections");
    while (1); // Halt if sensor not found
  }
  
  printLine(2, "BMP280: OK");
  printLine(3, "MQ7: Ready");
  delay(2000);
  lcd.clear();
}

// ========================================
// MAIN LOOP: Handle buttons and display
// ========================================
void loop() {
  // Read button states
  buttonNextState = digitalRead(BUTTON_NEXT);
  buttonBackState = digitalRead(BUTTON_BACK);
  
  // Check NEXT button press
  if (buttonNextState != lastButtonNextState) {
    if (buttonNextState == HIGH) {
      currentScreen++;
      if (currentScreen >= totalScreens) {
        currentScreen = 0; // Wrap to first screen
      }
      lcd.clear();
      delay(50); // Debounce
    }
  }
  lastButtonNextState = buttonNextState;
  
  // Check BACK button press
  if (buttonBackState != lastButtonBackState) {
    if (buttonBackState == HIGH) {
      currentScreen--;
      if (currentScreen < 0) {
        currentScreen = totalScreens - 1; // Wrap to last screen
      }
      lcd.clear();
      delay(50); // Debounce
    }
  }
  lastButtonBackState = buttonBackState;
  
  // Display current screen
  displayScreen();
  
  // Update delay
  delay(500);
}

// ========================================
// DISPLAY FUNCTION: Show current screen
// ========================================
void displayScreen() {
  char displayText[21];
  
  if (currentScreen == 0) {
    // ====================================
    // SCREEN 1: BMP280 Data
    // ====================================
    float temperature = bmp.readTemperature();
    long pressurePascals = bmp.readPressure();
    float pressureHpa = pressurePascals / 100.0;
    float altitude = bmp.readAltitude(SEA_LEVEL_PRESSURE_HPA * 100);
    
    // Display header
    printLine(0, "=== BMP280 Data ===");
    
    // Temperature
    snprintf(displayText, sizeof(displayText), "Temp: %.1f%cC", temperature, 223);
    printLine(1, displayText);
    
    // Pressure
    snprintf(displayText, sizeof(displayText), "Press: %.1f hPa", pressureHpa);
    printLine(2, displayText);
    
    // Altitude
    snprintf(displayText, sizeof(displayText), "Alt: %.1f m", altitude);
    printLine(3, displayText);
    
  } else if (currentScreen == 1) {
    // ====================================
    // SCREEN 2: MQ7 Gas Sensor Data
    // ====================================
    int coValue = analogRead(MQ7_PIN);
    
    // Display header
    printLine(0, "==== MQ7 Sensor ====");
    
    // CO reading
    snprintf(displayText, sizeof(displayText), "CO Level: %d", coValue);
    printLine(1, displayText);
    
    // Status based on threshold
    if (coValue < 400) {
      printLine(2, "Status: SAFE");
    } else if (coValue < 800) {
      printLine(2, "Status: WARNING");
    } else {
      printLine(2, "Status: DANGER!");
    }
    
    // Navigation hint
    printLine(3, "Next/Back to navigate");
  }
}

Usually in order to get help you need to post a picture of a hand drawn wiring diagram. We need to see where the real wires connect.
Have you tried a minimum version? One sensor, no display just use Serial. This is on order to determine what general area is causing the problem. If the first test works, either add more sensors or implement the display but not both. I think you get the idea.

Show it.

Any reason not to use a library?

1 Like

Interesting, the LCD is a 5 volt device the ESP32 is a 3V3 volt device, what is the interface. Are there Pull Up resistors. Hmmmmmmmmmmm! A simple annotated schematic would answer these questions and many more. I expect it will in short time get you an accurate answer. Also post links to the technical information on each of the hardware devices.