Knight Rider & Cylon Lights for the Raspberry Pi

The most obvious application for a Raspberry Pi is re-creating the sliding red lights found on “KITT” from Knight Rider or the Cylons in Battestar Galactica. This can all be done with pure electronics but that doesn’t involve any programming and therefore isn’t as cool.

So here is a brief description of my “running lights” project. It may be overkill to throw an entire computer at such a task but it served a number of purposes :

  • good introduction to Python GPIO programming
  • good introduction to Raspberry Pi GPIO interfacing
  • good practice at soldering, wiring, testing and constructing an electronic circuit

It isn’t my intention to show you how to create the circuit board but hopefully there is enough information on this page to help you get started.

Raspberry Pi Parts

Components

  • 10 5mm Red LEDs (£1.50)
  • 10 560ohm resistors (£0.10)
  • 10 27Kohm resistors (£0.10)
  • 10 BC548 NPN transistors (£1.00)
  • 1 Stripboard (£3.50)
  • 12 lengths of wire
  • 1 0.1″ Crimp connector housing 1×3 pin (£0.05)
  • 2 0.1″ Crimp connector housing 1×10 pin (£0.40)
  • 12+ Female crimp pins for 0.1″ housings (£0.60)

Tools

  • Wirecutters/stripers
  • Soldering iron + solder
  • 1 Stripboard cutter Tool (Spot Face Cutter)

In total the board cost me approximately £10 in bits but it really depends on what components and tools you already have. I didn’t need to buy solder or a stripboard cutter but I did spend £12 on a new wire stripper. If you plan on doing any work with stripboard a “stripboard cutter” or “spot cutter” is well worth a few pounds/dollars.

The photos below show my scripboard with the 10 LEDs, resistors and transistors soldered in place. Each LED requires 1 560ohm resistor, 1 27Kohm resistor and 1 BC548 transistor.

Each LED is wired as shown in the following diagram :
Given the low current required the transistor can replaced with any device that can supply the LED with 5mA. So BC547 or BC548 devices are perfect.

I didn’t worry which LED I connected to which GPIO pin. Once the circuit was working I corrected the light sequence in the Python code to put them in the correct order.

Python Program

This is the Python program I used to sequentially turn the LEDs on an off. It uses the RPi.GPIO library so that must installed already.

#------------------------------------------------
# Name: Running Lights
# Author    : matt.hawkins
# Created   : 21/06/2012
# Python    : 2.7
# Copyright : (c) matt.hawkins 2012
#------------------------------------------------
#!/usr/bin/env python

# Import required libraries
import time
import RPi.GPIO as GPIO

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO signals to use
# that are connected to 10 LEDs
# Pins 7,11,13,15,19,24,23,16,18,22
# GPIO4,GPIO17,GPIO21,GPIO22,GPIO10,
# GPIO8,GPIO11,GPIO23,GPIO24,GPIO25
RpiGPIO = [4,17,21,22,10,8,11,23,24,25]

# Set all pins as output
for pin in RpiGPIO:
  print "Setup pins"
  GPIO.setup(pin,GPIO.OUT)

# Define some settings
StepCounter = 0
StepDir = 1
WaitTime = 0.2

# Define some sequences

# One LED
StepCount1 = 10
Seq1 = []
Seq1 = range(0,StepCount1)
Seq1[0] =[1,0,0,0,0,0,0,0,0,0]
Seq1[1] =[0,1,0,0,0,0,0,0,0,0]
Seq1[2] =[0,0,1,0,0,0,0,0,0,0]
Seq1[3] =[0,0,0,1,0,0,0,0,0,0]
Seq1[4] =[0,0,0,0,1,0,0,0,0,0]
Seq1[5] =[0,0,0,0,0,1,0,0,0,0]
Seq1[6] =[0,0,0,0,0,0,1,0,0,0]
Seq1[7] =[0,0,0,0,0,0,0,1,0,0]
Seq1[8] =[0,0,0,0,0,0,0,0,1,0]
Seq1[9] =[0,0,0,0,0,0,0,0,0,1]

# Double LEDs
StepCount2 = 11
Seq2 = []
Seq2 = range(0,StepCount2)
Seq2[0] =[1,0,0,0,0,0,0,0,0,0]
Seq2[1] =[1,1,0,0,0,0,0,0,0,0]
Seq2[2] =[0,1,1,0,0,0,0,0,0,0]
Seq2[3] =[0,0,1,1,0,0,0,0,0,0]
Seq2[4] =[0,0,0,1,1,0,0,0,0,0]
Seq2[5] =[0,0,0,0,1,1,0,0,0,0]
Seq2[6] =[0,0,0,0,0,1,1,0,0,0]
Seq2[7] =[0,0,0,0,0,0,1,1,0,0]
Seq2[8] =[0,0,0,0,0,0,0,1,1,0]
Seq2[9] =[0,0,0,0,0,0,0,0,1,1]
Seq2[10]=[0,0,0,0,0,0,0,0,0,1]

# Two LEDs from opposite ends
StepCount3 = 9
Seq3 = []
Seq3 = range(0,StepCount3)
Seq3[0] =[1,0,0,0,0,0,0,0,0,1]
Seq3[1] =[0,1,0,0,0,0,0,0,1,0]
Seq3[2] =[0,0,1,0,0,0,0,1,0,0]
Seq3[3] =[0,0,0,1,0,0,1,0,0,0]
Seq3[4] =[0,0,0,0,1,1,0,0,0,0]
Seq3[5] =[0,0,0,1,0,0,1,0,0,0]
Seq3[6] =[0,0,1,0,0,0,0,1,0,0]
Seq3[7] =[0,1,0,0,0,0,0,0,1,0]
Seq3[8] =[1,0,0,0,0,0,0,0,0,1]

# Choose a sequence to use
Seq = Seq3
StepCount = StepCount3

# Start main loop
while True:
  print "-- Step : %i --" %StepCounter

  for pin in range(0, 10):
    xpin = RpiGPIO[pin]
    if Seq[StepCounter][pin]!=0:
      print " Enable %i" %xpin
      GPIO.output(xpin, True)
    else:
      print " Disable %i" %xpin
      GPIO.output(xpin, False)

  StepCounter += StepDir

  # If we reach the end of the sequence reverse
  # the direction and step the other way
  if (StepCounter==StepCount) or (StepCounter<0):
    StepDir = StepDir * -1
    StepCounter = StepCounter + StepDir + StepDir

  # Wait before moving on
  time.sleep(WaitTime)

Given that it uses this library the script must be run as root i.e. run using :

sudo python running_lights.py

This assumes you’ve saved the script as a file named “running_lights.py”.

Here is a video showing Sequence 3 running :

I put other Raspberry Pi related videos on my YouTube channel Raspberry Pi playlist.

This entry was posted in Hardware, Python and tagged , , , . Bookmark the permalink.



24 Responses to Knight Rider & Cylon Lights for the Raspberry Pi

  1. Matt says:

    The prices in brackets are the total cost for that number of items. To keep the price down you may have to order more than the required number. For example I ordered resistors in packs of 100 for 99p on ebay. In general ordering the components online was much cheaper than going to a shop. I bought the stripboard from Maplin but I’m sure it would be cheaper online.

  2. David says:

    Having just tried the code you pasted above, python had a go about the use of the singe = in the condition of the “while StepCounter=0:” part of the algorithm.

    I’ve also found that using “while StepCounter==0:” only executes the first run, but changing it to “while 1:” will make it continuously loop.

    Thanks for posting the article, just thought I’d make it aware that there are problems with the code that was pasted above.

  3. Paul says:

    I see from your code that you use pins 11 through to 20. I have downloaded a spreadsheet listing all the GPIO pins and it says do not connect to pins 4, 6, 14, 17, 20 and 26. I have no idea why it says not to use them – and I haven’t in my projects – but they seem to work for you.

    Do you have any idea why there are warnings not to use the pins?

    • Matt says:

      I do not use Pin 4. The numbers 4,17,21,22,10,8,11,23,24,25 are GPIO references not Pin nu4mbers. “4″ is GPIO4 which is Pin 7 for example.

  4. Jan says:

    Nice example!

  5. Carlo says:

    Hi.
    It seems that the python source code listing is truncated in the middle of a statement.

  6. David says:

    Can’t get it to work. Syntax error in line 80 which reads:- while 1==1. This line was the subject of an earlier post and you changed it. Is there something missing? The picture is not terribly clear so do I need to connect live to pin 1 and ground to pin 6. I’m using a breadboard. It’s my first project with multiple LEDs and my first bash at electronics (the subject was not taught in school when I left in 1959), also first attempt at Python.

  7. David says:

    Just noticed that line 80 changed in above to while True:. It still does not work!

    • Matt says:

      What is the full syntax error? Make sure the indentation is correct as this is vital in Python. I’ve updated the diagram as the “power source” symbol was confusing. Pin 2 and Pin 6 on the Pi provide +5V and 0V to the circuit.

  8. David says:

    This program is getting on my nerves. It seems to be so full of sytax errors that, as a newbie, I am concerned that it has not been tried and tested thoroughly on a RaspberryPi. If this is the case then, Matt, you should be ashamed of youself. I have now found and installed the module by using python3, but I now get an error on line 20. Sort it out, please. I am not going to apologise for my tone – I have been a professional all my life and have never published work that is unchecked and does not conform to high standards of working practices. If this gets modded out then be sure I have a copy to post eleswhere. Do the job properly or don’t do it at all.

    • Matt says:

      Works fine for me. Must be your dodgy soldering. I have never used Python 3 but feel free to write your own programme and publish that.

    • Matt says:

      David, you need to calm down and get a grip

      1) Most of your issues so far have been caused by syntax errors due to your careless typing.
      2) You are trying to use Python 3.
      3) You are trying to use WiringPi when I clearly state you need to use RPi.GPIO.
      4) My Youtube video shows my script working.
      5) It’s not my fault if you can’t tell the difference between curved and square brackets.

      I am happy to correct any errors in my articles as they are reported. This is a hobby and the information is provided “as is”. If you don’t like my posts then you are welcome to go some place else. Please don’t threaten me over something so trivial as a bit of Python code. It is embarrassing. For you.

      Would love to see your published work given you are clearly an expert in some other field. I hope it isn’t medicine or aircraft engineering.

  9. Robert says:

    In your code:

    RpiGPIO = [4,17,21,22,10,8,11,23,24,25]

    # Set all pins as output
    for pin in RpiPins:
    print “Setup pins”
    GPIO.setup(pin,GPIO.OUT)

    Shouldn’t RpiGPIO be RpiPins? Otherwise RpiPins is undefined at the time of the for.

  10. David says:

    Just for clarity. No typing errors apart from that uppercase W. I used copy and paste into leafpad. No soldering; using breadboard. After you first published this you had to alter it. Even after my ‘rant’ you had to alter it again introducing GPIO BCM. Hence, I am justified in my comments. I did use RPi.GPIO which I downloaded and installed per your instructions. I also downloaded WiringPi from this site thinking it must be useful for something because it was here. If I am wrong then I am wrong andf old enough to admit it. Can you say the same?

    • Matt says:

      Not all updates to my site are the result of your comments. This isn’t the 1960s. Web pages are not slabs of stone. They get updated whenever the author feels like it. I switched to using BCM references because it is a better way to do things. You did not download WiringPi from my site. I’ve never used WiringPi, don’t provide downloads of it and don’t use it in any of my scripts. I think you are confused. Again.

  11. Nice little demo, but why the transistors?

    I appreciate you might want to do it for demo purposes, (to demonstrate driving higher loads), but the Pi is more than capable of driving small LEDs directly to do this sort of thing – especially the 5mA load you’re presenting it with here…

    e.g. while I’d not recomend running this for very long (it does exceede some specs. notably the 3.3v regulator!) http://unicorn.drogon.net/pi17leds.jpg works just fine. Each LED here is pulling 10mA, so 170mA in total – the worst that would happen here is that the 3.3v reg. would shut down and the Pi reboot.

    -Gordon

    • Matt says:

      I didn’t want to encourage people to draw current directly from the GPIO pins because when they moved onto other devices (buzzers etc) they may damage their Pi. Some users may not appreciate the limits so I decided to play it safe from the start. This way they can use whatever size LEDs they like without drawing too much current. Also it means you can have a standard setup and swap between LEDs, buzzers and small motors.

  12. chichara says:

    Hi,
    How can i generate random led flasher with raspberry.
    for example i have 5 led and 1 button.
    So if i press the button, random led will flash on.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>