I2C Library for LCD 0x27 or Ax07

Hi there,
Am trying to connect a LCD with I2C into the mbed nucleo-413zh so it can displays “Fire” when it activates the flame sensor and displays " No fire" when flame sensor is not activated. I have tried modifying the TextLCD.h and TextLCD.cpp but not been successful. The LCD turns on but nothing displays. The flame sensor activates when fire is detected but besides that nothing else happens. It only displays Fire or No fire in the Serial Terminal. Also am trying to connect a motor connected to a L298N so it also activates when fire is detected but still doesn’t work.

This is the library am using-

This is the TextLCD.cpp -

#include “TextLCD.h” // Include the header for TextLCD
#include // Required for specifying time durations

// Constructor for initializing the LCD
TextLCD::TextLCD(I2C* i2c, uint8_t addr, LCDType type) {
_i2c = i2c;
_addr = addr;
_type = type;
_backlight = LightOn;

// Power-up delay to ensure LCD is ready
ThisThread::sleep_for(10ms);  // Ensure proper delay

// Initialize the LCD
lcd_init();

}

// Function to initialize the LCD
void TextLCD::lcd_init() {
// Initialization sequence for the LCD
lcd_command(0x33); // Initialize
lcd_command(0x32); // Initialize
lcd_command(0x28); // Function set: 4-bit, 2-line
lcd_command(0x0C); // Display on, cursor off
lcd_command(0x06); // Entry mode set

// Additional delay to ensure LCD setup
ThisThread::sleep_for(10ms);

}

// Send a command to the LCD
void TextLCD::lcd_command(uint8_t cmd) {
_i2c->start();
_i2c->write(_addr);
_i2c->write(0x00); // Command register
_i2c->write(cmd);
_i2c->stop();

// Ensure a delay after sending a command
ThisThread::sleep_for(1ms);  // Add delay for LCD processing

}

// Clear the screen
void TextLCD::cls() {
lcd_command(0x01); // Clear display
ThisThread::sleep_for(2ms); // Allow time for clearing
}

// Set cursor location
void TextLCD::locate(int column, int row) {
uint8_t row_offsets = {0x00, 0x40}; // Offsets for rows
lcd_command(0x80 | (column + row_offsets[row]));
}

// Print formatted text to the LCD
void TextLCD::printf(const char* format, …) {
char buffer[32]; // Buffer for formatted text
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args); // Format the text
va_end(args);

// Send each character to the LCD
_i2c->start();
_i2c->write(_addr);
_i2c->write(0x40);  // Data register
for (int i = 0; buffer[i] != '\0'; i++) {
    _i2c->write(buffer[i]);
}
_i2c->stop();

}

// Control the backlight
void TextLCD::setBacklight(BacklightState state) {
if (state == LightOn) {
lcd_command(0x08); // Command to turn on backlight
} else {
lcd_command(0x00); // Command to turn off backlight
}
_backlight = state;
}

This is the TextLCD.h-

#ifndef TEXTLCD_H
#define TEXTLCD_H

#include “mbed.h” // Ensure Mbed header is included
#include // For variable argument functions like printf
#include // For specifying time durations

class TextLCD {
public:
enum LCDType {
LCD16x2, // 16 characters x 2 lines
LCD20x4 // 20 characters x 4 lines
};

enum BacklightState {
    LightOn,
    LightOff
};

TextLCD(I2C* i2c, uint8_t addr, LCDType type);
void printf(const char* format, ...);
void setBacklight(BacklightState state);
void cls();  // Clear screen
void locate(int column, int row);

private:
void lcd_command(uint8_t cmd); // Send command to the LCD
void lcd_init(); // Initialize the LCD

I2C* _i2c;  // I2C instance
uint8_t _addr;  // I2C address
LCDType _type;  // LCD type
BacklightState _backlight;

};

#endif // TEXTLCD_H

This is my current code-

#include “mbed.h”
#include “TextLCD.h” // Include a library for LCD handling
#include // Required for specifying time durations

// Define pin connections
DigitalIn flame_sensor(PB_5); // Flame sensor pin
DigitalOut alarm(PC_8); // Alarm pin

// Motor driver pins
DigitalOut motor_in1(PA_5); // IN1 pin of L298N connected to PA_5
DigitalOut motor_in2(PA_6); // IN2 pin of L298N connected to PA_6
PwmOut motor_pwm(PA_7); // ENA pin of L298N connected to PA_7

// I2C instance and LCD setup with address 0x27
I2C i2c_lcd(PB_9, PB_8); // SDA, SCL
TextLCD lcd(&i2c_lcd, 0x27, TextLCD::LCD16x2); // Initialize LCD

// Serial communication for debugging
BufferedSerial pc(USBTX, USBRX, 9600); // USBTX and USBRX are the USB serial ports

int main() {
// Initial setup
ThisThread::sleep_for(100ms); // Wait 100ms to ensure hardware is ready
const char* startup_message = “mbed Fire Module Test\n”;
pc.write(startup_message, 23); // Using known length to avoid strlen

// Initialize the LCD
lcd.setBacklight(TextLCD::LightOn);  // Turn on the backlight
lcd.cls();  // Clear the screen
lcd.printf("Flame Sensor Ready");

while (true) {
    // Read the flame sensor
    int fire = flame_sensor.read();

    if (fire == 1) {  // If high, fire is detected
        alarm = 1;  // Turn on the alarm
        motor_in1 = 1;  // Set motor direction (example)
        motor_in2 = 0;  // Set motor direction (example)
        motor_pwm = 0.8;  // Set motor speed (example: 80% duty cycle)
        const char* fire_msg = "Fire! Fire!\n";
        pc.write(fire_msg, 12);  // Using known length
        lcd.cls();
        lcd.locate(0, 0);  // Move to the first line, first column
        lcd.printf("Fire! Fire!");
    } else {
        alarm = 0;  // Turn off the alarm
        motor_pwm = 0;  // Stop the motor
        const char* no_fire_msg = "No Fire\n";
        pc.write(no_fire_msg, 8);  // Using known length
        lcd.cls();
        lcd.locate(0, 0);  // Move to the first line, first column
        lcd.printf("No Fire");
    }

    // Delay to avoid message spam
    ThisThread::sleep_for(200ms);
}

}

Hello,

it doesn’t matter about sensor and motor but most important informations are missing.

  • What display are you using?
  • Did you test the library with the example program? That is, from my point of view, very good practice. I mean, try every library of each component separately with recommended example and when you know it works, then you can implement it to your project.

However i do not know why you choose exactly this library because most popular library for LCD under Mbed is TextLCD. HD44780 Text Display - #2 by JohnnyK

// Delay to avoid message spam

This is nor related to your issue but maybe try to use another variable for detection of sensor state change.

int main() {
	// Initial setup
	ThisThread::sleep_for(100ms); // Wait 100ms to ensure hardware is ready
	const char* startup_message = “mbed Fire Module Test\n”;
	pc.write(startup_message, 23); // Using known length to avoid strlen

	// Initialize the LCD
	lcd.setBacklight(TextLCD::LightOn);  // Turn on the backlight
	lcd.cls();  // Clear the screen
	lcd.printf("Flame Sensor Ready");

	int fire = 0;
	int fireLast = 0;

	while (true) {
		// Read the flame sensor
		fire = flame_sensor.read();
		if(fire != fireLast){  //will trigger necessary code only when it is needed
			if (fire == 1) {  // If high, fire is detected
				alarm = 1;  // Turn on the alarm
				motor_in1 = 1;  // Set motor direction (example)
				motor_in2 = 0;  // Set motor direction (example)
				motor_pwm = 0.8;  // Set motor speed (example: 80% duty cycle)
				const char* fire_msg = "Fire! Fire!\n";
				pc.write(fire_msg, 12);  // Using known length
				lcd.cls();
				lcd.locate(0, 0);  // Move to the first line, first column
				lcd.printf("Fire! Fire!");
			} else {
				alarm = 0;  // Turn off the alarm
				motor_pwm = 0;  // Stop the motor
				const char* no_fire_msg = "No Fire\n";
				pc.write(no_fire_msg, 8);  // Using known length
				lcd.cls();
				lcd.locate(0, 0);  // Move to the first line, first column
				lcd.printf("No Fire");
			}
		}
		fireLast = fire;

		// Delay to avoid message spam
		ThisThread::sleep_for(200ms);
	}
}

BR, Jan