Arduino Game Board - Q/A

Just to show that you can remap the Question switches to different Answer switches.

In this version, pushing a switch connected on pin 8, remaps the Q and As as in the arrays below:

//original question and answer associations
//           Question switches  2  4  6  22  24  26  28  30  32  34  36  38
byte originalAnswers[12]     = {3, 5, 7, 23, 25, 27, 29, 31, 33, 35, 37, 39};

//remapped question and answer associations
//           Question switches  2  4  6  22  24  26  28  30  32  34  36  38
byte remappedAnswers[12]     = {7, 3, 5, 39, 37, 35, 33, 31, 29, 27, 25, 23};

Sketch version 1.08 (with remapping option)

//
// https://forum.arduino.cc/t/arduino-game-board-q-a/927329
//
//*********************************************************************************
// Version   YY/MM/DD   Description
// =======   ========   ===========
// 1.00      21 11 20   Working sketch
// 1.02      21 11 20   Added a Structure definition so we can easily have 12 QandAs
// 1.03      21 11 20   Needs additions and testing for 12 switches
// 1.04      21 11 21   Combined some tests; added some comments
// 1.05      21 11 21   Added trapping for more than 2 switches pressed;
//                      added heartbeat LED and buzzer
// 1.06      21 11 21   Move the switches to different controller pins
// 1.07      21 11 27   To speed up execution time, added switchChangeFlag
// 1.08      21 11 28   Option to remap the question switches to different answer switches
//

// Matching a question to the correct answer turns on the "Correct Green LED"
// Matching a question to the wrong answer turns on the "Wrong Red LED"
//

//*********************************************************************************

//if the next line is commented, NO debug code is generated
//#define DEBUG

#ifdef DEBUG
//                                for oscilloscope triggering
#define PULSE9                    cli(); PINB = bit(PINB1); PINB = bit(PINB1); sei()

#else
#define PULSE9                    //nothing defined

#endif

//*********************************************************************************

//5V---[Internal 50k Resistor]---Pin---[Switch]---GND
#define PUSHED                    LOW

//Pin---[220R]---[A->|-K]---GND
#define LEDon                     HIGH
#define LEDoff                    LOW

#define ENABLED                   true
#define DISABLED                  false

//******************************************


//const byte buzzer               = 12;
//const byte heartbeatLED         = 13;
//const byte GreenLED             = 11;       //Correct Answer LED
//const byte RedLED               = 10;       //Wrong Answer LED

const byte remapSwitch          = 8;

#ifdef DEBUG
const byte pulsePin             = 9;      //pin PINB1, for oscilloscope triggering
#endif

const byte buzzer               = 50;
const byte heartbeatLED         = 51;
const byte GreenLED             = 52;       //Correct Answer LED
const byte RedLED               = 53;       //Wrong Answer LED

bool switchChangeFlag           = DISABLED;

byte RedLEDflag;
byte GreenLEDFlag;
byte switchCount;
byte currentState;
byte lastRemapSwitch            = !PUSHED;

//******************************************
//define the Question and Answer Structure
struct QandA
{
  const byte Qpin;
  byte       Apin;
  byte       bitNumQ;
  byte       bitNumA;
  byte       lastStateQ;
  byte       lastStateA;

}; //END of struct QandA

//******************************************
//the number of QandA pairs to be defined
const byte numQuestions         = 12;

//define all the objects
QandA pairNum[numQuestions]     =
{
  // pins    bits   last Q   last A
  //Q   A   Q   A
  //======  ====== ======== ========
  { 2,  3,  0,  1, !PUSHED, !PUSHED},    //pair #1     Qpin Apin bitNumQ bitNumA lastStateQ lastStateA
  { 4,  5,  2,  3, !PUSHED, !PUSHED},    //pair #2
  { 6,  7,  4,  5, !PUSHED, !PUSHED},    //pair #3
  {22, 23,  6,  7, !PUSHED, !PUSHED},    //pair #4
  {24, 25,  8,  9, !PUSHED, !PUSHED},    //pair #5
  {26, 27, 10, 11, !PUSHED, !PUSHED},    //pair #6
  {28, 29, 12, 13, !PUSHED, !PUSHED},    //pair #7
  {30, 31, 14, 15, !PUSHED, !PUSHED},    //pair #8
  {32, 33, 16, 17, !PUSHED, !PUSHED},    //pair #9
  {34, 35, 18, 19, !PUSHED, !PUSHED},    //pair #10
  {36, 37, 20, 21, !PUSHED, !PUSHED},    //pair #11
  {38, 39, 22, 23, !PUSHED, !PUSHED}     //pair #12
};

//
//END of our Structure and definition

//******************************************
//original question and answer associations
//           Question switches  2  4  6  22  24  26  28  30  32  34  36  38
byte originalAnswers[12]     = {3, 5, 7, 23, 25, 27, 29, 31, 33, 35, 37, 39};

//remapped question and answer associations
//           Question switches  2  4  6  22  24  26  28  30  32  34  36  38
byte remappedAnswers[12]     = {7, 3, 5, 39, 37, 35, 33, 31, 29, 27, 25, 23};

//******************************************
//The flag is 32 bits, corresponds to 16 question/answer pairs
//A=Answer, Q=Question           AQAQAQAQAQAQAQAQAQAQAQAQAQAQAQAQ
//Q and A number                 11111111111111
//                               66554433221100998877665544332211
//                               --------------------------------
//Bit                            3322222222221111111111
//Number                         10987654321098765432109876543210
unsigned long Flag           = 0b00000000000000000000000000000000;  //32 bits

//question switch pushed
unsigned long question[12]   = {1, 4, 16, 64,  256, 1024, 4096, 16384,  65536, 262144, 1048576, 4194304};
//element #                     0  1   2   3     4     5     6      7       8       9       10       11

//answer switch pushed
unsigned long answer[12]     = {2, 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608};
//element #                     0  1   2    3    4     5     6      7       8       9       10       11

//timing stuff
unsigned long switchMillis;
unsigned long heartbeatMillis;

//*********************************************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(buzzer, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);
  pinMode(GreenLED, OUTPUT);
  pinMode(RedLED, OUTPUT);

#ifdef DEBUG
  pinMode(pulsePin , OUTPUT);
  digitalWrite(pulsePin, LOW);
#endif

  //***************************************
  for (byte x = 0; x < numQuestions; x++)
  {
    pinMode(pairNum[x].Qpin, INPUT_PULLUP);
    pinMode(pairNum[x].Apin, INPUT_PULLUP);
  }

  pinMode(remapSwitch, INPUT_PULLUP);

} //END of setup()


//*********************************************************************************
void loop()
{
  //***************************************
  //time to toggle the heartbeat LED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart the TIMER
    heartbeatMillis = millis();

    //toggle LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));

  }

  //******************************************
  //is it time to check the switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart the TIMER
    switchMillis = millis();

    checkSwitches();

  }

  //******************************************
  //has there been a state change in any of the switches ?
  if (switchChangeFlag == ENABLED)
  {
    //yes, okay, we will deal with it
    switchChangeFlag = DISABLED;

    controlLEDs();
  }

  //******************************************
  //other none blocking code goes here
  //******************************************

} //END of loop()


//*********************************************************************************
void controlLEDs()
{
  //***********************************************
  //control the LEDs as per switches pushed
  //
  //initialize
  RedLEDflag = LEDon;

  //******************************
  //more than 2 switches pressed ?
  if (switchCount > 2)
  {
    GreenLEDFlag = LEDoff;
  }

  //******************************
  //no switches are pushed ?
  else if (Flag == 0)
  {
    GreenLEDFlag = LEDoff;
    RedLEDflag = LEDoff;
  }

  //******************************
  else
  {
    //check what switches are being pushed
    for (byte x = 0; x < 12; x++)
    {
      //for oscilloscope triggering
      PULSE9;

      //**************
      //are the correct switches are pushed ?
      if (Flag == question[x] + answer[x])
      {
        GreenLEDFlag = LEDon;
        RedLEDflag = LEDoff;

        //we found them, no need to go further
        break;
      }

      //**************
      //is 1 question switch is pushed ?
      else if (Flag == question[x])
      {
        GreenLEDFlag = LEDoff;
        RedLEDflag = LEDoff;

        //we found it, no need to go further
        break;
      }

      //**************
      //is 1 answer switch is pushed ?
      else if (Flag == answer[x])
      {
        GreenLEDFlag = LEDoff;
        RedLEDflag = LEDoff;

        //we found it, no need to go further
        break;
      }

    } //END of for (byte x = 0; x < 12; x++)

  } //END of else()

  //***********************************************
  //update the LEDs and sound the buzzer as needed
  digitalWrite(GreenLED, GreenLEDFlag);
  digitalWrite(RedLED, RedLEDflag);

  //**************
  //correct buzzer sound
  if (GreenLEDFlag == LEDon)
  {
    tone(buzzer, 4000, 500);
  }

  //**************
  //wrong buzzer sound
  else if (RedLEDflag == LEDon)
  {
    tone(buzzer, 500, 500);
  }

  //***********************************************

} //END of  controlLEDs()


//*********************************************************************************
void checkSwitches()
{
  //***********************************************
  //scan all the switches to see if there are changes in state, act accordingly
  for (byte x = 0; x < numQuestions; x++)
  {
    //***********************************************
    //current                                        Q u e s t i o n   s w i t c h
    currentState = digitalRead(pairNum[x].Qpin);

    //******************************
    //was there a change in state ?
    if (pairNum[x].lastStateQ != currentState)
    {
      //update to the new state
      pairNum[x].lastStateQ = currentState;

      //a switch has changed state, Flag it
      switchChangeFlag = ENABLED;

      //******************
      //was the switch PUSHED ?
      if (currentState == PUSHED)
      {
        switchCount++;

        //set the associated flag bit
        Flag = Flag | bit(pairNum[x].bitNumQ);
      }

      //******************
      //the switch was released
      else
      {
        switchCount--;

        //reset the associated flag bit
        Flag = Flag & ~bit(pairNum[x].bitNumQ);
      }

      //******************
      //print the Flag so we can see the total
      Serial.print(Flag);

      //print the number of switches being pressed
      Serial.print("\t Switches pressed = ");
      Serial.println(switchCount);

    } //END of  if (pairNum[x].lastStateQ != state)

    //***********************************************
    //current                                        A n s w e r   s w i t c h
    currentState = digitalRead(pairNum[x].Apin);

    //******************************
    //was there a change in state ?
    if (pairNum[x].lastStateA != currentState)
    {
      //update to the new state
      pairNum[x].lastStateA = currentState;


      //a switch has changed state, Flag it
      switchChangeFlag = ENABLED;

      //******************
      //was the switch PUSHED ?
      if (currentState == PUSHED)
      {
        switchCount++;

        //set the associated flag bit
        Flag = Flag | bit(pairNum[x].bitNumA);
      }

      //******************
      //the switch was released
      else
      {
        switchCount--;

        //reset the associated flag bit
        Flag = Flag & ~bit(pairNum[x].bitNumA);
      }

      //******************
      //print the Flag so we can see the total
      Serial.print(Flag);

      //print the number of switches being pressed
      Serial.print("\t Switches pressed = ");
      Serial.println(switchCount);

    } //END of  if (pairNum[x].lastStateA != state)

  } //END of  for (byte x = 0; x < numQuestions; x++)


  //***********************************************
  //                                               r e m a p S w i t c h
  currentState = digitalRead(remapSwitch);

  //******************************
  //was there a change in state ?
  if (lastRemapSwitch != currentState)
  {
    //update to the new state
    lastRemapSwitch = currentState;

    //******************
    //was the switch PUSHED ?
    if (currentState == PUSHED)
    {
      //the question switches are remapped to new answer switches
      for (byte x = 0; x < numQuestions; x++)
      {
        pairNum[x].Apin = remappedAnswers[x];
      }

      Serial.println("\nQuestion switches have been remapped.\n");
    }
  }

} //END of checkSwitches()

//*********************************************************************************
1 Like