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


Blinking LEDs on Raspberry Pi

Here is how you can blink some LEDs with Raspberry Pi.

First of all, this is what you will end up with:

LEDs_Raspberry_Pi

You will have three LEDs being controlled programmatically from the Pi.
We will control the LEDs through the GPIO PINs by using Linux’s built-in GPIO sysfs.

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 LEDs: red, green, blue
    • 4 pieces of male/male jumper wires

Step 1: Boot up and establish serial connection

Connect the Pi to the breadboard with the breakout cable and the cobbler.
Connect the USB to TTL cable like this: https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/connect-the-lead

  • Brown to RXD PIN (receive)
  • White to TXD PIN (transmit)
  • Black to GND PIN (ground)
  • Leave the Red cable unconnected. It is for power, but we will use the power adapter of the Pi for that.
  • Plug the USB plug to your computer.

Put your SD card with Raspbian into the Pi.
Plug the power cable to your Pi.
Plug the Pi’s power adapter to the wall socket.
Now the Pi is booting. You should see its red led lit up.

Run screen on your laptop:

sudo screen /dev/ttyUSB0 115200

Press ENTER and you should see something like this:

[    2.641363] usb 1-1: New USB device found, idVendor=0424, idProduct=9514
[    2.651493] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    2.661640] hub 1-1:1.0: USB hub found
[    2.667076] hub 1-1:1.0: 5 ports detected
[    2.951168] usb 1-1.1: new high-speed USB device number 3 using dwc_otg
[    3.071404] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[    3.079917] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    3.108390] smsc95xx v1.0.4
[    3.177061] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:9d:7e:2c
[    3.958510] udevd[156]: starting version 175
[    6.232318] bcm2708-i2s bcm2708-i2s.0: Failed to create debugfs directory
[    9.452151] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[    9.943347] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[   15.772181] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
��
Raspbian GNU/Linux 7 raspberrypi ttyAMA0

raspberrypi login: 

OK. Now you can shutdown the Pi like this:

sudo shutdown -h now

Unplug the power adapter from the wall.
Unplug the USB cable from your computer.

Step 2: Wire up the circuit

Here is the schematic I used:

RPi LEDs schematic

  • GND PIN: One of the GPIO GND PIN of the Pi
  • R1, R2, R3: 560 ohm resistors
  • D1, D2, D3: Red, green and blue LEDs
  • PIN 23, 24, 25: These GPIO PINs will provide 3.3 Volts to each LED circuit

Step 3: Basic scripts for GPIO control

Script for initializing a LED PIN:

pi@raspberrypi:~$ cat gpio-init.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-init.sh pin-number in|out"
        exit 255
}

if [ $# -ne 2 ]; then
        die "Missing argument"
fi

PIN=$1
DIR=$2

echo -n "Exporting GPIO pin $PIN... "
echo $PIN > /sys/class/gpio/export || die "Cannot export"
echo "done"
sleep 1

echo -n "Setting direction to $DIR... "
echo $DIR > /sys/class/gpio/gpio$PIN/direction || die "Cannot set direction"
echo "done"
sleep 1

Script for putting PINs HIGH or LOW:

pi@raspberrypi:~$ cat gpio-write.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-write.sh pin-number value"
        exit 255
}

if [ $# -ne 2 ]; then
        die "Missing argument"
fi

PIN=$1
VAL=$2

echo -n "Writing $VAL to pin $PIN... "
echo $VAL > /sys/class/gpio/gpio$PIN/value || die "Cannot write"
echo "done"

Script for de-initializing LEDs:


pi@raspberrypi:~$ cat gpio-done.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-done.sh pin-number"
        exit 255
}

if [ $# -ne 1 ]; then
        die "Bad argument"
fi

PIN=$1

echo -n "Un-exporting GPIO pin $PIN... "
echo $PIN > /sys/class/gpio/unexport || die "Cannot un-export"
echo "done"
sleep 1

Step 4: Blink some LEDs

Script for defining common variables (e.g. PIN numbers) used by other scripts.

pi@raspberrypi:~$ cat blinker-def.sh 
# This is meant to be sourced from other scripts.

RED=23
GREEN=24
BLUE=25

Script for initializing the LEDs:

pi@raspberrypi:~$ cat blinker-init.sh 
#!/bin/sh

. ./blinker-def.sh

./gpio-init.sh $RED out
./gpio-init.sh $GREEN out
./gpio-init.sh $BLUE out

Script for blinking the LEDs:
We loop through some hardcoded LED patterns.

pi@raspberrypi:~$ cat blinker-blink.sh 
#!/bin/sh

. ./blinker-def.sh

while true; do
        for J in 100 010 001 101 011 100 110 001; do
                VAL_RED=`expr substr $J 1 1`
                VAL_GREEN=`expr substr $J 2 1`
                VAL_BLUE=`expr substr $J 3 1`
                ./gpio-write.sh $RED $VAL_RED
                ./gpio-write.sh $GREEN $VAL_GREEN
                ./gpio-write.sh $BLUE $VAL_BLUE
                sleep 1
        done
done

Script for de-initialization:

pi@raspberrypi:~$ cat blinker-cleanup.sh 
#!/bin/sh

. ./blinker-def.sh

./gpio-done.sh $RED
./gpio-done.sh $GREEN
./gpio-done.sh $BLUE

So, if you then run these in this sequence, you should get LEDs blinking in the predefined patterns:

$ sudo ./blinker-init.sh
$ sudo ./blinker-blink.sh # Press Ctrl-C when you got bored of it.
$ sudo ./blinker-cleanup.sh

END OF POST