RGB LED Strip for 3D Printer With Octoprint

by bartojo in Workshop > 3D Printing

1113 Views, 4 Favorites, 0 Comments

RGB LED Strip for 3D Printer With Octoprint

PXL_20230714_132438522.jpg
PXL_20230714_130643976.jpg

I've wanted to improve the lighting on my 3D printer for some time. I decided to use individually-addressable RGB LEDs so that I could also use the lights to reflect the status of my printer using OctoPrint's API & a simple Python script!

Supplies

  • A 3D Printer
  • A Raspberry Pi running OctoPrint (mine is using the OctoPi image, but one running Raspbian or any other Linux flavor should work as well)
  • I'm using a Raspberry Pi 4 - other models should work (just know I'm referencing the Pi 4 pinout)
  • A strip of individually-addressable RGBs (I used a WS2182 strip. Mine had 150 LEDs over 16.4 ft - a higher density of LEDs may work better, but I already had this one leftover from another project)
  • Basic soldering experience & tools OR plug-and-play jumper cables for connecting the LED strip to the Pi
  • Heat shrink tubing (only necessary if soldering)
  • Insulated wires for connecting the LED strip to the Raspberry Pi (optional if using plug-and-play cables & your cables are long enough to reach the LED strip from the Raspberry Pi)

Hardware Connections

Note: You'll be using the Raspberry Pi to drive the LEDs. Depending on your Raspberry Pi placement, this might require longer cables. I've mounted my Raspberry Pi to the top bar of my printer to make the cable runs shorter using this mount I designed. You definitely can keep the Raspberry Pi closer to the height of the print bed, but it will require longer cables.

Pinout/Data Connection Diagram

Your RGB LED strip should have three connections - 5V/VIN, Data (sometimes shown as "DI" for "Data In"/"DO" for "Data Out"), and Ground/GND. These connections will be attached to the following pins on the Raspberry Pi:

  • 5V -> 5V power [Pin 2]
  • Data -> GPIO 12 (PWM0) [Pin 32]
  • Ground -> Ground [Pin 30]

Image from Official Raspberry Pi Documentation

You can use a different GPIO port - just be sure to remember which # GPIO port you chose ("12", for me).

Actual Connecting

Make the connections as described above in one of two ways:

Soldering

If you're handy with a soldering iron, solder appropriate cable to the pads on the RGB LED strip. Connect the other end of the cables to the Raspberry Pi via either solder or female jumper cables. If you use this method, it is recommend to apply some heat shrink tubing to the end of the LED strip where you soldered to keep the connections in place.

Plug-and-Play Connectors

Most RGB LED strips will come with at least one end pre-soldered with cables or even a header already connected. If that's the case, you can leverage this existing connector to make your connections to the Pi even easier.


Note about logic level shifters: Many similar tutorials will recommend the use of logic level shifters between the Pi and the Data line of the LED strip. Most LED strips operate with a 5V logic level, while the Raspberry Pi operates at a 3.3V logic level. You can buy logic shifters to correct this fairly easily, but in my experience, it's only an issue when driving longer LED strips. I only had a total of 9 LEDs in my short strip, so I didn't have the need to work in level shifters, but your mileage may vary.

Software

The software for this project is fairly straightforward. I had to install the following dependencies on my Pi (with commands):

sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel

With those packages installed, we can now write our Python script. Place this in a location on the Pi where you can easily find it (something like `/home/pi/leds`, for instance).

Python Script (led_controller.py):

import requests
import board
import neopixel
import time

OCTOPRINT_API_TOKEN = "UPDATEME"
NUM_PIXELS = 9

pixels = neopixel.NeoPixel(board.D12, NUM_PIXELS, bpp=3, auto_write=False, brightness=1, pixel_order=neopixel.GRB)

headers = {'Authorization': f'Bearer {OCTOPRINT_API_TOKEN}'}

# Helper Functions to display specific colors
def show_white():
    pixels.fill((255,255,255))
    pixels.show()

def show_white_dim():
    pixels.fill((50,50,50))
    pixels.show()

def show_red():
    pixels.fill((255,0,0))
    pixels.show()

def show_blue():
    pixels.fill((0,0,255))
    pixels.show()

def show_yellow():
    pixels.fill((255,255,0))
    pixels.show()

def turn_off():
    pixels.fill((0,0,0))
    pixels.show()

# Function to get the current status(es) from Octoprint
def get_current_status():
    try:
        status = requests.get("http://localhost/api/printer", headers=headers)

        flags = status.json().get('state', {}).get('flags', {})

        active_statuses = []

        for flag in flags:
            if flags[flag] == True:
                active_statuses.append(flag)

        return active_statuses
    except:
        return ['errors']

# Infinite 'while' loop that checks the Octoprint status every 2 seconds
def watch_status():
    while True:
        status = get_current_status()

        if "errors" in status:
            show_red()

        elif "paused" in status:
            show_yellow()

        elif "printing" in status:
            show_white()

        elif "ready" in status:
            show_white_dim()

        time.sleep(2)

watch_status()

You will need to update the OCTOPRINT_API_TOKEN variable with your Octoprint API token. Once logged into the Octoprint UI, you can find this by navigating to "Settings" > "Application Keys". You can generate a new one on that page specific to your LED script.

If you did not use GPIO Pin 12, you'll need to update the "board.D12" variable in the NeoPixel constructor with the GPIO Pin # you used.

Ensure the script has "execute" permissions:

chmod +x led_controller.py

The script should start if you run:

sudo python3 led_controller.py

The script must be run as sudo in order to properly control the Raspberry Pi's GPIO pins.

Color Automation

As written above, the script controls the RGB LEDs in the following ways:

  • If Octoprint experiences any errors (or if it is unreachable/still starting up), the LEDs turn RED.
  • When a print is paused, the LEDS turn YELLOW. This is helpful if you insert pauses into your gcode for changing filament colors at a certain layer.
  • While printing, the LEDs turn WHITE. This helps illuminate the build plate.
  • While ready (but not printing), the LEDs are still WHITE, but much dimmer.

Feel free to customize the above code to add your own colors or use different Octoprint statuses to fit your needs!

Running Automatically on Startup

If you want this script to run automatically (in the background) whenever your Raspberry Pi is running, add a crontab entry for it. Do this by first running:

sudo crontab -e

This will allow you to edit the crontab file. Add a new entry with the following:

@reboot python3 /PATH/TO/YOUR/SCRIPT/led_controller.py &

Restart your Pi, and your LEDs should be automatically controlled!

The End

That's it! You should now have an RGB LED strip mounted to your printer, controlled by the same Raspberry Pi that runs Octoprint. If you hit any issues or have any feedback, please let me know in the comments below! Good luck!