Game-ON (memory Game)

by MilanMattheeuws in Circuits > Raspberry Pi

208 Views, 1 Favorites, 0 Comments

Game-ON (memory Game)

casing_af.jpg

Hello everyone. I am Milan, a student in Multimedia and Creative Technologies in Howest in Kortrijk, Belgium. At the end of my first year i had to make a project containing a few sensors and a few other devices. This had to be connected to a Raspberry Pi. What you will see here is what I made for my project. It's called GAME-ON and it is a memory game where you have to repeat the order that 4 led lights showed you with a joystick.

In this instructable I will show you how to build this project step by step. I put a lot of work in this project and i hope you will enjoy making the this game just like I did.

Supplies

This is the list of materials you will need:

- 1 Raspberry Pi 4

- 1 Raspberry Pi charger (you should have this with the Raspberry Pi)

- 1 Ethernet cable (to connect to the Raspberry Pi)

- 1 LCD 16x4 display

- 2 broadboards (it is possible to make with 1 breadboard but I recommend 2)

- 1 RFID-RC522

- 1 LDR light resistor

- 1 MCP3008

- 1 Arcade Joystick (4-way)

- 9 330Ω resistors

- 1 10kΩ resistor

- 4 LED lights (color doesn't matter, but I chose for red)

The following types of cables to connect the parts on you breadboard:

- male to male

- male to female

- female to female (if the other cables are too short)

Create the Database

MilanMattheeuws_Database_ERD.PNG

If you have sensors that collect data you will want to save that data into a database. In this step we will make that database. The database we will make will contain 5 tables. In the picture above you can see the ERD of the database. This is the structure of the database.

The first table is a table with all the users in so we can select the user that we want to play the game as on the website later, or scan in on the RFID. The 'user' entity will have an id to identify the user. The user will also have a first - and nastname and a nickname. The nickname will be unique to every user. The database will also keep track of the highest level the user has completed.

The second table will contain all the available levels. In my project i made 8 levels in total. These are levels 1 through 8. The number of the level indicates how many times the led's will light up. Every level has an id (the number of the level) and a name.

The third table is a session table where we will keep track of when a user logged in. This means the timestamp and date (the date is optional) of the moment the user is logged in. This table will also keep data on if the user paid or not.

The fourth table is a table to keep track of the payment system. This table will keep the time of a difference in value of the lightsensor. This means that if a coin is placed on this sensor, the coin will block the light. This means that someone paid. Afterwards you can take your coin back.

The last table will keep track of every level that is played within a session. While logged in as a user, you can play different levels. Each time a level starts, a record will be added in the database.

Program the First Sensor

The first sensor we will be programming is the RFID. For this sensor I used a library and a guide. This is the guide I used:

https://pimylifeup.com/raspberry-pi-rfid-rc522/#:~...

In this guide you will also get a link to the library and there is a description on how to install and use it.

I changed the pin layout a little because for some reason i couldn't put 2 devices on the same spi connection pins on my Raspberry Pi. For this i had to enable other SPI pins on the Raspberry Pi. I found a good guide for this. This is the guide I used:

https://blog.stabel.family/raspberry-pi-4-multiple...

The SPI pins I enabled are the SPI5 pins. I chose the SPI 5 pins bacause those were the ones still unused on my Raspberry Pi.

Like I said before I used a different pin layout than the guide. This is the pin layout I used:

- The MISO pin of the RFID goes in GPIO13 (the MISO pin for SPI5)

- The MOSI pin of the RFID goes in GPIO14 (the MOSI pin for SPI5)

- The IRQ pin goes into GPIO25

- The SDA pin goes into GPIO18

- The SCK pin goes into GPIO 15

- The GND will be grounded

- The 3V3 will be connected to 3V3

Program the Second Sensor

LDR fritzing.PNG

For the second sensor I didnt use a library, just a coded class. I found a really usefull guide to program this sensor. If you follow it correctly it should work pretty quick.

https://tutorials-raspberrypi.com/photoresistor-br...

I let this class run every 10 seconds on a thread in my project and if there was a big difference in the result I collected the data and wrote it to the database. If you want to do this the difference has to be pretty big because the sensor will always differ with a few values even if you dont touch it (the sensor is sensitive).

To be able to read the light resistor you will need an analog/digital converter. This is the MCP3008. It is also important to connect an 10k ohm resistor with the light resistor. Don't forget this.

If you connect everything to the Raspberry Pi like told in the guild, you shuild be able to copy the code and run it smoothly.

Program the Joystick

joystick.png

To program the joystick i didn't really use a guide or anything. This is bacause it isn't that hard to let this work. In the scheme above you can see how i connected all the pins. You are not obligated to use the resistors between the GPIO pins and the joystick, but i would recommend it for safety. It is also possible that the joystick you use has 8 pins instead of 4. This was the case with me. In that case has every pin a seperate ground pin. So you just have to ground 4 pins instead of 1. It should be pretty clear what 2 pins are part of 1 side on the joystick.

Now i will discuss the code i wrote to make the joystick work. I also wrote this in python.

These are the imports needed for the class:

import RPi.GPIO as GPIO
import time
import random

The next step is to set each pin of the joystick:

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # Use GPIO pin numbering

GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # physical 18 GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # physical 32 GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # physical 16 GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # physical 13

I also set the physical pin numbering next to it if you want to use this numbering instead.

Set a function for each side of the joystick to run when that side is pressed:

def button_north_callback(channel):
print('the north button was pushed")
time.sleep(0.3)

This is an example for the north side of the joystick. You can add code to this if you want your program to do something when that side is pushed. For now it only contains a print statement. Repeat this function for the other 3 sides.

You can now add an event detect for each side. This means that when a side is pushed, the function you made in the previous step will run. I made some variables for each side with their GPIO number to make it easier for me to program the class.

east = 27 # physical 13
south= 12 # physical 32
west = 24 # physical 18
north = 23 # physical 16

GPIO.add_event_detect(east,GPIO.RISING,callback=button_east_callback)
GPIO.add_event_detect(west,GPIO.RISING,callback=button_west_callback) GPIO.add_event_detect(south,GPIO.RISING,callback=button_south_callback) GPIO.add_event_detect(north,GPIO.RISING,callback=button_north_callback)

Now when you push every side the right direction should be printed.

Code the Leds

leds.png

The last part of the electronical devices that we will program are the leds. There aren't that hard just like the joystick. In the scheme above you can see the pin layout i used for the leds. The pins are next to each other so it is easy to find all the leds on the Raspberry Pi, if you need to find them later on in the project to build it inside a casing.

I wrote the code when these pins are in use so if you connect them this way you can just use the code I wrote. If you used other pins you can just change the pins in the pin layout section of the code.

At the end of this class you can add the code from the joystick to it and create a class that will run a level when you give the level number as parameter to the function.

I used the same imports for the leds as for the joystick, these are the imports:

import RPi.GPIO as GPIO
import time
import random

Now we have to set the pins again (we will use the GPIO pin numbering again and not the physical pin numbering):

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # Use GPIO pin numbering

GPIO.setup(2, GPIO.OUT) # physical 3
GPIO.setup(3, GPIO.OUT) # physical 5
GPIO.setup(4, GPIO.OUT) # physical 7
GPIO.setup(17, GPIO.OUT) # physical 1

I also set the physical pin numbering next to it if you want to use this numbering instead. I also made led variables again to make the programming a bit more easy.

north_led = 2 # physical 3
east_led = 3 # physical 5
west_led = 17 # physical 11
south_led = 4 # physical 7

To trun of all the leds you can use this code:

GPIO.output(north_led, False)
GPIO.output(east_led, False)
GPIO.output(south_led, False)
GPIO.output(west_led, False)

You can change the False to True to make the led light up. Then I wrote some code to let the led's go off in a random order:

while i < levelnumber:
randomled = random.randint(1, 4)

if randomled == 1:
GPIO.output(north_led, True)
time.sleep(1)
GPIO.output(north_led, False)
elif randomled == 2:
GPIO.output(east_led, True)
time.sleep(1)
GPIO.output(east_led, False)
elif randomled == 3:
GPIO.output(south_led, True)
time.sleep(1)
GPIO.output(south_led, False)
elif randomled == 4:
GPIO.output(west_led, True)
time.sleep(1)
GPIO.output(west_led, False)

time.sleep(0.1)
i += 1

The i variable is the counter so make sure to declare this variable before the while statement. The levelnumber variable is the variable you give to the function to let the function know how many times the leds should go off .In other words the number is what level should be run.

Now you can combine the code of the sensor to make the level function complete and make the lights turn on a few times if the user has the right order. I used 2 arrays to compare the order of the leds and the order of the joystick to see if they completed the level or not.

Combine the Classes

MilanMattheeuws_projectone_Fritzingschema_Electronisch_final_schema.png

If you followed the previous steps you should have the classes for the RFID, the light resistor and for a level. Now you can combine these into your main app. If you want to you can build a website around your game to change your user (if you don't want to scan the RFID) or to change the level. Whenever you change the level you can run the LCD class to display the current level with an extra message.

In the image above I put the scheme of the complete project. I would recommend using this layout because there arenn't many pins left and you would have to look for a while to find another pin layout that would be compatible.

Make the Casing

casing.jpg

If you want your game to look nice you will need a casing. Just pick a wooden box that you think would be big enough. I used a wooden box i had found somewhere with a width of 27 cm and a length of 34 cm, but this is pretty big.

First drill 4 holes so they make the corners in the shape of a rhombus. Make sure that the holes are big enough to put the legs of the led lights through, but nog big enough to let the entire led through. Next make a hole to put the LCD display through. The hole I made was 7 by 2,6 cm big. This is big enough for the lcd screen, but not for the PCB underneath it. This way it will look the nicest. Also drill a hole for the light resistor.

You will need to make a hole for the joystick. Make sure that the hole is big enough to let the pins through, but not the entire joystick. If you did this you can screw the joystick to the casing.

You can test if the RFID can scan though the ceiling of your box. If this works, you dont need to make a hole for it but you can just stick it underneath that ceiling.

The image above is what my casing looked like after the holes were made. But as you can see, it doesn't look that great. So give the box a layer of paint and it will look much better.

Final Result

casing_af.jpg

If you painted the case and stuck all the sensors to it, it should look much better.

With this done the project you made should be finished. If you want to build that website I mentioned earlier you are free to do so, or maybe add some other original and surprising things to the game. Challenge yourself!

I hope you had a lot of fun making this project and hopefully you made something you can be proud of.