Learning To Count To 5 With a Raspberry Pi

Prototyping a small counting game – pressing a button to count up to 5 with LEDs and on an OLED screen – then celebrating once reached.

My daughter loves to help me build simple circuits, turning LED lights on and off on a breadboard. Not yet grasping her 1-2-3’s or A-B-C’s, I thought building a small game would be an engaging way to get her learning with the things she likes.

To put this together I used the following setup:

Wired as so:

By no means am I a Python developer, so I’m just swinging away here – the codes very repetitive, but hey, it does the trick easy enough.

# https://davidsword.ca/learning-to-count-to-5-with-a-raspberry-pi/

import time
import busio
import adafruit_ssd1306
import RPi.GPIO as GPIO
from board import SCL, SDA
from PIL import Image, ImageDraw, ImageFont

# settings
countTo       = 5 # probably don't change as there's 5 LEDs to count along with.
onCompleteMsg = "YAYY !!"
animateLoop   = 20 # how many LED chases to do
animateSpeed  = 0.04 # how fast to chase
screenPadding = 3 
fontSize      = 40
fontTTF       = 'whatever-font.ttf' # probably need to change this, see http://www.dafont.com/bitmap.php

# @see https://pinout.xyz/
# @see https://davidsword.ca/wp-content/uploads/2020/06/learning-to-count-to-5-with-a-raspberry-pi.png
GPIO.setmode(GPIO.BCM)
led1 = 5
led2 = 6
led3 = 13 
led4 = 19
led5 = 26
btn  = 22

# Display Setup
# @see https://learn.adafruit.com/adafruit-pioled-128x32-mini-oled-for-raspberry-pi/usage
i2c      = busio.I2C(SCL, SDA)
disp     = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
disp.fill(0)
disp.show()
width    = disp.width
height   = disp.height
image    = Image.new("1", (width, height))
draw     = ImageDraw.Draw(image)
font     = ImageFont.truetype(fontTTF, fontSize)

def displayClear():
    # Draw a black filled box to clear the image.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)
    disp.fill(0)
    disp.show()

def display(val):
    displayClear()
    draw.text((screenPadding, screenPadding), str(val), font=font, fill=255)
    disp.image(image)
    disp.show()

def turnOn(pin):
    GPIO.output(pin, GPIO.HIGH)
    
def turnOff(pin):
    GPIO.output(pin, GPIO.LOW)

# @TODO loop this dynmically
def animation():
    turnOff(led1)
    turnOff(led2)
    turnOff(led3)
    turnOff(led4)
    turnOff(led5)
    turnOn(led1)
    time.sleep(animateSpeed)
    turnOff(led1)
    turnOn(led2)
    time.sleep(animateSpeed)
    turnOff(led2)
    turnOn(led3)
    time.sleep(animateSpeed)
    turnOff(led3)
    turnOn(led4)
    time.sleep(animateSpeed)
    turnOff(led4)
    turnOn(led5)
    time.sleep(animateSpeed)
    turnOff(led5)

GPIO.setup(led1, GPIO.OUT)
GPIO.setup(led2, GPIO.OUT)
GPIO.setup(led3, GPIO.OUT)
GPIO.setup(led4, GPIO.OUT)
GPIO.setup(led5, GPIO.OUT)
GPIO.setup(btn, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

displayClear()

count = 0
while True:
    if GPIO.input(btn) == GPIO.HIGH:
        if count < ( countTo - 1 ):
            count += 1
            display(count)
            if count == 1:
                turnOn(led1)
            if count == 2:
                turnOn(led2)
            if count == 3:
                turnOn(led3)
            if count == 4:
                turnOn(led4)
            # no long-pressing the button
            time.sleep(0.75)
        else:
            # we hit the limit, do some fun stuff.
            turnOn(led5)
            count = countTo
            display(count)
            time.sleep(0.75)
            display(onCompleteMsg)
            for z in range(animateLoop):
                animation()
            count = 0
            displayClear()

Run the script with python3 oled-count-game.py. If the script fails and you get a warning about missing modules, the modules can be installed usually with sudo pip3 install <module_name>, for the GPIO if that’s missing, it can be installed with sudo apt-get install python3-rpi.gpio --assume-yes.

Leave a Reply

Your email address will not be published. Required fields are marked *