LCD pulsing text

I'm trying to put together bits of code to eventually end up with a 9x4 matrix of button inputs, send each individual button pressed as a HID usb gamepad, whilst certian buttons display text on a lcd.

I have got the lcd working, running it in 4 bit mode, it's a 20 x 1 character module... which is from the bus ticket machine i am interfacing to a computer simulator,

So now i am looking having button presses display different text on the lcd, eventually it will need to scan the matrix'd buttons, and display text for about 10 different buttons being pressed,

Text to display will be ticket type, to stay on the display untill either the cancel button is pressed, or the print ticket button is pressed, when the display is to change to show 'printing' for 2 seconds, then blank the display.

This is my script so far... a combination of the standard lcd library, and a bit of script i found from someone who wanted 3 buttons to display text,

// include the library code:
#include <LiquidCrystal.h>
#include <Wire.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int switchPin = 10;              // switch is connected to pin 10
int switchPin1 = 9;              // switch is connected to pin 9
int switchPin2 = 8;              // switch is connected to pin 8
int prevState;                     // variable for reading the pin status
int currState;                // variable to hold the last button state

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 1);
  
  pinMode(switchPin, INPUT);     // Set the switch pin as input
  pinMode(switchPin1, INPUT);    // Set the switch pin as input
  pinMode(switchPin2, INPUT);    // Set the switch pin as input
}

 void loop(){
  currState = digitalRead(switchPin);
  
  if(currState !=prevState){
 
  if(currState == LOW){
  lcd.println("   ");
  lcd.clear();
  
  } 
    
    
  else {
    
  prevState = currState;
  currState = digitalRead(switchPin);
  if(currState !=prevState)
  lcd.print(0, 0);
  lcd.print("Fahrschein Erm  1.70");
  
  }
  }
  prevState = currState;

 currState = digitalRead(switchPin1);
  
  if(currState !=prevState){
  if(currState == LOW){
  lcd.println("   ");
  lcd.clear();
  } 
  else {
    
  prevState = currState;
  currState = digitalRead(switchPin1);
  if(currState !=prevState)
  lcd.print(0, 0);
  lcd.print("TagesKarte      9.00");
  
  }
  }
  prevState = currState;
  
  
  currState = digitalRead(switchPin2);
  
  if(currState !=prevState){
  if(currState == LOW){
  lcd.println("   ");
  lcd.clear();
  } 
  else {
    
  prevState = currState;
  currState = digitalRead(switchPin2);
  if(currState !=prevState)
  lcd.print(0, 0);
  lcd.print("Fahrschein Nor  2.70");
  
  }
  }
  prevState = currState;
  }

It works, however the text is pulsing when it is shown, not flashing, but pulsing from bottom to top, as if it's being refreshed at too slow a rate,
or it might be because of the code that is keeping a look out for button presses?

I also see no way to alter how long the text stays displayed for, ATM it displays for about 4 or 5 seconds, then blanks, and there is a delay if you press another button before it changes the text.

Is there a better way to do what i am trying, and will this even be compatable with matrix buttons when i try and add that part of the code?

You are clearing or writing the display all the time, depending on a value that is updated muliple times per run in your loop.
Maybe you should first check all inputs, set the output message accordingly and then check to see if that message is already present before you write it to the display.
The goal of this is to only write to the display if the message has changed.
I don't think that is what you are doing right now because currState is updated at least 3 times each run.

Viel Erfolg.

Thanks mate,

I thought it might have been clearing and re-writing to the display all the time,

i found that if i press all 3 buttons at once, the display becomes solid and is nice and readable, so i guess i am locking something up doing that... i'll only ever press one button at a time in my finished design anyway.

Unfortunately this is all new to me, i just found some code on the net, and it kind of does what i want... but i need to modify it for my own use now,

Not sure i need to check the message is already displayed before writing to the display? as if it is, it will just flash once when it is updated???

the goal is definately to only write to the display when something changes, either a 'ticket' selection button, the canel button 'clear display' or print ticket : display 'printing' then clear display,

So, i assume i need to scan all inputs for changes, detect an input, check if the button pressed has a lcd function assigned to it, if so, either write that message on the lcd, clear the display or display the 'printing' message, wait 2 seconds, then clear the display,

I have slightly modified the keypad sketch to work with my button matrix :

#include <Keypad.h>

const byte ROWS = 4; //4 rows
const byte COLS = 9; //9 columns
//define the symbols on the buttons of the keypads, Ideally i want the real keys, i.e. 'Fahrschein Nor', 'Kurzstrecke', 'Ausgabe' etc, 
//but the hexakeys thing i think only reads/displays the last letter.
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3','4','5','6','7','8'},
  {'9','A','B','C','D','E','F','G','H'},
  {'I','J','K','L','M','N','O','P','Q'},
  {'R','S','T','U','V','W','X','Y','Z'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {12, 11, 10, 9, 8, 7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad cusomKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  char customKey = cusomKeypad.getKey();
  
  if (customKey != NO_KEY){
    Serial.println(customKey);
  }
}

i wonder if i could alter the bit where it sends the charecters to serial, to send them to the lcd, and assign text to be displayd instead of just the button assignment number/letters,

i've tried another way, and it's working a lot better,

However, it has a big delay, about 2 seconds before it registers a button press and displays the text,
it's probably a silly mistake, but i am not sure what it is,
and not sure i can do this kind of sketch with a button matrix,

#include <LiquidCrystal.h>

int buttonPin1= 6;
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int prevButtonState1;
int prevButtonState2;
int prevButtonState3;
int prevButtonState4;

void setup()
{
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  
  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  digitalWrite(buttonPin3, LOW);
  digitalWrite(buttonPin4, LOW);
  
  lcd.begin(20, 1);
  lcd.print("Omsi Almex a90");
  delay(2000);
  lcd.clear();
}


void loop(){
  int buttonState1 = digitalRead(buttonPin1);
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);
 
  if (buttonState1 == LOW && prevButtonState1== HIGH){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Fahrschein Nor  2.70");
    prevButtonState1 = buttonState1;
  }
  else if(buttonState2 == LOW && prevButtonState2== HIGH){
    lcd.clear();
    lcd.print("Fahrschein Erm  1.70");
    prevButtonState2 = buttonState2;
  }  
  else if(buttonState3 == LOW && prevButtonState3== HIGH){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Tageskarte      9.00");
    prevButtonState3 = buttonState3;
  }
  else if(buttonState4 == LOW && prevButtonState4== HIGH){
    lcd.clear();
    lcd.print("    >>Drucken<<     ");
    delay(2000);
    lcd.clear();
    prevButtonState4 = buttonState4;
  }
    else{
    prevButtonState1 = buttonState1;
    prevButtonState2 = buttonState2;
    prevButtonState3 = buttonState3;
    prevButtonState4 = buttonState4;
 }
  }

However, it has a big delay, about 2 seconds before it registers a button press and displays the text,
it's probably a silly mistake, but i am not sure what it is, ...

Would your delay(2000), the one in loop(), have anything to do with this?

Also - you really should avoid using lcd.clear() in your loop. You do not have to clear the display before writhing new information, just reposition the cursor and send the new information.

If you do use lcd.clear() then you do not have to reposition the cursor to (0,0), the clear operation does that for you.

Don

Nope, even with the delays removed, it still takes it's time,

i've changed a few things, got rid of all delays except the one that keeps the 'Belegdruck' text on screen for a short while, then clears the screen, makes no difference if i remove that delay too,

#include <LiquidCrystal.h>

int buttonPin1= 6;
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);

  digitalWrite(buttonPin1, LOW);
  digitalWrite(buttonPin2, LOW);
  digitalWrite(buttonPin3, LOW);
  digitalWrite(buttonPin4, LOW);
}


void loop(){
  int buttonState1 = digitalRead(buttonPin1);
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);

  if(buttonState1== HIGH){
    lcd.setCursor(0,0);
    lcd.print("   >>Belegdruck<<   ");
    delay (100);
    lcd.clear();
  }
    
  else if (buttonState2==HIGH){
    lcd.setCursor(0,0);
    lcd.print("Fahrschein Nor  2.70");
  }
  else if(buttonState3== HIGH){
    lcd.setCursor(0,0);
    lcd.print("Kurzstrecke     1.70");
  }  
  else if(buttonState4== HIGH){
    lcd.setCursor(0,0);
    lcd.print("Tageskarte      9.00");
  }  
}

The above code works just like before, i removed all the 'int prevButtonState' bits, as i figured they were not needed, the script i got this info from originally had a message on the screen whenever no buttons were pressed, changing to show which were pressed, then back to no button is pressed displayed.

But basically, if i press button 4, it displays it's text, if i then press button 3, it changes immediately to button 3's text, same if i press button 2 after button 3 or 4, and pressing button 1 does the 'Belegdruck' thing, and clears the display,

However, if i press say button 2, then press button 4, it waits about 4 seconds before changing the text to that of button 4, i.e. i can go down the button numbers instiantly, but going up them gives the delays,

Also, even with the button 1 delay before clearing the lcd set for 100 millis, it takes 4 seconds to clear the display.

Something is causing the delay... i can't believe it's the time it takes the loop part of the script to run??

i'm an idiot,

it was switch bounce,
i'd found parts of cod on various sites, put them together, not realising that by setting the input pins to LOW wasn't doing anything, hence with my buttons going high to be read, the inputs were floating, and i was effectively sending loads of button press commands,

changed the script on the advise of people at my local hackspace....

#include <LiquidCrystal.h>

int buttonPin1= 6;    //sets pins buttons are connected to
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;
int buttonPin5= 13;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //sets pins lcd is connected to, running in 4 bit mode, RW pin tied to gnd

void setup()
{
  pinMode(buttonPin1, INPUT);  //assigns button pins as inputs
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buttonPin5, INPUT);

  digitalWrite(buttonPin1, HIGH);  //sets internal pulldown resistors
  digitalWrite(buttonPin2, HIGH);
  digitalWrite(buttonPin3, HIGH);
  digitalWrite(buttonPin4, HIGH);
  digitalWrite(buttonPin5, HIGH);

  lcd.begin(20, 1);   //lcd size
  lcd.print("Der Omnibussimulator"); //welcome text
  delay(2000);  //displays for 2 secs
  lcd.clear();  //clears display
}


void loop(){
  int buttonState1 = digitalRead(buttonPin1);  
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);
  int buttonState5 = digitalRead(buttonPin5);


  if (buttonState1== LOW){
    lcd.setCursor(0,0);
    lcd.print("Fahrschein Nor  2.70");  //German for single ticket, stays on the lcd untill another buttons is pressed
  }
  else if(buttonState2== LOW){
    lcd.setCursor(0,0);
    lcd.print("Kurzstrecke     1.70");  //German for short trip ticekt, stays on lcd untill another button is presed
  }  
  else if (buttonState3== LOW){
    lcd.setCursor(0,0);
    lcd.print("Tageskarte      9.00");  //German for day ticket, stays on display untill another button is pressed
  }  
  else if(buttonState4== LOW){  //button pressed
    lcd.setCursor(0,0);  //clears display
    lcd.print("   >>Belegdruck<<   ");  //German for 'printing ticket'
    delay(350);
    lcd.noDisplay();
    delay(250);
    lcd.display();
    delay(350);
    lcd.noDisplay();
    delay(250);
    lcd.display();
    delay(550);
    lcd.clear();
  }
  else if(buttonState5== LOW){
    lcd.clear();
  }
}

And it all works, instant response from the buttons, no delays other than those i put in to flash the 'printing ticket' text,

Now to work out how to integrate the 9x4 button matrix into this script, having about 10 or 11 of the matrix'd buttons displaying text on the lcd, the other buttons are to be ignored by tis part of the script.