Heads Up Signpost

A motion sensing signpost to randomly direct players left or right

Similar projects worth following
Another hockey (or other sports) gadget. To encourage players to keep their eyes up while moving, this motion sensing signpost will randomly signal left or right to direct the athlete around an obstacle. Other modes are supported, including alternating left/right or timed random left/right (with 5, 10, 15 or 30 second countdowns).


The Signpost is related to my Timing Gate project: it was an intermediate effort to experiment with powering a micro controller from a LiPo battery with a USB charger. The design is based around the Adafruit Trinket M0, and features

  • a single button for mode selection
  • two strips of NeoPixels as a display
  • a PIR motion sensor
  • LiPo battery power with a TP4056 charging module

The NeoPixel strips are independent for ease of assembly, but could be reduced to a single strip with the left and right sides managed in software.

Software is available on Github.


The Trinket M0 has a nice on-board power path: battery and USB bus voltages are OR'd (through two Schottky diodes) into a AP2112 3.3V 600mA LDO. The AP2112 has a max 400mV dropout, but nominally that drops to less than 200mV below 400mA output current, so it works fine with a LiPo cell (3.7V - less than 200mV dropout - say 300mV Schottky diode = 3.2V). It can also easily regulate the battery while charging (4.2V).

Both input levels (3.7V for the battery, 5V for the USB bus) will power the NeoPixels. Technically, a level shifter is required for the data line from the M0 to the NeoPixels when the supply is 5V and the processor is running at 3.3V (spec says "high" is within 70% of Vdd), but everything will work fine on battery power. I've tried both (with the 74HCT125 as a level shifter and directly writing to the NeoPixels at 3.3V), and both work for prototyping. However, because both the battery and USB bus voltages are inputs to the LDO, prototyping requires a manual jumper to switch back and forth between sources.

The PIR module includes its own 3.3V LDO (mine came with an HT7133-1), which needs to be bypassed to power everything off of the 3.3V supply from the Trinket. This was done by removing the LDO with a hot air gun and soldering on a jumper (which should also qualify this build for HaD). 


The "display" for the signpost is two sets of 12 NeoPixels arranged in a staggered grid. To concurrentlysupport polling the mode button and PIR and displaying animated symbols, I wanted to avoid blocking calls to the display. To handle this, I added a frame clock based on a hardware timer interrupt. This is not well documented for the Trinket M0 and depends on some understanding of the SAMD21 datasheet. I used the following examples & notes

and I'm grateful to the authors for putting those together. Basically, the SAMD21 has a collection of "timer/counter" (TC) modules that can be associated with various clocks (including the XO, etc.). The TC modules have some prescaling (max 1024), and support 8, 16 or 32 bit counters. Interrupts call a specific handler that is predefined. The 32 bit counters are made by joining a pair of TC modules, but I was not able to get that to work -- the examples above are all 16 bit counters, but in the end that was sufficient for my purposes (max time is 2^16*1024/48000000 = 1.3981 seconds). My implementation is in I tried to generalize it a bit to target different TCs, but this could be improved.

Main Loop

With the frame clock as described in the previous section, the main loop

  • checks the PIR state for an edge (and loads an appropriate animation if triggered)
  • checks the (software debounced) mode button (and loads an appropriate animation if triggered)checks the
    • mode animations can be interrupted so that the mode button can be quickly pressed repeatedly
  • checks for a frame event and ticks the active animation if present

The frame clock is also used for the countdown timers, which cycle by

  • display a start symbol (both left & right arrows simultaneously)...
Read more »


Base plate 3MF with snap fit bracket for a 6mm momentary push button, a small LiPo battery and a TP4056 charging module (needs RetainingClip.3mf and a knurled insert for screw). Tripod mount with a 1/4"-20 screw & knurled insert.

3mf - 34.04 kB - 01/05/2022 at 01:55



Printable bracket for button type NeoPixels. Print two (one mirrored). Solder NeoPixels in a strip.

3mf - 65.49 kB - 01/05/2022 at 01:55



The enclosure. No supports required, but might help with the opening for the PIR. Heat set knurled inserts to secure light panels (M3) and base plate (M4).

3mf - 69.35 kB - 01/05/2022 at 01:55


3mf - 5.30 kB - 01/05/2022 at 01:55


MPEG-4 Video - 7.84 MB - 01/05/2022 at 01:54


View all 13 components

  • 1

    Print the base plate, top shell, retaining clip and two light panels (left and right mirrored). Heat set the knurled inserts

    • 1 1/4"-20 in the bottom of the base plate for the tripod screw
    • 1 M3 in the top of the base plate for the TP4056 retaining clip
    • 2 M3 in the top shell sides for the light panels
    • 6 M4 in the top shell to secure the base plate

    Drill two M2 holes for the PIR (countersinks are printed on the front face).

  • 2
    Light Panel Assembly

    This is extremely tedious: place and solder wires between each of the 12 NeoPixel buttons in the order shown in the diagram. Repeat for the other panel. At the input side of each strip, terminate with a JST connector.

  • 3
    Main Board Assembly

    Place two strips of female headers to receive the Trinket. Underneath, add a 3 pin 90 degree male header (for a jumper): one outside pin connects to the Trinket's Vbus, the other to the Trinket's Vbat. The central pin is Vled to power the NeoPixel strips. Add a 100-1000uF decoupling cap between Vled and ground. Add 5 male JST receptacles:

    • 1x 2 pin for Vbat input
    • 1x 2 pin for the mode push button
    • 1x 3 pin for the PIR (3.3V, data, ground)
    • 2x 3 pin for the NeoPixel strips (shared Vled & ground, separate data lines)

View all 5 instructions

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates