LCD1602 Qapass not working on 8 bits [SOLVED]

Hello ! So, i'm trying to test my LCD into 8 bits mode without any libraries, but I can't make any character appear, even the instructions aren't working !
Any help would be greatly appreciated

main file

//#include <LiquidCrystal.h>

#include "LCD1602.h"

const uint8_t data[8]{5, 6, 7, 8, 9, 10, 11, 12};
LCD1602 _lcd(2, 3, 4, data);

//LiquidCrystal lcd(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);

void setup() {
  //lcd.begin(16, 2);
  _lcd.begin(0x38, 0x0F, 6);
  _lcd.writeChar(0x7D);
  //lcd.print('c');
}

void loop() {
  
}

LCD1602 source file

#include <stdint.h>
#include "Arduino.h"
#include "LCD1602.h"

LCD1602::LCD1602(uint8_t rs, uint8_t rw, uint8_t enable, uint8_t* dataPins){
  _rs = rs;
  _rw = rw;
  _enable = enable;
  _dataPins = dataPins;
}

void LCD1602::begin(char functionSet, char displayOnOff, char entryModeSet){
  pinMode(_rs, OUTPUT);
  pinMode(_rw, OUTPUT);
  pinMode(_enable, OUTPUT);

  dataSize = sizeof(_dataPins) / sizeof(*_dataPins);
  is4BitsMode = dataSize == 4;

  for (uint8_t i = 0; i < dataSize; i++) {
    pinMode(_dataPins[i], OUTPUT);
  }

  inst(functionSet);
  inst(displayOnOff);
  inst(entryModeSet);

  clear();
}

void LCD1602::writeChar(char code){
  digitalWrite(_rs, HIGH);
  digitalWrite(_rw, LOW);

  if (!is4BitsMode){
    writeCodeToLCD(code);
    clk();
  }else{
    char lcdCode = code >> 4;
    writeCodeToLCD(lcdCode);
    clk();
    lcdCode = code & 0x0F;
    writeCodeToLCD(lcdCode);
    clk();
  }
  
  delayMicroseconds(50);
}

void LCD1602::writeString(char *message){
  char* pt = message;
  while (*pt != 0) {
    writeChar(*pt);
    pt++;
  }
}

void LCD1602::inst(char code){
  digitalWrite(_rs, LOW);
  digitalWrite(_rw, LOW);

  if (!is4BitsMode){
    writeCodeToLCD(code);
    clk();
  }else{
    char lcdCode = code >> 4;
    writeCodeToLCD(lcdCode);
    clk();
    lcdCode = code & 0x0F;
    writeCodeToLCD(lcdCode);
    clk();
  }
  
  delayMicroseconds(50);
}

void LCD1602::clear(){
  digitalWrite(_rs, LOW);
  digitalWrite(_rw, LOW);

  writeCodeToLCD(0);
  clk();
  writeCodeToLCD(1);
  clk();

  delay(2);
}

void LCD1602::returnHome(){
  digitalWrite(_rs, LOW);
  digitalWrite(_rw, LOW);

  writeCodeToLCD(0);
  clk();
  writeCodeToLCD(2);
  clk();

  delay(2);
}

void LCD1602::setCursor(uint8_t x, uint8_t y){
  char code = 128 + (64 * x) + y;
  inst(code);
}

void LCD1602::clk(){
  digitalWrite(_enable, HIGH);
  digitalWrite(_enable, LOW);
}

void LCD1602::writeCodeToLCD(char code){
  for (uint8_t i = 0; i < dataSize; i++){
    digitalWrite(_dataPins[i], (code >> i) & 1);
  }
}

Your wiring to the display back light looks rather odd and would probably have the effect of making anything written to the screen difficult to read.
There is an example of writing to an LCD1602 screen in both 4 bit and 8 bit mode without using a library here: LCD 1602 (and similar) databus sniffer - #41 by 6v6gt . See the attached program LCD1602_write_V0_05.ino

1 Like

dataSize = sizeof(_dataPins) / sizeof(*_dataPins)

Try print the value of dataSize, it may not be what you think. _dataPins is a pointer, not an array :slight_smile:

Okay, solved by passing each dataPin one by one into the ctor. sizeof is no longer needed.
But yeah you're right, it doesn't return the right value
@6v6gt I looked at the .ino file, and it still uses LiquidCrystal library :upside_down_face:
(And I wired the pot correctly by removing the +5V too!)
The main issue was finally sizeof

You've solved it now apparently but the sample I linked to was a testing routine which included multiple use cases. One of which was direct writing to the display in 8 bit mode, including display initialization, without using any of the library functions.

OKAY LCD SKILL ISSUE
It doesn't work, AGAIN :neutral_face: :face_with_symbols_over_mouth:
Changing LCD does nothing

This is a working ChatGPT code, and I dunno why my code isn't working

#include "LCD.h"

// Constructeur
LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) {
    _rs = rs;
    _enable = enable;
    dataPins[0] = d0;
    dataPins[1] = d1;
    dataPins[2] = d2;
    dataPins[3] = d3;
    dataPins[4] = d4;
    dataPins[5] = d5;
    dataPins[6] = d6;
    dataPins[7] = d7;
}

// Initialisation de l'écran LCD
void LCD::begin() {
    Serial.begin(9600);
    pinMode(_rs, OUTPUT);
    pinMode(_enable, OUTPUT);
    for (uint8_t i = 0; i < 8; i++) {
        pinMode(dataPins[i], OUTPUT);
    }

    delay(50); // Attendre que l'écran s'initialise

    // Séquence d'initialisation en mode 8 bits
    Serial.println("Sending wake-up command 0x30");
    send(0x30, LOW); // Commande de "wake-up"
    delay(5);
    Serial.println("Sending wake-up command 0x30");
    send(0x30, LOW); // Répétition de la commande de "wake-up"
    delay(1);
    Serial.println("Sending wake-up command 0x30");
    send(0x30, LOW); // Répétition de la commande de "wake-up"
    delay(1);

    // Mode 8 bits, 2 lignes, 5x8 dots
    Serial.println("Setting function mode 0x38");
    send(0x38, LOW);
    delay(1);

    // Activer l'affichage, désactiver le curseur
    Serial.println("Turning on display 0x0C");
    send(0x0C, LOW);
    delay(1);

    // Effacer l'écran
    clear();

    // Mode d'entrée : incrémentation automatique, sans décalage
    Serial.println("Setting entry mode 0x06");
    send(0x06, LOW);
}

// Fonction pour effacer l'écran
void LCD::clear() {
    Serial.println("Clearing display 0x01");
    send(0x01, LOW);
    delay(2); // Attendre que l'écran soit effacé
}

// Fonction pour écrire une chaîne de caractères
void LCD::writeString(const char *message) {
    while (*message) {
        send(*message++, HIGH);
    }
}

// Fonction pour envoyer une commande ou des données
void LCD::send(uint8_t value, uint8_t mode) {
    digitalWrite(_rs, mode);
    write8bits(value);
    pulseEnable();
}

// Fonction pour écrire 8 bits
void LCD::write8bits(uint8_t value) {
    for (uint8_t i = 0; i < 8; i++) {
        digitalWrite(dataPins[i], (value >> i) & 0x01);
    }
}

// Fonction pour générer une pulsation sur la broche Enable
void LCD::pulseEnable() {
    digitalWrite(_enable, LOW);
    delayMicroseconds(1);
    digitalWrite(_enable, HIGH);
    delayMicroseconds(1); // Activer l'écran
    digitalWrite(_enable, LOW);
    delayMicroseconds(100); // Attendre que l'écran traite l'instruction
}

Did ChatGPT say anything about the Arduino standard setup() and loop() ? Usually, failure to respect these requirements ends with an error message.

It didn't write anything in loop

Here's my code :

#include <stdint.h>
#include "Arduino.h"
#include "LCD.h"

LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7){
  _rs = rs;
  _enable = enable;

  dataPins[0] = d0;
  dataPins[1] = d1;
  dataPins[2] = d2;
  dataPins[3] = d3;
  dataPins[4] = d4;
  dataPins[5] = d5;
  dataPins[6] = d6;
  dataPins[7] = d7;

  is4BitsMode = false;
}

void LCD::begin(char functionSet, char displayOnOff, char entryModeSet){
  pinMode(_rs, OUTPUT);
  //pinMode(_rw, OUTPUT);
  pinMode(_enable, OUTPUT);

  for (uint8_t i = 0; i < (is4BitsMode ? 4 : 8); i++) {
    pinMode(dataPins[i], OUTPUT);
  }

  inst(functionSet);
  inst(displayOnOff);
  inst(entryModeSet);

  clear();
}

void LCD::writeChar(char code){
  digitalWrite(_rs, HIGH);
  //digitalWrite(_rw, LOW);

  if (!is4BitsMode){
    writeCodeToLCD(code);
    clk();
  }else{
    char lcdCode = code >> 4;
    writeCodeToLCD(lcdCode);
    clk();
    lcdCode = code & 0x0F;
    writeCodeToLCD(lcdCode);
    clk();
  }
  
  delayMicroseconds(50);
}

void LCD::writeString(char *message){
  char* pt = message;
  while (*pt != 0) {
    writeChar(*pt);
    pt++;
  }
}

void LCD::inst(char code){
  digitalWrite(_rs, LOW);
  //digitalWrite(_rw, LOW);

  if (!is4BitsMode){
    writeCodeToLCD(code);
    clk();
  }else{
    char lcdCode = code >> 4;
    writeCodeToLCD(lcdCode);
    clk();
    lcdCode = code & 0x0F;
    writeCodeToLCD(lcdCode);
    clk();
  }
  
  delayMicroseconds(50);
}

void LCD::clear(){
  digitalWrite(_rs, LOW);
  //digitalWrite(_rw, LOW);

  writeCodeToLCD(1);
  clk();

  delay(2);
}

void LCD::returnHome(){
  digitalWrite(_rs, LOW);
  //digitalWrite(_rw, LOW);

  writeCodeToLCD(2);
  clk();

  delay(2);
}

void LCD::setCursor(uint8_t x, uint8_t y){
  char code = 128 + (64 * x) + y;
  inst(code);
}

void LCD::clk(){
  digitalWrite(_enable, HIGH);
  digitalWrite(_enable, LOW);
}

void LCD::writeCodeToLCD(char code){
  for (uint8_t i = 0; i < 8; i++){
    digitalWrite(dataPins[i], (code >> i) & 1);
  }
}

It says nothing about setup, just lcd.begin and lcd.writeString

Not enough of the code is visible. You appear to have included the .cpp file only. Missing is both the .h file and the .ino file. I suggest that you load both the working and non working versions of this program into the wokwi.com simulator and share the links here.

Incidentally, you can't leave the RW pin floating. It has an internal pullup resistor and would by default be in read mode. You want it in write mode.

I've connected RW to ground
LCD - Wokwi ESP32, STM32, Arduino Simulator (ChatGPT code)
LCD_2 - Wokwi ESP32, STM32, Arduino Simulator (My code)

This is incorrect:

image

You are loading dataPins[ ] and dataPinsRead[ ] as an array but have defined no storage for them. You should explicitly define them e.g. dataPins[8].

image

This causes corruption and was not even possible to get Serial.print to work properly.
But I think after solving that, you have other problems.

Oh okay, yeah Serial.print prints random values :sweat_smile:
I'm trying to rewrite what ChatGPT has written
I'll try to do with what you suggest to me

@6v6gt It's the uint8_t* corruption that broke up everything ! I've taken my code from Wokwi simulator, put uint8_t dataPins[8]; into the header file, and now that works
I've NEVER thought a pointer used as array can corrupt an entire custom library

I also had to rewire it to get it to work and changed a pin LCD_2 Copy - Wokwi ESP32, STM32, Arduino Simulator. There may have been a bad connection. It corrupted a maximum of 16 bytes but that was enough.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.