Question about referencing

Simple question really, why does this work,

else{
      while(doQuestion){
        int Q = 3;
          doDisplay(Question[Q][0], Question[Q][1], Question[Q][2], Question[Q][3], Question[Q][4]);
          answer = Question[Q][5];
          doQuestion=false;
          
    }

But this doesn't even though the value is the same (But the referenced variable is global)

else{
      while(doQuestion){
        int Q = questionNum;
          doDisplay(Question[Q][0], Question[Q][1], Question[Q][2], Question[Q][3], Question[Q][4]);
          answer = Question[Q][5];
          doQuestion=false;
          
    }

Ignore the excessive array referencing, I'll clean that up once I fix this hurdle.

It acts completely erratic if I use the referenced variable rather that a fixed one.

If you need more code reference, let me know and I'll put it up, just trying to avoid spamming.

Thanks.

Probably need to see more of the code to give an accurate answer, like all of the code or at least a minimum runnable example.

1 Like

I don't believe you, if I do understand you, which I don't quite yet.

Put some serial print statements in there and verify your assertions about the values being the same or whatever.

You may get a surprise.

And yeah, this would be easier to see in the context of a complete it compiles and runs type example

a7

1 Like

Ok, I'm going to paste the code, I hope it's not too much to go through.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd (0x27, 20, 4); //Define 20x4 LCD
LiquidCrystal_I2C lcd2 (0x26, 16, 2); //Define 16x2 LCD

int buttonPressed = 0; //int for which button is pressed.
int welcome = 0; //Set welcome to 0 to display welcome message.
int questionNum = 0; //Define question number.
int totalQuestions = 10; //Set question amount.
int score = 0; //Keep score.
int buzzer = 7; //Buzzer pin.
int answer = 0;
bool doQuestion = false;

void setup() {
//Define buzzer.
  pinMode(buzzer, OUTPUT);
//Define button pins.
  pinMode(8, INPUT_PULLUP);
    pinMode(9, INPUT_PULLUP);
      pinMode(10, INPUT_PULLUP);
        pinMode(11, INPUT_PULLUP);

//Start serial
  Serial.begin(9600);

//Initalise both lcd screens.
    lcd.init();
      lcd.backlight();
        lcd2.init();
          lcd2.backlight();

}

const char * const gameMess[2][6] PROGMEM = {
{"Welcome to Superquiz! Press any button to continue.", "Ready", "to", "play", "?", 1 },
{ "Game Over", "Your score is:", 1 }
};

const char * const Question[10][6] PROGMEM = {
{ "How many seasons of Friends where there?", "1", "4", "6", "10", 4 },
{ "Who pees on Monica after she is stung by a jelly fish?", "Chandler", "Rachel", "Joey", "Pheobe", 3 },
{ "Ross says whos name at the altar in london?", "Rachel", "Pheobe", "Monica", "Emily", 1 },
{ "How many sisters does joey have?", "5", "7", "2", "0", 2 },
{ "What is the name of Joeys character in the commercial for opening milk carton", "Mike", "Tommy", "Kevin", "Drake", 3 },
{ "What instrument did Ross intend to play at Monica and Chandlers Wedding?", "Bagpipe", "Drums", "Guitar", "Sax", 1 },
{ "What is Chandlers middle name?", "Nora", "Muriel", "Charles", "Francis", 2 },
{ "Who was Monicas first kiss?", "Chandler", "Pete", "Ross", "Richard", 3 },
{ "Chick Jr and Duck Jr get stuck in what?", "Toilet", "Foosball", "Bin", "Fridge", 2 },
{ "Who famously said PIVOT?", "Rachel", "Joey", "Monica", "Ross", 4 }
};

//Function for displaying on lcds.
void doDisplay(String mainLCD, String A1, String A2, String A3, String A4){
//Split question string between total lines and print on appropriate line.
  int stringStart = 0;
  int stringEnd = 20;
  int lcdLine = 0;

  for(lcdLine; lcdLine <= 3; lcdLine++){
    String displayString = mainLCD.substring(stringStart, stringEnd);//Create substring from main string within 20 chars.
          lcd.setCursor(0,lcdLine); //Set lcd line to required line.
          lcd.print(displayString); //Print 20 char substring.
              stringStart = stringEnd; //New substring start position is string end.
              stringEnd = stringEnd+20; //Add 20 to stringEnd to start the next 20 chars.
                
  }
  //Set answer screen.
  lcd2.setCursor(0, 0);
  lcd2.print(A1);
    lcd2.setCursor(7, 0);
    lcd2.print(A2);
      lcd2.setCursor(0, 1);
      lcd2.print(A3);
          lcd2.setCursor(7, 1);
          lcd2.print(A4);         
}

//Sound function.
void playSound(int doSound){
  switch (doSound){
    //Current answer sound.
    case 0:
    tone(buzzer,1000);    
      delay(200);
    tone(buzzer,500);    
      delay(200);
    tone(buzzer,1000);    
      delay(200);
        noTone(buzzer); 
    break;
    
    //Wrong answer sound.
    case 1:
    tone(buzzer,200);    
      delay(200);
        noTone(buzzer); 
    tone(buzzer,100);    
      delay(200);
        noTone(buzzer); 
    break;

    //Intro / gameover sound.
    case 2:
    tone(buzzer,1000);    
      delay(500);
        noTone(buzzer); 
    tone(buzzer,800);    
      delay(200);
        noTone(buzzer); 
    tone(buzzer,1000);    
      delay(200);
        noTone(buzzer);
    tone(buzzer,900);    
      delay(200);
    tone(buzzer,800);    
      delay(200);
        noTone(buzzer);
    break;
  }
}

//Function to run on end of game.
void doEnd(){
  lcd.setCursor(0,0);
  lcd.print("Game over");
    lcd.setCursor(0,1);
    lcd.print("Your score is:");
      lcd.setCursor(0,2);
      lcd.print(score);
        lcd.setCursor(0,3);
        lcd.print("Press any button.");
}


//Function for if answer is correct.
void doAnswer(int a){
      lcd.clear(); //Clear lcd one
      lcd2.clear(); //Clear lcd two
      lcd.setCursor(0,0);
        if(a==1){
          lcd.print("Correct answer!"); 
          score++; 
          playSound(0);
        }
          else{
            lcd.print("Wrong answer!"); 
            playSound(1);
            }
              lcd2.print("Next question"); //Print on lcd two
              lcd2.setCursor(0,1); //Set second row on lcd two.
              lcd2.print("Coming up"); //Print on lcd two.
              buttonPressed=0; //Reset stored button press value.
              delay(3000); //Delay 3 seconds so user can read screen.
              lcd.clear(); //Clear lcd one.
              lcd2.clear(); //Clear lcd two.
              questionNum++; //Move to next question.
}

void doButtons(){
  if(buttonPressed > 0 & welcome==0){ //If any button pressed.
  playSound(2);
      welcome=1; //Set welcome to 1 to show we have passed this stage.
      doQuestion = true;//Set first question
      lcd.clear(); //Clear lcd one.
      lcd2.clear(); //Clear lcd two.
      buttonPressed=0; //Reset button press.
      delay(1000); //Delay for one second.
      
  }
 else{
  if(buttonPressed > 0){ //As we reset button to 0, make sure it is more than 0.
        if(buttonPressed==answer){ 
            doAnswer(1); //Call answerCorrect function.             
        }
        else{
           doAnswer(0);        
        }
  }
 }
  
}

void loop() {
  if(questionNum > totalQuestions){ //Check if quiz should end.
      doEnd();
  }
  else{
    if(welcome == 0){
         doDisplay(gameMess[0][0], gameMess[0][1], gameMess[0][2], gameMess[0][3], gameMess[0][4]);
     }
     
    else{
      while(doQuestion){
        int Q = questionNum;
          doDisplay(Question[Q][0], Question[Q][1], Question[Q][2], Question[Q][3], Question[Q][4]);
          answer = Question[Q][5];
          Serial.print(questionNum);
          doQuestion=false;
          
    }
  }
}
  

    //Read button inputs.
    int b1 = digitalRead(8); 
    int b2 = digitalRead(9);
    int b3 = digitalRead(10);
    int b4 = digitalRead(11);

    //Assign button inputs to an number, 1-4
    if(b1==0){buttonPressed=1;} 
      if(b2==0){buttonPressed=2;}
        if(b3==0){buttonPressed=3;}
          if(b4==0){buttonPressed=4;}
doButtons();
    //Call doButton function which checks button press compared to answer.
     

}

It's just a quiz game.

I've checked the serial output and it matches a number that works if I specifically set the int Q to the same.

Thanks.

When you set Q to a literal number, the compiler hard codes the array elements into the code. Using a variable, the array access is at runtime, and you are not properly referencing the PROGMEM array.

2 Likes

If you allow QuestionNum to actually reach the value 10 you are calling for trouble.

Try changing this

To this (my personal preference)

if(questionNum >= totalQuestions){ //Check if quiz should end.

Or this (which should also work)

if(questionNum == totalQuestions){ //Check if quiz should end.


While at it, change

if (buttonPressed > 0 & welcome == 0) { //If any button pressed.

To

if (buttonPressed > 0 && welcome == 0) { //If any button pressed.

Look up the difference between operators & and && to see why I recommend this change

1 Like

Appreciate the reply, I was meant to get around to these but I don't even know why I put & and not &&.

Thanks.

Accurate, thanks dude, definitely need to look into PROGMEM more, I knew I had it too easy, haha!

All works as it should when I remove PROGMEM so 100% that.

Thanks.

1 Like

for (lcdLine; lcdLine <= 3; lcdLine++) {
Shouldn't that be:
for (lcdLine = 0; lcdLine <= 3; lcdLine++) {

You have a bunch of warnings about storing an 'int' in a 'char *'.

/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:36:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
 };
 ^
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:36:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
 };
 ^
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:49:1: warning: invalid conversion from 'int' to 'const char*' [-fpermissive]
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino: In function 'void doDisplay(String, String, String, String, String)':
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:58:15: warning: statement has no effect [-Wunused-value]
   for (lcdLine; lcdLine <= 3; lcdLine++) {
               ^
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino: In function 'void doButtons()':
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:157:21: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
   if (buttonPressed > 0 & welcome == 0) {  //If any button pressed.
       ~~~~~~~~~~~~~~^~~
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino: In function 'void loop()':
/private/var/folders/kq/89qrmhn9563d565c5th318kw0000gn/T/.arduinoIDE-unsaved2022108-21084-1jprzqy.ph4h/sketch_nov8a/sketch_nov8a.ino:189:31: warning: invalid conversion from 'const char*' to 'int' [-fpermissive]
         answer = Question[Q][5];
                  ~~~~~~~~~~~~~^
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::begin(uint8_t, uint8_t, uint8_t)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:66:39: warning: unused parameter 'cols' [-Wunused-parameter]
 void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
                                       ^~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::setDelay(int, int)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:307:39: warning: unused parameter 'cmdDelay' [-Wunused-parameter]
 void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
                                       ^~~~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:307:52: warning: unused parameter 'charDelay' [-Wunused-parameter]
 void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
                                                    ^~~~~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:310:50: warning: unused parameter 'graphtype' [-Wunused-parameter]
 uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
                                                  ^~~~~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t, uint8_t, uint8_t, uint8_t)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:311:55: warning: unused parameter 'row' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end){}
                                                       ^~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:311:68: warning: unused parameter 'column' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end){}
                                                                    ^~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:311:84: warning: unused parameter 'len' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end){}
                                                                                    ^~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:311:98: warning: unused parameter 'pixel_col_end' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end){}
                                                                                                  ^~~~~~~~~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::draw_vertical_graph(uint8_t, uint8_t, uint8_t, uint8_t)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:312:53: warning: unused parameter 'row' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_row_end){}
                                                     ^~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:312:66: warning: unused parameter 'column' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_row_end){}
                                                                  ^~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:312:82: warning: unused parameter 'len' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_row_end){}
                                                                                  ^~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:312:96: warning: unused parameter 'pixel_row_end' [-Wunused-parameter]
 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_row_end){}
                                                                                                ^~~~~~~~~~~~~
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::setContrast(uint8_t)':
/Users/john/Documents/Arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp:313:45: warning: unused parameter 'new_val' [-Wunused-parameter]
 void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
                                             ^~~~~~~
Sketch uses 12050 bytes (42%) of program storage space. Maximum is 28672 bytes.
Global variables use 1245 bytes (48%) of dynamic memory, leaving 1315 bytes for local variables. Maximum is 2560 bytes.

That's weird, I get no errors or warnings,

Sketch uses 9804 bytes (30%) of program storage space. Maximum is 32256 bytes.
Global variables use 1496 bytes (73%) of dynamic memory, leaving 552 bytes for local variables. Maximum is 2048 bytes.

Also, lcdLine is already defined as an int before the loop?

You probably have 'Compiler warnings:' in 'Preferences...' set to "None" (the unfortunate default).

1 Like

Damn I didn't realise, I'll clean that up, trying to be as accurate as I can !

Thanks for the heads up, I'll let you know how it goes.

Thanks again for the heads up, corrected all my warnings!

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