Raspberry Pi 3 GPIO: pushbuttons, LEDs for RC and BARR

R. X. Seger
Jul 11, 2016 · 5 min read

General-Purpose I/O on Raspberry Pi’s 40-pin J8 header:

Raspberry Pi 2 & 3 Pin Mappings from Microsoft Windows Dev Center

In this article I’ll be wiring up four inputs to pushbuttons, and four outputs to light-emitting diodes, then writing software to light up yellow to replay a remote control signal, and the green/red when certain aircraft flights are detected overhead, all controlled through the GPIO port. All the components I’m using are from the Sparkfun Raspberry Pi 3 Starter Kit.


Pi Wedge for breaking out the J8 header to a breadboard, uses abbreviated pin name labels, like “G17” for GPIO 17, and when a GPIO pin has an alternate function it lists that function instead, so GPIO 2 on pin #3 is labeled “SDA”.

Port selection is arbitrary, but I wanted to keep the overloaded pins available for their other purposes in the future, so I decided on:

  • Pin #11 / GPIO 17: green pushbutton


Sparkfun also sells a larger assortment of tactile buttons but the Raspberry Pi 3 starter kit includes one each of red, yellow, green, and blue. The pins connect as follows:

Tactile button pinout diagram

These pushbutton-style switches can be straddled across the center divider of the breadboard. Jumpers to connect pin #1 to +3.3 V PWR, and #4 to a GPIO input pin.

I had already connected these buttons in SDR first project: initial setup, node-hackrf, GNU Radio on Linux, OS X, RPi 3 w/ FM tuner, where they functioned as volume and channel controls, but I moved them further apart in the breadboard to allow room for the LEDs.


Light-emitting diodes:

20x 5 mm LEDs, 5x each: red (620–625 nm), yellow (587–591 nm), green (570–575 nm), blue (465–467.5 nm)

This is a garden variety pack of LEDs, there are many other colors not included: orange (600–610 nm) and violet (395–400 nm), infrared (940–950 nm, or 840–850 nm), ultraviolet (395–400 nm). There are other types of LEDs available, including different wavelengths of ultraviolet (UVA/UVB), from other suppliers such as LEDsupply and ThorLabs.

Ultraviolet could be useful as a blacklight, and infrared could be useful to send to infrared sensors on some RTL-SDR dongles (but not the RTL-SDR Blog silver dongle). But for now, I’ll only be using these red, yellow, green, and blue color LEDs from the starter kit.

Conveniently, resistors are included for current-limiting, 20 total (one each for the 5*4 LEDs):

330 Ω ±5% 1/6 Watt Carbon Film Resistors — 20 pack

All of the LEDs are suitable for use with the 330 Ω resistors at 3.3 V, at a reasonable brightness. Connect the resistor to one side of the LED, and to a GPIO port. Wiring should be straightforward, or see below for a photo.


After wiring up all the pushbuttons and LEDs and resistors to the GPIO pins, wrote a simple Python script using RPi.GPIO:

import RPi.GPIO as GPIO
BTN_G = 11 # G17
BTN_R = 12 # G18
BTN_Y = 13 # G27
BTN_B = 15 # G22
LED_G = 29 # G5
LED_R = 31 # G6
LED_Y = 32 # G12
LED_B = 33 # G13
GPIO.setup([BTN_G, BTN_R, BTN_Y, BTN_B], GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup([LED_G, LED_R, LED_Y, LED_B], GPIO.OUT, initial=GPIO.LOW)
while True:
[g, r, y, b] = [GPIO.input(BTN_G), GPIO.input(BTN_R), GPIO.input(BTN_Y), GPIO.input(BTN_B)]
GPIO.output(LED_G, not g)
GPIO.output(LED_R, not r)
GPIO.output(LED_Y, not y)
GPIO.output(LED_B, not b)

Script available here: gptest.py. Press a button and the corresponding LED should light up. Testing with all LEDs lit up:

LEDs and buttons wired up to Raspberry Pi GPIO

Application: remote control signal replay

As described in Receiving IR signals with RTL-SDR dongles, I’m using the IR sensor of a NooElec NESDR RTL-SDR dongle to receive signals from remote controls, currently for powering off or rebooting the device. But it would be nice to know whether IR is working without performing those actions, and to know what pulses are being sent.

Updated nec-pwr.py to flash the yellow LED, “replaying” the infrared signal 100x slower:

for group in groups:
if ‘0’ in group: light_leds(False)
else: light_leds(True)
time.sleep(len(group) * 20e-6 * 100)

It could be replayed even lower to help visually discern the pulses, or near realtime if desired, but I went with 100x for the time being.

Application: flight watchlist

On this same device I’m also running dump1090, tracking flights using ADS-B. But some aircraft are more interesting than others.

dump1090 can be interfaced through TCP port 30003, which streams CSV data using the SBS1 port 30003 format. We can connect to this port, pick out the callsign, and light up the LEDs appropriately. Script to do this:

Update 2016/07/12: latest version of flightled moved to https://github.com/rxseger/flightled

Edit the settings as needed, run sudo /etc/init.d/flightled start to begin, and sudo ln -s /etc/init.d/flightled /etc/rc5.d/S01flightled to run on boot. The script is configured to turn on the green LED when any flight with a callsign is observed, for one second. And the red LED turns on for 12 hours when a callsign listed in watchlist.txt is observed.

How to find “interesting” flights to watch? A good start is ListFAA-BARRpgm_2013.pdf, a list of 6912 callsigns from what used to be known as the Block Aircraft Registration Request BARR program, now the FAA Aircraft Situation Display to Industry ASDI Block. These aircraft are voluntarily blocked from FlightAware, FlightRadar24 (though not ADS-B Exchange), but homemade ADS-B receivers will receive them.

You can also find interesting callsigns by other means:

Circular flight pattern of a possible surveillance aircraft (not on the 2013 BARR list)


The GPIO is an easy and convenient means of providing simple button input and LED output on a headless Raspberry Pi. With a quick glance I can now test for remote control infrared signal decoding, dump1090 flight tracking status, and whether any particularly interesting fights were recently seen.

This is only a relatively unsophisticated configuration, much more is possible with GPIO including controlling various peripheral devices. The blue LED is software-controllable, but I haven’t figured out a use for it yet, nor the pushbutton inputs. Lots of possibilities for future expansion.