Make an arduino "quiz" systeem

Hi,

I'm working on a project and was wondering if someone here could help me!

What my goal is: I want a small machine that displays a question and 3 answers underneath it. The user will then be able to press on a button to "tell" the system which answer they think is correct / fits the best. Then the arduino will add a point to a variable if the answer is correct. The questions and answers will be programmed into the code.

EXAMPLE:

Question: How big is the room you are standing in?

A: 0-15 square meter [if the player answers this question the arduino will add 0 points]

B: 15-30 square meter [if the player answers this question the arduino will add 1 points]

C: 30 and more square meter [if the player answers this question the arduino will add 2 points]

So far I got the display running, but my only problem is with the answers. How can you make a program that adds for example 0 point to a variable if button A is pressed, 1 if button B is pressed and 2 if button C is pressed (and then go to a new question if a answer is pressed)?

Thanks in advance!

Have you looked at any of the programming examples provided with the IDE?
I'm pretty sure switch handling and addition are covered.

cekstuffertz:
So far I got the display running, but my only problem is with the answers. How can you make a program that adds for example 0 point to a variable if button A is pressed, 1 if button B is pressed and 2 if button C is pressed (and then go to a new question if a answer is pressed)?

First thing would be to find a suitable data structure to store all the questions and answers.

As you are using much text and the RAM of most Arduino boards is very limited, you will most likely want to store the questions and answers in PROGMEM (flash) memory.

Then you could create an array that holds pointers to all the text you want to use. When you need the text for displaying it, you'd have to retrieve it from PROGMEM by an index into the array (index in the array == question number in the quiz).

Example data structures:

const char Q0[] PROGMEM= "What do the Japanese people call their own country?";
const char Q0A1[] PROGMEM= "Nippon";
const char Q0A2[] PROGMEM= "Honolulu";
const char Q0A3[] PROGMEM= "Hong Kong";

const char Q1[] PROGMEM= "How big is the room you are standing in?";
const char Q1A1[] PROGMEM= "0-15 square meter";
const char Q1A2[] PROGMEM= "15-30 square meter";
const char Q1A3[] PROGMEM= "30 and more square meter";

const char Q2[] PROGMEM= "What is the name of the desert area in Mexico?";
const char Q2A1[] PROGMEM= "Sahara";
const char Q2A2[] PROGMEM= "Atacama";
const char Q2A3[] PROGMEM= "Sonora";

const char Q3[] PROGMEM= "How many time zones are there in the world?";
const char Q3A1[] PROGMEM= "5";
const char Q3A2[] PROGMEM= "12";
const char Q3A3[] PROGMEM= "24";

const char Q4[] PROGMEM= "Which river is flowing through Rome?";
const char Q4A1[] PROGMEM= "Tiber";
const char Q4A2[] PROGMEM= "Donau";
const char Q4A3[] PROGMEM= "Wolga";

struct question_t {const char* q; const char *a1; const char *a2; const char *a3; byte correct;};

// Now fill a struct array of question text, answer texts and correct answer number
question_t questions[]={
 {Q0, Q0A1, Q0A2, Q0A3, 1},
 {Q1, Q1A1, Q1A2, Q1A3, 2},  
 {Q2, Q2A1, Q2A2, Q2A3, 3},  
 {Q3, Q3A1, Q3A2, Q3A3, 3},  
 {Q4, Q4A1, Q4A2, Q4A3, 1},  
};

const int NUMQUESTIONS= sizeof(questions)/sizeof(question_t);

Otherwise your sketch might use too much RAM, even with small quizzes, especially with UNO boards.

I’m actually doing something very similar right now. I followed @jurs suggestion and I have my questions laid out just like his example

struct question_t {
  const char* q;
  const char *a1;
  const char *a2;
  const char *a3;
  int pa1; int pa2; int pa3; //scores
};

// questions, answers and scores
question_t questions[] = {
  {Q0, Q0A1, Q0A2, Q0A3, -1, 0, 1},
  {Q1, Q1A1, Q1A2, Q1A3, 0, 0, 2},
  {Q2, Q2A1, Q2A2, Q2A3, 5, 4, 3}
};

const int NUMQUESTIONS = sizeof(questions) / sizeof(question_t);

My problem now is printing the questions. To try it I’m making a simple cycle just to print them one after the other. The for works as intended. I’m trying to do it this way:

for (int i = 0; i < NUMQUESTIONS ; i++)
  {
    Serial.print(NUMQUESTIONS - i); Serial.println(" questions remaining: "); //this works fine

    Serial.println(questions[i].q); //this is the problem

    delay(500);
  }

So, I’m trying to use Serial.println(questions*.q) but it only prints jiberish, however, if I remove PROGMEM from the initial declarations, it prints fine.*
How can I corrently print the things in PROGMEM? Thank you very much

How can I corrently print the things in PROGMEM?

By reading the data from PROGMEM, and not from RAM.

AWOL:
By reading the data from PROGMEM, and not from RAM.

What would be the instruction for that in this case?

I garantee you I'm not asking without researching first, but I'm not very good at arduino yet.

When in doubt, RTFM

Do I need to change any of the previous code? I've tried a lot of different iterations but I'm not getting there. I had read that page before posting in this thread and tried some different things from there, but still no results.

I apreciate being lead in the right direction and thank you for your time, but I'd be very grateful if you could let me know how the correct printing instruction would be.

Some variations I have tried in the comments

BPMorais:
Do I need to change any of the previous code?

Changes for doing WHAT?
Doing a full featured quiz like "who wants to be a millionaire", playable on Arduino Serial in the serial monitor?

Or just printing the questions given in reply #2 to the serial monitor?

Doing a full-featured quiz program from the data given in #2 requires many additional lines of code.

Just printing the questions (and possible answers) to Serial can be done with only a few additional code lines.

jurs:
Changes for doing WHAT?
Doing a full featured quiz like "who wants to be a millionaire", playable on Arduino Serial in the serial monitor?
Or just printing the questions given in reply #2 to the serial monitor?

The final product is supposed to be somewhat similar to who wants to be a milionaire, yes. A program that gives the user 1 question and answers and requests him to chose one of the options to move along to the next question. All interaction done through the serial. Wrong answers don't make you lose, they just give 0 points or negative.

I understand that this will require other pieces of coding, such as waitting for the user to input their answer and processing the score. But I'm taking it one step at a time, and right now my challenge is printing the questions/answers that I have saved in PROGMEM.

BPMorais:
The final product is supposed to be somewhat similar to who wants to be a milionaire, yes. A program that gives the user 1 question and answers and requests him to chose one of the options to move along to the next question. All interaction done through the serial. Wrong answers don’t make you lose, they just give 0 points or negative.

I understand that this will require other pieces of coding, such as waitting for the user to input their answer and processing the score. But I’m taking it one step at a time, and right now my challenge is printing the questions/answers that I have saved in PROGMEM.

OK, here is another piece of code, which can print all the questions and possible answers from PROGMEM to Serial.

I have made two functions for you:

  1. function serial_P will only print a string from PROGMEM to Serial

  2. function serialLine_P will do the same, then finish with a Serial.println();

Here is the whole sketch code example:

const char Q0[] PROGMEM= "What do the Japanese people call their own country?";
const char Q0A1[] PROGMEM= "Nippon";
const char Q0A2[] PROGMEM= "Honolulu";
const char Q0A3[] PROGMEM= "Hong Kong";

const char Q1[] PROGMEM= "How big is the room you are standing in?";
const char Q1A1[] PROGMEM= "0-15 square meter";
const char Q1A2[] PROGMEM= "15-30 square meter";
const char Q1A3[] PROGMEM= "30 and more square meter";

const char Q2[] PROGMEM= "What is the name of the desert area in Mexico?";
const char Q2A1[] PROGMEM= "Sahara";
const char Q2A2[] PROGMEM= "Atacama";
const char Q2A3[] PROGMEM= "Sonora";

const char Q3[] PROGMEM= "How many time zones are there in the world?";
const char Q3A1[] PROGMEM= "5";
const char Q3A2[] PROGMEM= "12";
const char Q3A3[] PROGMEM= "24";

const char Q4[] PROGMEM= "Which river is flowing through Rome?";
const char Q4A1[] PROGMEM= "Tiber";
const char Q4A2[] PROGMEM= "Donau";
const char Q4A3[] PROGMEM= "Wolga";

struct question_t {const char* q; const char *a1; const char *a2; const char *a3; byte correct;};

// Now fill a struct array of question text, answer texts and correct answer number
question_t questions[]={
 {Q0, Q0A1, Q0A2, Q0A3, 1},
 {Q1, Q1A1, Q1A2, Q1A3, 2},  
 {Q2, Q2A1, Q2A2, Q2A3, 3},  
 {Q3, Q3A1, Q3A2, Q3A3, 3},  
 {Q4, Q4A1, Q4A2, Q4A3, 1},  
};

const int NUMQUESTIONS= sizeof(questions)/sizeof(question_t);


void serial_P(PGM_P str)
{
  // this function will print the string str from PROGMEM to Serial
  while(char c = pgm_read_byte(str))
  {
    
    str++; Serial.write(c);
  }
}


void serialLine_P(PGM_P str)
  // this function will print the string str from PROGMEM to Serial and a CR/LF newline
{
  serial_P(str);
  Serial.println();
}




void setup()
{
  Serial.begin(9600);
  for (int i=0;i<NUMQUESTIONS;i++)
  {// we now print all questions and possible answers to Serial
    // be ware that array index starts with zero, but question numbering starts with one!
    Serial.print("Question #");  Serial.print(i+1);Serial.print(": ");
    serialLine_P(questions[i].q);
    Serial.println("possible answers:");
Serial.print("1: ");serialLine_P(questions[i].a1);
Serial.print("2: ");serialLine_P(questions[i].a2);
Serial.print("3: ");serialLine_P(questions[i].a3);
Serial.println();        
  }
}

void loop()
{
}

Thank you jurs, this has been extremely helpful :slight_smile: