ArduMem

About: Student interested in electronics and programming :)

Intro: ArduMem

ArduMem is a memory game made using the Arduino. The rules are simple: You will see few random blinks and then you have to repeat the blinks in the correct order. We will make two versions: the first will be made on prototype board, and the second one will be made on our PCB :)

So let's get started!!!

Step 1: (Protoboard Version) Parts and Tools

Parts:

  1. Arduino Uno compatible board - ebay
  2. 1 x Prototype board - ebay
  3. 9 x (6 mm x 6 mm) Momentary Tactile Push Button Switch - ebay
  4. 9 x (5 mm) LEDs - ebay
  5. 3 x 1000 Ohm resistor (Brown, Black, Red) - ebay
  6. 1 x 12 pin Single row female header - ebay
  7. Breadboard Male to Male Wires - ebay

Tools:

  1. Solder Iron
  2. Solder
  3. Wires


Step 2: (Protoboard Version) Creating the Matrices

This project consists of two 3x3 matrices, one for the LEDs and one for the tactical switches. We use matrices, because in this way we will only need 6 Arduino pins to control the LEDs and 6 Arduino pins to control the switches, 12 pins in total. I used 3x3 matrices, but you can make matrices with any dimensions, but remember for M x N matrix you will need M+N pins in total. Because we have two matrices, you will need 2(M+N) pins in total, so be sure your Arduino has enough pins.

The LED matrix we will create is common-row cathode, which means the cathodes of LEDs in a row and anodes of LEDs in a column are connected.

Get the prototype board and arrange the switches and LEDs like on the picture. Solder them to the board without making connection. Now we need to wire them. Check the schematic diagram. Also, eagle schematic file is attached.

First the LED matrix:

  • In a row, we need to wire the cathodes of the LEDs
  • In a column, we need to wire the anodes of the LEDs

I have labelled the image, so you need to connect cathodes of LEDs labelled 1, 2, 3 and 4, 5, 6 and 7, 8, 9, and anodes of LEDs labelled 1, 4, 7 and 2, 5, 8 and 3, 6, 9 (red wires are the connections between LEDs).

Then wire the switches like shown in the diagram (pins numbered 1,2 on schematics are connected, also pins 3,4). In the image, wire switches labeled 1, 2, 3 and 4, 5, 6 and 7, 8, 9 in row, and switches labeled 1, 4, 7 and 2, 5, 8 and 3, 6, 9 in column (blue wires are the connections between switches).

Then put the resistors and wire them, each one for each LED column.

Now connect every row and column to the header pins. I have connected them like this(from left to right):

    1. empty, not needed
    2. LED Column 1
    3. LED Column 2
    4. LED Column 3
    5. LED Row 1
    6. LED Row 2
    7. LED Row 3
    8. Switch Column 1
    9. Switch Column 2
    10. Switch Column 3
    11. Switch Row 1
    12. Switch Row 2
    13. Switch Row 3

    Finally we can place breadboard wire to every pin and get to the next part - wiring and programming the Arduino.

    Step 3: (PCB Version) Parts and Tools

    Parts:

    1. Arduino Uno compatible board - ebay
    2. 1 x Single side PCB circuit board (100 mm x 160 mm minimum size) - ebay
    3. 9 x (12 mm x 12 mm) Momentary Tactile Push Button Switch - ebay
    4. 9 x (10 mm) LEDs - ebay
    5. 3 x 470 Ohm resistor (Yellow, Purple, Brown) - ebay
    6. 1 x 12 pin Single row female header - ebay
    7. Breadboard Male to Male Wires - ebay

    Tools:

    1. Solder Iron
    2. Solder
    3. Every other tools you would need to develop the PCB, depends on the method you choose

    Step 4: (PCB Version) Creating the Matrices

    First, we need to develop the PCB. I have included eagle files and layout ready to print in the archive in attachments. LedButtonMatrix10.pdf contains the layout. You can use any method you like - toner transfer, UV exposure, or because the lines are straight, you can draw the layout using water resistant permanent marker, the method I used. After drawing the connections, the next step is to etch the board. I used ferric chloride for this step. Then clear the board using acetone or nitro diluent. Finally, drill the holes. Good tip is to place stick tape all over the connection side of the board, and mark the drills with marker.

    Then just place the components (there is layout with parts also included in the archive), and solder them.

    Now here are the connector pins:

    • First connector is the switches' connector:
      1. Row 1
      2. Row 2
      3. Row 3
      4. Column 1
      5. Column 2
      6. Column 3
    • Second connector is the LEDs' connector:
      1. Row 1
      2. Row 2
      3. Row 3
      4. Column 1
      5. Column 2
      6. Column 3

    Next, let's program the Arduino :)

    Step 5: Programming the Arduino

    After we created the matrices, now it's time to make the game using our Arduino. I used Arduino Uno, you can use any Arduino that has at least 12 pins.

    Now let's take a look at the code (available as attachment too):

    /*
     * ArduMem - Arduino Memory Game
     * Author: Bojan Sofronievski
     * Last updated: 22 AUG 2018
     */
    #include <Keypad.h>
    
    const byte nRows = 3;  //number of rows in the matrices
    const byte nCols = 3;  //number of columns in the matrices
    byte ledRows[nRows] = {7, 6, 5}; //pins of LED matrix's rows
    byte ledCols[nCols] = {4, 3, 2}; //pins of LED matrix's columns
    byte btnRows[nRows] = {13, 12, 11}; //pins of Switch matrix's rows
    byte btnCols[nCols] = {10, 9, 8}; //pins of Switch matrix's columns
    char keys[nRows][nCols] =
    {
      {'0', '1', '2'},
      {'3', '4', '5'},
      {'6', '7', '8'},
    }; //if you have different number of rows or columns than 3x3, edit this array
    
    Keypad keypad = Keypad( makeKeymap(keys), btnRows, btnCols, nRows, nCols );
    
    byte patterns[][3] =
    {
      {
        B101,
        B010,
        B010
      },
      {
        B101,
        B010,
        B101
      }
    }; //if you have different number of rows or columns than 3x3, edit this array
    
    const byte level = 4; //higher the level, more blinks to memorize
    const long pause = 1000;
    byte randomNumbers[level]; //array for random blinks
    
    void ledTurnOffAll(); //function to turn all LEDs off
    void ledTurnOnAll(); //function to turn all LEDs on
    void ledTurnOn(byte pos); //function to turn particular LED on
    void setColumn(byte pattern); //function used to set particular column
    void showPattern(byte* pattern); //function for showing patterns on the LED matrix
    
    void setup()
    {
      for (byte thisPin = 0; thisPin < nRows; thisPin++)
      {
        pinMode(ledRows[thisPin], OUTPUT);
      }
      for (byte thisPin = 0; thisPin < nCols; thisPin++)
      {
        pinMode(ledCols[thisPin], OUTPUT);
      }
      randomSeed(analogRead(0));
      ledTurnOffAll();
    }
    
    void loop()
    {
      //Generate random blinks
      for (byte i = 0; i < level; i++)
        randomNumbers[i] = random(nRows * nCols);
    
      //Prepare for game
      ledTurnOnAll();
      delay(pause);
      ledTurnOffAll();
      delay(pause);<br>
      //Show the blinks
      for (byte i = 0; i < level; i++)
      {
        ledTurnOn(randomNumbers[i]);
        delay(pause);
        ledTurnOffAll();
        delay(500);
      }
    
      //Preapare for game
      ledTurnOnAll();
      delay(pause);
      ledTurnOffAll();
    
      //Game starts here
      boolean guess = false;
      byte p = 0;
      while (!guess)
      {
        char key = keypad.waitForKey();
        if (key == randomNumbers[p] + '0')
        {
          ledTurnOn(randomNumbers[p]);
          delay(1000);
          ledTurnOffAll();
          if (p == level - 1) guess = true;
          p++;
        }
        else
        {
          showPattern(patterns[1]);
          ledTurnOffAll();
          break;
        }
      }
      if (guess)
      {
        showPattern(patterns[0]);
        ledTurnOffAll();
      }
      delay(pause);
    }
    
    void ledTurnOffAll()
    {
      for (byte thisPin = 0; thisPin < nRows; thisPin++)
      {
        digitalWrite(ledRows[thisPin], HIGH);
      }
      for (byte thisPin = 0; thisPin < nCols; thisPin++)
      {
        digitalWrite(ledCols[thisPin], LOW);
      }
    }
    
    void ledTurnOnAll()
    {
      for (byte thisPin = 0; thisPin < nRows; thisPin++)
      {
        digitalWrite(ledRows[thisPin], LOW);
      }
      for (byte thisPin = 0; thisPin < nCols; thisPin++)
      {
        digitalWrite(ledCols[thisPin], HIGH);
      }
    }
    
    void ledTurnOn(byte pos)
    {
      digitalWrite(ledRows[pos / 3], LOW);
      digitalWrite(ledCols[pos % 3], HIGH);
    }
    
    void SetColumn(byte pattern)
    {
      for (int i = nCols - 1; i >= 0; i--, pattern >>= 1)
      {
        digitalWrite(ledCols[i], ~pattern & 1 ? LOW : HIGH);
      }
    }
    
    void showPattern(byte* pattern)
    {
      int i = 0;
      while (i <= 300)
      {
        int last_row = nRows - 1;
        for (int row = 0; row < nRows; last_row = row++)
        {
          digitalWrite(ledRows[row], LOW);
          digitalWrite(ledRows[last_row], HIGH);
          SetColumn(pattern[row]);
          delay(3);
        }
        i++;
      }
    }

    Firstly, install the Keypad library if you don't have it: Arduino Keypad Library

    Connect the matrices' board to the Arduino.

    Be sure that the arrays ledRows, ledCols, btnRows and btnCols are matching the pins you have connected the matrices' elements to the Arduino. For example the first element in ledRows array is the pin number where you have connected the first row of the LED matrix, the second element is the second row and the third element is the third row. It is also possible to modify the code for matrices with different dimensions than 3x3, I added comments to those places in the code.

    Then simply upload the code and we are done. The game is ready to play :)

    Step 6: How to Play and Future Improvements

    At the beginning of every game, every LED will turn on, then off. Now LEDs will start blinking. Based on this version, 4 LEDs will blink. After that, again every LED will turn on, then off. Now it's your turn to play the game. Press the buttons in correct order as the LEDs blinked. If you get all correct, the Y shape will be displayed. If you make mistake, immediately X shape will be displayed. After this, the games starts all over again.

    How can this game be improved?

    Now we can control the level only if we change the constant in the code. We can add switch with three positions, and every position can represent level - easy, medium, hard. Based on the level, the numbers of blinks to memorize and the time between blinks can be set differently.

    Also it is possible to lower down the number of required pins, for example we can use shift registers, but the code would be more complicated.

    Share

      Recommendations

      • Tiny Home Contest

        Tiny Home Contest
      • Furniture Contest 2018

        Furniture Contest 2018
      • Audio Contest 2018

        Audio Contest 2018

      Discussions

      0
      None

      This would be a great tutorial for teaching how to use inputs and outputs on Arduino.