NOTE: Every post ends with "END OF POST". If you don't see it then open the full post in a separate page!

Controlling LEDs and switches with Raspberry Pi

Here is how you can control LEDs with switches with Raspberry Pi.

This is what you will get in the end:

RPi LEDs and switches

We will make a small game where we blink up the LEDs in a sequence and the player has to repeat it. Each switch controls a given LED.

If you are new to Raspberry Pi, then you may want to read this post first: https://feherenfekete.wordpress.com/2015/01/06/blinking-leds-on-raspberry-pi/

Ingredients

I used the pieces that came with the Raspberry Pi Model B+ Starter Pack (http://www.adafruit.com/product/2125):

  • Raspberry Pi Model B+
  • SD card with Raspbian Wheezy (Linux)
  • USB to TTL serial cable: for communication with the Pi
  • For the circuit
    • Breadboard
    • Adafruit Pi Cobbler Plus Kit- Breakout Cable
    • 3 pieces of 560 ohm resistors
    • 3 pieces of 10 Kohm resistors
    • 3 LEDs: red, green, blue
    • 3 switches
    • 4 + 2 + 6 pieces of male/male jumper wires

Wiring

Here is the schematic I used:

RPi_LEDs_switches_schematic

The connection of the switches uses pull-up resistors. For more information about this see the following links:

Here is some explanation for the schematic:

  • 5V+ : The 5V GPIO PIN of the Pi
  • GND PIN : We use two separate GND PINs of the Pi. One for the LEDs circuit and one for the switch circuit.
  • PIN 23, 24, 25, 16, 20, 21 : These are generic GPIO PINs of the Pi
  • R1, R2, R3 : 560 ohm resistors
  • R4, R5, R6 : 10K ohm resistors
  • S1, S2, S3 : switches
  • D1, D2, D3 : LEDs red, green and blue

Programming

We will use Python for this because it’s easy ๐Ÿ™‚

For simplicity, we hardcoded the LED sequences and we have only 3 of them.
First it shows a LED sequence. Then it waits for user input. The user has to repeat the sequence using the switches. Each switch controls one of the LEDs.
If the user presses the wrong swicth (i.e. wrong color) then we show an Error signal by blinking the red LED a few times. Then we repeat the sequence for the user to try again. She can try 3 times. After that, we move on to the next sequence.
If the user successfully repeated the sequence then we acknowlegde it by blinking all the LEDs a few times. Then we move on to the next sequence.
Each sequence is worth 3 points. Each failed attempt means a minus point.

pi@raspberrypi:~$ cat switches-and-leds.py
#!/usr/bin/env python

import time
import RPi.GPIO as gpio
import os

ledOff = 0
ledOn = 1

switchOff = 1
switchOn = 0

red = 0
green = 1
blue = 2
noColor = -1

redLed = 25
greenLed = 24
blueLed = 23

redSwitch = 21
greenSwitch = 20
blueSwitch = 16

colorToLedMap = { red : redLed, green : greenLed, blue : blueLed }
colorToSwitchMap = { red : redSwitch, green : greenSwitch, blue : blueSwitch }

switchStabilityTimeout = 0.025

def init():
        gpio.setmode(gpio.BCM)
        gpio.setup(redLed, gpio.OUT)
        gpio.setup(greenLed, gpio.OUT)
        gpio.setup(blueLed, gpio.OUT)
        gpio.setup(redSwitch, gpio.IN)
        gpio.setup(greenSwitch, gpio.IN)
        gpio.setup(blueSwitch, gpio.IN)

def cleanup():
        gpio.cleanup()

def setAllLeds(state):
        for color, led in colorToLedMap.iteritems():
                gpio.output(led, state)

def setLed(color, state):
        led = colorToLedMap[color]
        gpio.output(led, state)

class SwitchStateHandler:
        def __init__(self):
                self.wasOn = False
                self.count = 0
        def isStateStable(self, isOn):
                if isOn:
                        if self.wasOn:
                                self.count += 1
                        else:
                                self.wasOn = True
                else:
                        self.wasOn = False
                        self.count = 0
                if self.count == 3:
                        return True
                return False

def waitSwitchRelease():
        stateHandler = SwitchStateHandler()
        while True:
                redState = gpio.input(redSwitch)
                greenState = gpio.input(greenSwitch)
                blueState = gpio.input(blueSwitch)
                isOff = redState == switchOff and \
                        greenState == switchOff and \
                        blueState == switchOff
                if stateHandler.isStateStable(isOff):
                        return
                time.sleep(switchStabilityTimeout)

def readSwitch():
        waitSwitchRelease()
        setAllLeds(ledOff)
        redState = SwitchStateHandler()
        greenState = SwitchStateHandler()
        blueState = SwitchStateHandler()
        result = noColor
        while True:
                redIsOn = gpio.input(redSwitch) == switchOn
                greenIsOn = gpio.input(greenSwitch) == switchOn
                blueIsOn = gpio.input(blueSwitch) == switchOn
                if redState.isStateStable(redIsOn):
                        result = red
                        break
                if greenState.isStateStable(greenIsOn):
                        result = green
                        break
                if blueState.isStateStable(blueIsOn):
                        result = blue
                        break
                time.sleep(switchStabilityTimeout)
        if result != noColor:
                setLed(result, ledOn)
                waitSwitchRelease()
                setAllLeds(ledOff)
        return result

patterns = [[red, green, blue], [green, green, red, blue], [red, green, red, blue]]

def showPattern(pattern):
        for color in pattern:
                setAllLeds(ledOff)
                time.sleep(0.5)
                setLed(color, ledOn)
                time.sleep(0.5)
        setAllLeds(ledOff)

def showSuccessSignal():
        for i in xrange(0, 3):
                setAllLeds(ledOff)
                time.sleep(0.2)
                setAllLeds(ledOn)
                time.sleep(0.2)
        setAllLeds(ledOff)

def showFailedSignal():
        for i in xrange(0, 3):
                setAllLeds(ledOff)
                time.sleep(0.2)
                setLed(red, ledOn)
                time.sleep(0.2)
        setAllLeds(ledOff)

def guessPattern(pattern):
        for color in pattern:
                switch = readSwitch()
                if switch != color:
                        return False
        return True

def run():
        maxGuessCount = 3
        totalScore = 0
        for pattern in patterns:
                isGuessed = False
                guessCount = 0
                while not isGuessed and guessCount < maxGuessCount:
                        showPattern(pattern)
                        isGuessed = guessPattern(pattern)
                        if isGuessed:
                                print "Well done!"
                                showSuccessSignal()
                        else:
                                print "You missed it! Try again!"
                                guessCount += 1
                                showFailedSignal()
                score = (3 - guessCount)
                totalScore += score
                print "You earned %d points. Total score is %d." % (score, totalScore)

init()
try:
        run()
except KeyboardInterrupt:
        cleanup()

cleanup()

Now run it:

$ sudo ./switches-and-leds.sh

Enjoy! ๐Ÿ™‚

END OF POST

Advertisements

One Comment on “Controlling LEDs and switches with Raspberry Pi”


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s