#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
// Define LCD Pins
#define RS 2
#define E 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
// Define LCD Commands
#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
// Helper functions to control LCD
void lcd_pulse_enable() {
gpio_put(E, 1);
sleep_us(1);
gpio_put(E, 0);
sleep_us(100);
}
void lcd_send_nibble(uint8_t nibble) {
gpio_put(D4, (nibble >> 0) & 1);
gpio_put(D5, (nibble >> 1) & 1);
gpio_put(D6, (nibble >> 2) & 1);
gpio_put(D7, (nibble >> 3) & 1);
lcd_pulse_enable();
}
void lcd_send_byte(uint8_t data, bool is_command) {
gpio_put(RS, is_command ? 0 : 1);
lcd_send_nibble(data >> 4); // Send high nibble
lcd_send_nibble(data & 0x0F); // Send low nibble
sleep_us(40);
}
void lcd_init() {
// Set GPIO pins as output
gpio_init(RS);
gpio_init(E);
gpio_init(D4);
gpio_init(D5);
gpio_init(D6);
gpio_init(D7);
gpio_set_dir(RS, GPIO_OUT);
gpio_set_dir(E, GPIO_OUT);
gpio_set_dir(D4, GPIO_OUT);
gpio_set_dir(D5, GPIO_OUT);
gpio_set_dir(D6, GPIO_OUT);
gpio_set_dir(D7, GPIO_OUT);
// LCD Initialization Sequence
sleep_ms(20); // Wait for LCD to power up
lcd_send_nibble(0x03);
sleep_ms(5);
lcd_send_nibble(0x03);
sleep_us(150);
lcd_send_nibble(0x03);
lcd_send_nibble(0x02); // Set 4-bit mode
// Configure LCD
lcd_send_byte(0x28, true); // 4-bit, 2 lines, 5x8 dots
lcd_send_byte(0x0C, true); // Display ON, Cursor OFF
lcd_send_byte(LCD_CLEAR, true); // Clear display
lcd_send_byte(0x06, true); // Entry mode: move cursor right
}
void lcd_print(const char *str) {
while (*str) {
lcd_send_byte(*str++, false);
}
}
int main() {
stdio_init_all();
// Initialize LCD
lcd_init();
lcd_print("Hello, Wokwi!");
while (true) {
// Keep the message displayed
sleep_ms(1000);
}
return 0;
}