Skip to content

Control an LED strip with the GPIO Header

The GPIO Header addon brings the MSR-2's spare pins out to a row of headers, so you can hang your own hardware off the sensor. This guide wires a WS2812B strip to one of those pins and gets it into Home Assistant as its own light entity, color picker and effects included.

The same steps work on any Apollo device with a mezzanine port, including the MTR-1 and AIR-1. Click any photo to see it full size.

What you need

  • An Apollo MSR-2, or any Apollo device with a mezzanine port.
  • The Apollo GPIO Header addon.
  • A WS2812B (neopixel) RGB strip. SK6812 RGBW strips work too.
  • Three male-to-male DuPont wires. A set comes with the header.
  • A USB-C cable and power brick.

Watch the current draw

The 5V pin supplies up to 300mA. A meter of 60 LEDs at full white draws far more than that, so anything longer than a short strip needs its own 5V supply. You can power the MSR-2 itself from the 5V and GND pins instead of the USB-C port, but use one or the other, never both.

Choosing a data pin

IO2, IO4, IO6, and IO7 are free for LED data, and you can drive more than one strip by giving each its own pin. IO18 and IO19 are unavailable, and IO0 and IO1 are reserved for I2C sensors. This guide uses IO7, plus the 5V and GND pins at the top of the header for power.

Pinout diagram of the Apollo GPIO Header showing the 5V, GND, and IO pins

Attaching the GPIO Header

  1. Unplug the MSR-2 from power and pull the back plate off.

    MSR-2 with the back plate being lifted away MSR-2 PCB exposed with the back plate removed

  2. Line up the X marked on the MSR-2 PCB with the X on the GPIO Header. Both face the same way.

    The X marking on the MSR-2 PCB aligned with the X on the GPIO Header

  3. Press the header down onto the small black mezzanine connector, then check it sits flat with no gap along either edge.

    A thumb pressing the GPIO Header onto the mezzanine connector GPIO Header fully seated flat against the MSR-2 PCB

  4. Slide the blue GPIO back plate that came with the addon over the sensor and press until it clicks. If it needs more than light pressure, stop and check the orientation rather than forcing it.

    Blue GPIO back plate being fitted to the MSR-2

Wiring the strip

  1. Run three wires from the header to the strip: 5V, GND, and data. Matching the colors to the strip's own wiring saves a lot of squinting later, so use red for 5V, white for GND, and green for data on IO7.

    Red, white, and green DuPont wires laid out next to the GPIO Header DuPont wires pushed onto the 5V, GND, and IO7 pins Close-up of the three wires seated on the GPIO Header

  2. Plug the other end into the strip. Most strips come with a JST-SM pigtail carrying the same three colors, so the wires match up directly. The connector is rated to 3A.

    JST-SM connector on the end of a WS2812B strip DuPont wires plugged into the strip's JST-SM connector

  3. Check the direction before you power anything on. Arrows printed along the strip show which way data flows, and they need to point away from the MSR-2.

    Direction arrow printed on the LED strip pointing away from the sensor The wired end of the strip with the arrow running down its length

A dab of hot glue across the outer shells of the three DuPont connectors stiffens them into a single plug. (1)

  1. Keep glue out of the header's female pins. It will ruin the addon.

Hot glue joining the outer shells of three DuPont connectors

Adding the strip to your YAML

The MSR-2 knows nothing about the strip until you tell it how many LEDs there are and which pin they sit on.

  1. Open the ESPHome Device Builder app, find your MSR-2, and click Edit.

    The ESPHome Device Builder editor open on an MSR-2 configuration

  2. Add the block below at the bottom of the file, flush with the left margin so light: lines up with packages: and wifi:. Set num_leds to the number of LEDs on your strip, and change pin if you wired to a different port.

    light:
      - platform: esp32_rmt_led_strip
        id: bed_led
        name: "Bed LED"
        pin: GPIO7
        chipset: WS2812
        rgb_order: grb
        num_leds: 60
        default_transition_length: 0s
        effects:
          - pulse:
              name: "Slow Pulse"
              transition_length: 1000ms
              update_interval: 1000ms
              min_brightness: 50%
              max_brightness: 100%
          - pulse:
              name: "Fast Pulse"
              transition_length: 100ms
              update_interval: 100ms
              min_brightness: 50%
              max_brightness: 100%
          - addressable_rainbow:
    
  3. Check that the editor shows no red error markers.

    The ESPHome editor showing the new light block with no errors flagged

  4. Click Save, then Install, and pick Wirelessly. ESPHome compiles the firmware and sends it to the MSR-2. The first build takes a few minutes.

Older versions of this guide set rmt_channel: 1 on the light. ESPHome dropped that option, and leaving it in now fails validation, so the block above does not use it.

The ESPHome light effects reference covers everything else you can add under effects:, including addressable_scan.

Controlling it from Home Assistant

Once the install finishes, the MSR-2 exposes a new light entity called Bed LED.

The Bed LED entity listed on the MSR-2 device page in Home Assistant

Click the entity name to open the light card. The color wheel covers the full range, and the effects list holds the two pulses and the rainbow from the YAML above.

Home Assistant light card for Bed LED Color wheel open on the Bed LED card Effect list showing Slow Pulse, Fast Pulse, and rainbow

WS2812B strip lit up in color behind a bed, driven by the MSR-2

That's all folks! Thanks to Smart Home Sellout for putting this tutorial together.