Big Deploy Button
the arcade in your heart
Gabe // Oct. 4, 2019

A while back I purchased a dozen 100mm arcade buttons in the hope that I could make physical artifacts with them. At my previous employer I thought it would be fun to use one of them for something vaguely useful, thus the Big Deploy Button (BDB) was born.

The Design

The button has a massive stem with the MicroSwitch actuator at the end of it which means that it can't quite be a small build. The measured length of the stem is nearly 2 inches. This means I'd have to use between eight and sixteen layers of plywood and acrylic in order to enclose the stem, lighting and microcontroller. This also allowed for room (barely) to put in a key interlock device so not just anyone could deploy to prod.

The Build

Alternating layers of 2447 Acrylic and plywood were used to build the body. A few attempts were involved with the key interlock since I somewhat neglected the reality of geometry and cut out space for the faceplate but not the actual stem of the key interlock device. The layers were impregnated with holes in the structure and these holes were then filled with hot glue as the build progressed. The bottom layer above the base plate included a small gap where the USB cable could be passed through for power and initial flashing. Two sets of leds were installed into the structure, one facing down into the base plate which was acrylic and another facing up into the body of the device. The key interlock was friction fit into its faceplate and the whole assembly was lowered into the slot and glued into place. The microcontroller, of the venerable esp8266 family was carefully wired into the LEDs and key interlock and stuffed unceremoniously into place. This was done in two halves both containing approximately half the volume of the device and the hot glue that escaped during the initial build up provided just enough tack for the two halves to stick together firmly.

The Code

Micropython was used for its ability to quickly prototype simple logical components and was approximately below.

import machine, network
from machine import Timer, Pin
from neopixel import NeoPixel

# global DEPLOYING
DEPLOYING= False


UP_LEDS = 16
DN_LEDS = 8

# ws2812 pins upfacing/downfacing
p_WS_UP = Pin(13, Pin.OUT)
p_WS_DN = Pin(12, Pin.OUT)
np_UP = NeoPixel(p_WS_UP, UP_LEDS, bpp=4)
np_DN = NeoPixel(p_WS_DN, DN_LEDS, bpp=3)

# network
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
if not sta_if.isconnected():
    sta_if.active(True)
    sta_if.connect('blah', 'blah')
    ap_if.active(False)

    while not sta_if.isconnected():
        for i in range(UP_LEDS):
            np_UP[i] = [0x0,0x69,0x0,0x32]
        for i in range(DN_LEDS):
            np_DN[i] = [0x0,0x69,0x0]
        np_UP.write()
        np_DN.write()


# key nd button switches, wired between the pin and ground so we pull em right up
p_SW_KEY = Pin(14, Pin.IN, Pin.PULL_UP)
# also lmao 15 is reserved, 16 is unpullable
p_SW_BUT = Pin(5, Pin.IN, Pin.PULL_UP)

tim_pd = Timer(-1)
tim2_pd = Timer(-1)

def set_deploying_false(*timer):
    print("Cbfalse")
    globals()['DEPLOYING'] = False

def set_deploying_true(timer):
    print("cbtrue")
    globals()['DEPLOYING'] = True

def printstates(args):
    # print("BTN", p_SW_BUT.value())
    # print("KEY", p_SW_KEY.value())
    print("DEPLOYING", DEPLOYING)

def write_ws2812s(timer):
    DEPLOYING = globals()['DEPLOYING']
    print(DEPLOYING)
    print("ELIF", p_SW_KEY.value() == 0 and p_SW_BUT.value() == 0 or DEPLOYING)
    if p_SW_KEY.value() == 0 and p_SW_BUT.value() == 1 and not DEPLOYING: #key turned and button pulled high
        for i in range(UP_LEDS):
            np_UP[i] = [0x0,0x66,0xCA,0x0]
        for i in range(DN_LEDS):
            np_DN[i] = [0x0,0x66,0xCA]
    elif p_SW_KEY.value() == 0 and p_SW_BUT.value() == 0 or DEPLOYING: # key turned and button pulled low / "deployin"
        for i in range(UP_LEDS):
            np_UP[i] = [0x89, 0x89, 0x89, 0x0]
        for i in range(DN_LEDS):
            np_DN[i] = [0x89, 0x89, 0x89]
        if not DEPLOYING:
            print("")
            tim_pd.init(period=0, mode=Timer.ONE_SHOT, callback=set_deploying_true)
            # replace this with HTTP code that eventually hits set_deploying_false
            urequests.get("http://gmp.io")
            tim2_pd.init(period=10000, mode=Timer.ONE_SHOT, callback=set_deploying_false)

        else:
            pass
    else: # key unturned
        for i in range(UP_LEDS):
            np_UP[i] = [0x89, 0x0, 0x0, 0x0]
        for i in range(DN_LEDS):
            np_DN[i] = [0x89, 0x0, 0x0]
    np_UP.write()
    np_DN.write()

tim = Timer(-1)
tim.init(period=100, mode=Timer.PERIODIC, callback=write_ws2812s, )

The indicator lights were used to Signal to the user the various states the device was in.

  • A mint green emanated while the device was looking for and connecting to the wifi network
  • The default state once the device was connected to the wifi was a solid red
  • Once the key was turned it indicated in a deep blue
  • Once the button is pressed, the indicator glows white temporarily until the network request completes then turns back to the blue.