24 LED Larson Scanner

MediaWizards Forums
https://snitz.themediawizards.co.uk/Topic/Posts/5?pagenum=1
07 Dec 2025, 20:52

Topic


HuwR
24 LED Larson Scanner
06 Sep 2025, 21:12


Introduction

The Larson Scanner is a classic electronics project inspired by the iconic sweeping red lights seen on Battlestar Galactica’s Cylons and Knight Rider’s KITT car, both created by producer Glen A. Larson. This project recreates that nostalgic effect using a Raspberry Pi and a custom PCB with 24 LEDs.

Instead of dedicating one GPIO pin per LED, we’ll use Charlieplexing, a clever wiring technique that allows control of n2−n LEDs with only n pins. With 6 GPIO pins, we can drive up to 30 LEDs — more than enough for our 24‑LED scanner.

Larson scanner connection matrix diagram for Charlieplexing

Hardware Design

  • PCB Layout: Designed in Sprint‑Layout, the board arranges all 24 LEDs in a straight line for a clean, compact look.

Larson scanner PCB layout for Charlieplexing

  • Fabrication: The PCB was etched and soldered manually. Careful soldering is essential since Charlieplexing requires precise connections.

Larson scanner PCB with LED lights Charlieplexing

Larson scanner PCB reverse side for Charlieplexing

  • Charlieplexing Setup:

    • Pins used: GPIO 13, 16, 19, 20, 21, 26

    • Each LED is defined by a pair of pins (one HIGH, one LOW).

    • This reduces wiring complexity and keeps the Pi’s header uncluttered.

Software Implementation

We’ll use Python with the RPi.GPIO library to control the LEDs.

sudo apt-get update
sudo apt-get install rpi.gpio

Key Concepts:

  • Pin Resetting: Before lighting a new LED, all pins are set to input mode to avoid ghosting.

  • Lighting an LED: One pin is set HIGH, another LOW, while the rest remain inputs.

  • Sweep Effect: LEDs are lit in sequence, then reversed, creating the signature back‑and‑forth motion.

import sys, getopt
# Import the module that runs the GPIO pins
import RPi.GPIO as gpio
# Import the sleep function for pausing
from time import sleep
# set the GPIO pins to BOARD mode
gpio.setmode(gpio.BCM)
#If an argument is passed then set the repeat counter
repeatcount=0
myopts, args = getopt.getopt(sys.argv[1:],"l:")
for o, a in myopts:
if o == '-l':
repeatcount=int(a)
# This function lights a specific LED. The led variable input is a 2 item
# list, each item representing a pin
def lightLED(led):
#First clear the pins, by setting them all to input
for pin in charliePins:
gpio.setup(pin,gpio.IN)
#Now set up the first pin for HIGH OUTPUT
gpio.setup(led[0],gpio.OUT)
gpio.output(led[0],gpio.HIGH)
#Now set up the second pin for LOW OUTPUT
gpio.setup(led[1],gpio.OUT)
gpio.output(led[1],gpio.LOW)
# Define the array of pins used as leads
charliePins=[13,16,19,20,21,26] # Define the order for triggering the LEDs
charlieOrder=[1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14,17,16,19,18,21,20,23,22] # Build the array of LEDs by cycling through the pins and creating the pairs. # It has the disadvantage of not making them in order for larger sets of
# pairs, but is easier to maintain, IMO. charlieLEDS=[] for i in range(0,len(charliePins)-1):
for j in range(i+1,len(charliePins)):
charlieLEDS.append([charliePins[i],charliePins[j]])
charlieLEDS.append([charliePins[j],charliePins[i]])
#Run the code over and over and over again
try:
counter = 0
while 1:
if repeatcount > 0:
counter=counter+1
for led in charlieOrder:
lightLED(charlieLEDS[led])
sleep(.042)
if repeatcount > 0:
counter=counter+1
for led in reversed(charlieOrder):
lightLED(charlieLEDS[led])
sleep(.042)
if counter > repeatcount-1:
if repeatcount>0:
raise ValueError('limit reached')
#check pin 5 to see if we need to quit
#pin 5 can be set high by another script to trigger the scanner to stop.gpio.setwarnings(False)
gpio.setup(5,gpio.IN)
if gpio.input(5):
quit()
except KeyboardInterrupt:
print 'interrupted'
except ValueError as err:
print(err.args)
finally:
gpio.cleanup()

Advanced Features

  • Automatic Stop: A secondary script can set GPIO pin 5 HIGH, signaling the scanner to stop after the next sweep.

  • Repeat Count: Command‑line arguments allow limiting the number of sweeps.

  • Safety: Always use resistors with LEDs to prevent overcurrent damage.

import RPi.GPIO as gpio
gpio.setwarnings(False)
gpio.setmode(gpio.BCM)
gpio.setup(5,gpio.OUT)
gpio.output(5,gpio.HIGH)

Final Build

The finished project runs on a Raspberry Pi Zero 2 W, producing a smooth, glowing red sweep across 24 LEDs. It’s a striking retro effect that blends electronics, programming, and sci‑fi nostalgia. I designed and printed my own 3D case to house all the parts.

Larson scanner inside custom printed case for Cylon effect

Larson scanner neatly stored in custom 3D printed case

And off it goes 😃

 

 

©