Fun with LCD...

I suppose the typical introduction should go here…
I am relatively new to Arduino. Help please! :stuck_out_tongue:

I’m having some fun with an LCD, and feel like posting my code to see if there’s any better way of doing things. Please note that I haven’t even uploaded this to my Arduino to see if it works as intended, but it seems to compile fine.

The idea is for it to print words letter by letter, and depending on user input, display relevant information. So, without further adieu, here is the code:

//////////////////////////////////////////////////////////////////
///////////      WOULD YOU LIKE TO PLAY A GAME?      /////////////
//////////////////////////////////////////////////////////////////

// LIBRARIES //
#include <LiquidCrystal.h>

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

// PIN ASSIGNMENTS //
#define TRUEBUTTON 7
#define FALSEBUTTON 8

// GLOBAL VARIABLES //
boolean introPassed = false;
int typeDelay = 300;
char stringIntroLine1[] = {'W','o','u','l','d',' ','y','o','u',' ','l','i','k','e'};
char stringIntroLine2[] = {'t','o',' ','p','l','a','y',' ','a',' ','g','a','m','e','?'};
char stringStage1Line1[] = {'F','a','i','r',' ','e','n','o','u','g','h','.'};
char stringStage1Line2[] = {'L','e','t','\'','s',' ','b','e','g','i','n','.'};
int introLine1Length = 14;
int introLine2Length = 15;
int stage1Line1Length = 12;
int stage1Line2Length = 12;

// SETUP //
void setup() {
  lcd.begin(16, 2);
  lcd.blink();
  pinMode(TRUEBUTTON, INPUT);
  pinMode(FALSEBUTTON, INPUT);
}

// MAIN CODE //
void loop() {
  // WE ONLY WANT THE INTRO TO RUN THROUGH ONCE! //
  if (introPassed == false) {
    for(int n = 0; n < introLine1Length; n++) {
      lcd.print(stringIntroLine1[n]);
      delay(typeDelay);
    }
    lcd.setCursor(0, 1);
    for(int n = 0; n < introLine2Length; n++) {
      lcd.print(stringIntroLine2[n]);
      delay(typeDelay);
    }
    int trueButtonState = digitalRead(TRUEBUTTON); // WE'LL NEED THIS FOR THE NEXT PART!
    int falseButtonState = digitalRead(FALSEBUTTON); //WE'LL NEED THIS FOR THE NEXT PART!
    while (trueButtonState == LOW && falseButtonState == LOW) {
      trueButtonState = digitalRead(TRUEBUTTON);
      falseButtonState = digitalRead(FALSEBUTTON);
    }
    lcd.clear();
    if (trueButtonState == HIGH) {
      introPassed = !introPassed;
      for(int n = 0; n < stage1Line1Length; n++) {
        lcd.print(stringStage1Line1[n]);
        delay(typeDelay);
      }
      lcd.setCursor(0, 1);
      for(int n = 0; n < stage1Line2Length; n++) {
        lcd.print(stringStage1Line2[n]);
        delay(typeDelay);
      }
    
    }
    else if (falseButtonState == HIGH) {
      gameOver();
    }
    else {
      showError();
    }
    
  }
}

void gameOver() {
  lcd.clear();
  lcd.print("Haha, try again.");
  lcd.setCursor(0, 1);
  lcd.print("Restarting...");
  delay(2000);
}

void showError() {
  lcd.clear();
  lcd.print("OH NO!");
  lcd.setCursor(0, 1);
  lcd.print("You broke me.");
  delay(2000);
}

It’s incomplete… sort of. :roll_eyes:

char stringIntroLine1[] = {'W','o','u','l','d',' ','y','o','u',' ','l','i','k','e'};

This is hard to type, and hard to read.

char stringIntroLine1[] = {"Would you like"};

The does exactly the same thing, but is a bit easier to type and read.

int introLine1Length = 14;
int introLine2Length = 15;
int stage1Line1Length = 12;
int stage1Line2Length = 12;

The strlen() function will compute these (correctly) every time you really need to know the length. Much easier to manage code that does the work for you. If you change the message, you don’t need to recount the letters.

// WE ONLY WANT THE INTRO TO RUN THROUGH ONCE! //
if (introPassed == false) {

Then do it in setup.

  lcd.print("Restarting...");

But you don’t restart…

I don't think you've thought about how the code works... its not how it will be when done, but it should still work.

The reason for the arrays of letters as compared to a string is that I want it to appear as if it is "typing" it. If I wasn't, I would just do something like lcd.print("string");.

It DOES restart because I've put the intro in to the loop... after the gameOver() function is called, it returns to the loop and finishes it. Returning back to the intro.

Because I want it to print individual chars, the strleng() function wont help. The only way I can see of improving it is making multidimensional arrays rather than seperate ones.

The reason for the arrays of letters as compared to a string is that I want it to appear as if it is "typing" it. If I wasn't, I would just do something like lcd.print("string");.

The way the data is stored in the array, and the way it would be output in your code, is identical. One method is easier to maintain. But, hey, it's your code.

Because I want it to print individual chars, the strleng() function wont help.

You might want to try it.

Then a humble apology is due. I'm not at my computer, making it impossible for me to look into such things. Thank you for the advice, and I'll give it a try as soon as I get the chance!

Another question then...

Is this correct?

char myStrArray[][15][16] = {{"Would you like"},{"to play a game?"}};

[15] being the length of the first array (would you like), and [16] being the length of the second (to play a game?). The size includes the required null char.

Once again, this compiles fine... but might be wrong? :P

Why build in all these "magic numbers" like 15 and 16, when you can code without them? Then you don't have to worry about counting characters, and getting it wrong. The code below works in the sense that it slowly displays a message, letter by letter:

void setup ()
{
 const char * instructions [] = {
   "Would you like to",
   "Play a game?",
   "Well, let's begin ...",
   NULL,
 };

 Serial.begin (9600);

 for (int line = 0; instructions [line]; line++)
  {
  for (const char * p = instructions [line];  *p;  p++)
    {
    Serial.print (*p);
    delay (100);  
    }  // end of each character
   Serial.println (); 
  }  // end of each line
}  // end of setup

void loop ()
{
}  // end of loop

Of course, this doesn't output to the LCD display, but I'll leave that to you ...