Quizmaster

Hello, I’m new to arduino and I want to build a quizmaster. A small system that detects which player pressed first. (At the moment it is still small but later I want to add some extra stuff).
I build the system already with logic IC’s but, now I want to make it with a microcontroller. So I have some knowledge of electronics but I’m new to microcontrollers and programming.

I wrote a sketch and it works. But I want to know if it is programmed the proper way. Or is there a better way to do it?
The biggest question I have, is how I deal with the time. Let me explain. Every command takes some time? In case I want to make the quizmaster a little bit more eye candy. With flashing LEDs and maybe later, when I know the controller a bit better, I can use the crystal display to show which player pressed. But how should I program the buttons so it is still a fare system? So player 1 has no advantage compared with player 4.

This is my sketch:

int led1 = 8;
int led2 = 9;
int player1 = 1;
int player2 = 2;
int resetbutton = 5;
boolean reset = LOW;
boolean pressed = LOW;
boolean pressed1 = LOW;
boolean pressed2 = LOW;

void setup () 
{
 pinMode (led1, OUTPUT);
 pinMode (player1, INPUT);
 pinMode (led2, OUTPUT);
 pinMode (player2, INPUT);
 pinMode (resetbutton, INPUT);
}

void loop ()

{
  
  if (digitalRead (player1) == HIGH && reset == LOW && pressed == LOW || pressed1 == HIGH )
  {
   digitalWrite (led1, HIGH);
   pressed1 = HIGH;
   pressed = HIGH;
   
  }
  else 
  {
   digitalWrite (led1, LOW); 
  }
  
  if (digitalRead (player2) == HIGH && reset == LOW && pressed == LOW || pressed2 == HIGH )
  {
   digitalWrite (led2, HIGH);
   pressed2 = HIGH;
   pressed = HIGH;
  }
  else 
  {
   digitalWrite (led2, LOW); 
  }
  
  
  if (digitalRead (resetbutton) == HIGH)
  {
   reset = HIGH;  
   pressed = LOW;
   pressed1 = LOW;
   pressed2 = LOW;
  }
  else 
  {
   reset = LOW; 
  }
}

If your concerned with timing, then you can use interrupts, but for something like this, interrupts are overkill. Plus anything other than a Mega, will only have 2 interrupts.

In this case since you are going to be checking which person was first, stay away from the delay() function, it will be what kills your code. However if you do need some kind of delay, then you can use the millis() function to keep track of the passing time and do something when you need it to. Take a look at your example sketch Blink Without Delay, it will help you a lot.

No matter what you do there is a very small chance that two people will press their buttons at the same time. Of course they can't know that so as long as the system gives a reasonable result everyone will be happy.

I think the simplest way to do that is to read all the buttons in immediate succession - for example

void readButtons() {
   for (byte n = 0; n < numButtons; n++) {
      buttonPressed[n] = false;  // set all buttons to not-pressed
   }

   for (byte n = 0; n < numButtons; n++) {
      if( digitalRead(buttonPin[n]) == LOW) {     // meaning the button was pressed
          buttonPressed[n] = true;
          break;    // don't read any more buttons
      }
  }
}

Later in your code you can check which button was pressed and do what ever is needed

I'm assuming the button pins are set as INPUT_PULLUP and that the buttons pull the pin LOW when pressed.

It is possble for up to 6 buttons on an Uno (8 on a Mega) to be read at exactly the same instant using Direct Port Manipulation but I don't think it will be any benefit in this case. The FOR loop above will read them all in a millisecond or less.

The example in the first post in this Thread may be helpful to illustrate how your code could be organized - though that was not its original purpose.

...R

I'm having problems with reading out the buttons. I think it is because the "break" comment? When i hit the break, the program freeze. Or is this because the readButtons is running out of the loop?

Can you help me to read out the switches?

i run a small test with a if statement, but that didn't work,
in future i would like to use a switch case

case 0 = button 1 = true
case 1 = button 2 = true
case 2 = button 3 = true
case 3 = button 4= true

i know how to use cases but i don't know how to put the buttonpressed array in some kind of variable.

so i need for example a variable int witchButton
and this variable can be 1,2,3 or 4. but how do you do that?

this is wath i made from the code:

int buttonPin [] = {A1,A2,A3,A4};
int buttonPressed[]={false,false,false,false};

void setup () 
{
Serial.begin (9600);
for (int thisPin = 8; thisPin < 14; thisPin ++)
  { 
    pinMode (thisPin, OUTPUT); // for loop, pin 8 to 13 as output for the leds
for (int i = 8; i < 14; i ++)
  { 
     digitalWrite (i,LOW);    // switch the leds off
}
}

}
void readButtons() {
   for (byte n = 0; n < 5; n++) {
      buttonPressed[n] = false;  // set all buttons to not-pressed
   }

   for (byte n = 0; n < 5; n++) {
      if( digitalRead(buttonPin[n]) == HIGH) {     // meaning the button was pressed
          buttonPressed[n] = true;
          break;    // don't read any more buttons
          
      }
  }
}


void loop ()
{
  readButtons ();

  int witchButton = ? //value that came out of buttonPressed array 
  switch (witchButton) 
  {
    case 0: 
        //do something 
        break;
    case 1:
        //do something
        break;
    case 2: 
        //do something 
        break;
    case 3:
        //do something
        break;
    default;
        //do something
        break;
  }
}

You haven't set pinMode for the button pins. They should each be set as INPUT_PULLUP.

You could set the variable whichButton like this

for (byte n = 0; n < numButtons; n++) {
   if (buttonPressed[n] == true) {
       whichButton = n;
   }
}

and if you only want to use the button like that you could probably simplify things by changing readButton() to this to give you the value in whichButton directly.

void readButtons() {
   for (byte n = 0; n < numButtons; n++) {
      buttonPressed[n] = false;  // set all buttons to not-pressed
   }

   for (byte n = 0; n < numButtons; n++) {
      if( digitalRead(buttonPin[n]) == LOW) {     // meaning the button was pressed
          whichButton = n;
          break;    // don't read any more buttons
      }
  }
}

I can't figure out from your description what problem you are having that you think may be due to break;, or even which break; you are talking about.

...R