// https://forum.arduino.cc/t/hd44780-decoder/1143429
// https://wokwi.com/projects/369059701985585153
// LCD2004 Tiny Pacman on Wokwi
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 27, 29, 31, 33);
uint8_t pacman[8] = {
0b00000,
0b00000,
0b01110,
0b11011,
0b11111,
0b01110,
0b00000,
0b00000
};
uint8_t pacmanOpen[] = {
0b00000,
0b00000,
0b01110,
0b11011,
0b11100,
0b01110,
0b00000,
0b00000
};
uint8_t dot[] = {
0b00000,
0b00000,
0b00000,
0b00110,
0b00110,
0b00000,
0b00000,
0b00000
};
void setup() {
lcd.createChar(1, pacman);
lcd.createChar(2, dot);
lcd.begin(20, 4);
lcd.setCursor(3, 0);
lcd.print("wokwi-lcd2004");
lcd.setCursor(2, 2);
lcd.print("4 lines, 20 cols");
decoderSetup();
}
void loop() {
for (int i = 3; i < 16; i++) {
lcd.setCursor(i, 3);
lcd.print("\1");
for (int j = i + 1; j < 16; j++) {
lcd.setCursor(j, 3);
lcd.print("\2");
}
lcd.createChar(1, pacman);
delay(200);
lcd.createChar(1, pacmanOpen);
delay(200);
lcd.setCursor(i, 3);
lcd.print(" ");
}
delay(1000);
dataSpill();
}
// HD44780 DECODER, WRITTEN BY LEONARDO MARTINS 19/01/2019
# define RS_PIN 23 // RS (Register Select) pin
// # define RW_PIN 11 // RW (Read/Write) pin
# define EN_PIN 21 // EN (Enable) pin
# define DATA_PINS {37, 39, 41, 43} // Data pins D4, D5, D6 and D7
bool previousEn = LOW; // Previous state of the EN pin
volatile byte data = 0; // Storage for data
volatile bool highBits = true; // Flag to indicate if we are reading high or low bits
volatile bool dataReady = false; // Flag to indicate when data is ready to read
void decoderSetup() {
Serial.begin(9600); // Start serial communication
// Set control pins as input
pinMode(RS_PIN, INPUT);
// pinMode(RW_PIN, INPUT);
pinMode(EN_PIN, INPUT);
// Set data pins as input
int dataPins[] = DATA_PINS;
for (int i = 0; i < 4; i++) {
pinMode(dataPins[i], INPUT_PULLUP);
}
// Setup the interrupt
attachInterrupt(digitalPinToInterrupt(EN_PIN), readData, FALLING);
// Serial.println(digitalPinToInterrupt(EN_PIN));
// for (; ; );
}
void loopTEST() {
if (dataReady) {
// Print the corresponding ASCII character to the Serial
Serial.print(data);
dataReady = false; // Reset the data ready flag
}
}
volatile char dataBuffer[128];
volatile byte charCount;
void readData() {
// Check if it's a write operation (RW == 0) and data is being sent (RS == 1)
if (digitalRead(RS_PIN) == HIGH) {
// Read the 4-bit part of data
int dataPins[] = DATA_PINS;
byte part = 0;
for (int i = 0; i < 4; i++) {
part |= digitalRead(dataPins[i]) << i;
}
if (highBits) {
// This is the high bits part
data = part << 4;
} else {
// This is the low bits part
data |= part;
dataReady = true; // Indicate that data is ready to read
dataBuffer[charCount] = data;
charCount++;
}
// Flip the highBits flag
highBits = !highBits;
}
}
void dataSpill()
{
if (!dataReady)
return;
noInterrupts();
int myCount = charCount;
charCount = 0;
dataReady = false;
interrupts();
Serial.print("data ");
for (unsigned char tt = 0; tt < myCount; tt++) {
// Serial.print("0x");
Serial.print((byte) dataBuffer[tt], HEX);
Serial.print(" ");
}
Serial.println(".");
}