Skip to content

Instantly share code, notes, and snippets.

@raoulduke
Created October 13, 2025 03:36
Show Gist options
  • Save raoulduke/aa4e40fe07e03870e3f93ca88754421e to your computer and use it in GitHub Desktop.
Save raoulduke/aa4e40fe07e03870e3f93ca88754421e to your computer and use it in GitHub Desktop.
import RPi.GPIO as GPIO
import time
import random
# Setup GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
pwm = GPIO.PWM(17, 1000) # 1kHz PWM frequency
pwm.start(100)
def flicker_burst():
"""Rapid on-off flicker like a dying neon tube"""
flicker_count = random.randint(4, 12)
for _ in range(flicker_count):
# Off time (dark)
pwm.ChangeDutyCycle(255 - random.randint(0, 50))
time.sleep(random.uniform(0.02, 0.08))
# On time (bright)
pwm.ChangeDutyCycle(255 - random.randint(200, 255))
time.sleep(random.uniform(0.02, 0.07))
def slow_dim():
"""Gradually dim from bright to dim"""
for brightness in range(255, 100, -3):
pwm.ChangeDutyCycle(brightness)
time.sleep(random.uniform(0.01, 0.05))
def slow_brighten():
"""Gradually brighten from dim to bright"""
for brightness in range(100, 255, 3):
pwm.ChangeDutyCycle(brightness)
time.sleep(random.uniform(0.01, 0.05))
def power_surge():
"""Sudden bright flash then dim"""
pwm.ChangeDutyCycle(0) # Full bright
time.sleep(0.3)
for brightness in range(0, 180, 2):
pwm.ChangeDutyCycle(brightness)
time.sleep(0.01)
def struggling_start():
"""Struggling to turn on - multiple attempts"""
attempts = random.randint(2, 4)
for _ in range(attempts):
# Try to turn on
pwm.ChangeDutyCycle(255 - random.randint(100, 180))
time.sleep(random.uniform(0.15, 0.4))
# Failed - turns off
pwm.ChangeDutyCycle(255)
time.sleep(random.uniform(0.1, 0.3))
# Finally turns on
pwm.ChangeDutyCycle(0)
def intermittent_flicker():
"""Occasional quick flickers while otherwise on"""
base_brightness = random.randint(20, 60)
for _ in range(random.randint(3, 8)):
# Normal on
pwm.ChangeDutyCycle(base_brightness)
time.sleep(random.uniform(0.5, 2))
# Quick flicker off
pwm.ChangeDutyCycle(220)
time.sleep(random.uniform(0.03, 0.1))
try:
print("Starting Dying Neon Sign Effect...")
print("Press Ctrl+C to stop")
while True:
effect = random.randint(1, 6)
if effect == 1:
# Rapid death flicker
print("Effect: Rapid flicker burst")
flicker_burst()
time.sleep(random.uniform(0.5, 1.5))
elif effect == 2:
# Struggling to stay on
print("Effect: Struggling to power on")
struggling_start()
time.sleep(2)
elif effect == 3:
# Dim and brighten cycle
print("Effect: Gradual dim and brighten")
slow_dim()
time.sleep(random.uniform(0.3, 0.8))
slow_brighten()
time.sleep(1)
elif effect == 4:
# Power surge
print("Effect: Power surge")
power_surge()
time.sleep(random.uniform(1, 2))
elif effect == 5:
# Intermittent flickers
print("Effect: Intermittent flicker")
intermittent_flicker()
time.sleep(random.uniform(0.5, 1))
else: # effect == 6
# Stay bright normally then suddenly flicker
print("Effect: Normal bright then sudden flicker")
pwm.ChangeDutyCycle(255 - random.randint(240, 255))
time.sleep(random.uniform(1, 4))
flicker_burst()
time.sleep(random.uniform(0.5, 1))
# Random pause between effects
time.sleep(random.uniform(0.3, 1))
except KeyboardInterrupt:
print("\nShutting down...")
pwm.ChangeDutyCycle(255) # Turn off
time.sleep(0.5)
finally:
pwm.stop()
GPIO.cleanup()
print("Goodbye!")
@raoulduke
Copy link
Author

Dying Neon Sign Effect - Raspberry Pi LED Controller

A Python script that creates a realistic dying neon sign flicker effect on a 12V LED strip controlled by a Raspberry Pi (4, Zero WH, or Pico). Uses PWM (Pulse Width Modulation) on GPIO pin 17 to simulate the unpredictable behavior of a failing vintage neon sign.

Features:

  • Rapid flicker bursts (like a tube dying)
  • Struggling power-on sequences (multiple failed attempts)
  • Gradual dimming and brightening cycles
  • Power surge effects (sudden bright flash)
  • Intermittent random flickers
  • Smooth transitions between effects

Hardware Required:

  • Raspberry Pi (4, Zero WH, or Pico)
  • 12V LED Strip (3.5m or longer)
  • 12V Power Supply (5A)
  • Gate driver circuit (2N4124 transistor, IRF510 MOSFET, 1N4004 diode, 10kΩ and 1kΩ resistors)

Circuit Details:
The script controls the LED strip through a PWM gate driver circuit that safely amplifies the GPIO signal from 3.3V (16mA) to 12V (5A). This protects the microcontroller while providing full brightness control.

Code Features:

  • 6 different flicker effect functions
  • Random effect cycling
  • Configurable timing and randomness
  • Easy to modify for different effects
  • Graceful shutdown

Usage:
python3 dying-neon-sign-effect.py

Press Ctrl+C to stop (if connected to terminal). For headless operation, unplug power or SSH in and kill the process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment