Lander Module Category

8 Articles

alphanumeric & 3d printing

25 Jul 2021

categories: Lander Module
tags: HT16K33

Recent efforts have gone into getting the 14-segment alphanumeric display working. I first tried it with d2r2’s translation of the Adafruit library into Golang, but that proved a little frustrating. I then pivoted to’s experiment, and that worked much better. I do have to wrap it in some logic for a few reasons:

  • out of the box, it panics in certain situations related to the decimal
  • I will need a single interface that ends up controlling multiple ht16k33 devices (as in a 6- or 8-digit display)
  • I will likely need to implement scrolling text
  • I may or may not need the interface to control a whole line of nearby displays (as in the case where there are two 6-digit timers, but sometimes they work together to scroll a long string) But I got the test (ht16k33Test) to work! Here are some next steps I’m tracking:


  1. incorporate a segmented display into the console, and the modeTest. Have the display print different things in different modes.
  2. try using periph/conn/gpio instead of warthog618/gpiod
  3. begin playing with the I2C multiplexer board
  4. begin playing with the oled screen
  5. order a 24-bar graph (also based on ht16k33), and play with that
  6. begin playing with the analog joystick
  7. flash the Butterstick with normal-ass keys and write a listener specifically for those keys


  1. experiment with the textured Prusa print plate?
  2. Measure the keyboard cutout, 3dp a cover with known rectangle cutouts and screw-holes.
  3. Print a switchplate for the butterstick
  4. Make cuts for other panels, determine how to screw panels on


  1. Go to the first build crew meeting
  2. establish communication with someone who can help with the power circuit
  3. re-establish who is writing the narrative

As of the last meeting (7/22 with Dr Professor), we had a sketch of the final layout of touchpoints (see notes/layout_1.png). It did not include the bar-graph module though…

~ ~ later that day ~ ~

First print of a panel was a huge success! I did the thermal printer. I made the cuts to the vent port, and now the TI-99/4A is ruined! (for any other purpose).

The spacing of the vents is such that I think I’ll need to use #3 screws. It also happens that that’s the size that should fasten the printer to the plate! So far I’d been imagining using my stock of #8 screws, but it’ll be good to have options.

Case in point: I’m printing test plates now for the keyboard backer and keyboard switchplate, and the first test uses #8 for both, but I can already tell that no. 3 might be more fitting to fasten the switchplate to the eventual front plate.

Did some more thinking about the 24-bar graph idea. I think I’ll pick up a few to play with, but I don’t think there’s room for them on the console.

RPi4 setup, The Game-Stack

4 Jul 2021

categories: Lander Module
tags: golang

To dev on the RPi 4 I have to first update it:

sudo apt update
df -h # to check disk has enough free space
sudo apt full-upgrade
sudo apt clean

The game stack (tm) requires some careful thinking. I almost want to thread the quit signal all the way down, from main to the game server, to the modal game, to each mode. Because (a) the modalGame Run() can’t block on the mode’s Run(), and (b) we’ll want to wait while a mode finishes Close() before we Setup() the next mode.

So, a Run() needs to return a signal, and be non-blocking. And the selector switch needs to provide a signal for its value changes. And the modalGame’s Run() needs to listen to three signals:

  • quits from above
  • changes from selector
  • dones from below

Something like this:

func (mg *modalGame) Run(quit chan bool) (chan bool, error) {
  done := make(chan bool)

  go func() {
    run := true
    for run{
      select {
        case <-quit:
          run = false
        case <-selector.ValueChange():
          // start new mode
        case <-mg.currentModeExited:
          // clean up


The overall structure is proofed here:

Question: do I need games to return a channel for error-forwarding?
Answer: Probably not:

  1. nobody is going to read the logs of this thing (ooh! that gives me an idea though: there should be a button in test mode that prints the logs?! Or will that waste paper?). So it’s reasonable for the game to just log the error and exit 1 or whatever
  2. what would the listener do about it? tell the game to quit? the game should be the one to make that distinction itself

Question: when a mode in the modal game exits organically, what should happen?
Answer: What this means is that someone has completed the mode. They’ve done all the sequences, and gotten a report card. However it happens, the console should be rendered inoperable until the User Switch is reset. In program terms, I think it’s ok for the current modalTest to exit out.

      listen to changes to the mode selector switch

In the actual program, the testing, launch and landing games will not end of their own accord, but keep listening for a rising edge of the user switch. This behavior allows the user to “reset” their experience, if necessary. (Though perhaps they’d have to hit a kill switch to get the sequence to stop in the first place).

      listen to changes to the mode selector switch
        listen to changes to the user switch
        listen to changes to the user switch

Question: do we even need the games' Run() to return an exit code? I wonder what kind of runtime (pun intended) error would be catastrophic in that way.
Answer: let’s wait and see, after I do the next level of tests

End of day progress report:
Work continues apace! The modeTest runs, but it has at least one bug :P

  1. I should have an “off mode” handy.

  2. I should try out stubGame.

  3. if I leave testingGame, the listener for the selector stops? All I got was

    go run src/cmd/modeTest/main.go
    game server starting
    selector value changed to 1
    selector value changed to 2

    …and that’s it! no more input made any changes. I had to kill the main process and one subprocess to get the gpio back.

First step: more logging.
Well, second step. First step: try to sleep.

state machine

3 Jul 2021

categories: Lander Module

A few things are clear today:

  • I should dev on the RPi 4, so I can remote SSH in with VS Code
  • The next software hurdle to cross is the modal architecture. To that end I’ve worked up an interface and implementation that uses a guitar pickup switch as a SP5T instead of its normal operation (three digital outs, five positions: 100, 110, 010, 011, 001)
  • This modal idea is about to get a little hairier. I’m coalescing ideas about different sets of components, that get read at different times. The program essentially has to go through a state machine. Perhaps I should build the state machine as a first-class entity. The first step is probably to graph it out.
  • During development of this machine, I should keep a close eye on how reliable the experience is. Are there intermittent errors with pin lines unable to open or close? etc. If it becomes unreliable, I need to start keeping a reliable version printed and ready to install in the chassis. I don’t mean to use this policy to encourage breaking things, but rather to mitigate against what I know has been my pattern with software as a whole…

Oh gosh, I just realized a SP4T won’t work to do both power and data, unless I do some fancy diodes and voltage step-downs. No, let’s keep it simple and use two admin keyswitches. For the admin touchpoints, I wonder if I can fit them all (2 keyswitches and a USB…and an HDMI?) in the expansion slot. Or if I should just make them regular slide switches behind a screwed-on panel. Hmmmm, no, that’s too much touching, and what if the panel loses threads and falls off? For that HDMI question, I wonder if RPi can connect to phone hotspot and I can ssh in through that? New ticket!

So, next step is to mock this up using the guitar pickup switch as the “mode”, and assume power switch is on. Then, set up at least two different mode games, that each use the same toggle and LEDs, but with different behavior (e.g. test mode flashes an led while the toggle is held, but the landing mode latches the led).

transcribed to Go, looks promising

30 Jun 2021

categories: Lander Module

I have successfully transcribed my simple python script to a slightly-less-simple go program. No, I don’t know why I call python files “scripts” and go files “programs”. I’ve been using the library. It seems to do what we need. I didn’t immediately understand the WithFallingEdge option, but edge detection is easy enough to implement, and I bet if I tried again to figure it out I could.

It’s time to try the next hurdle, and this time to start in Go. I have a Quad Alphanumeric display backpack here, and it’s supposed to work over I2C. So let’s get it soldered and breadboarded!

first done 3d print, first done code!

29 Jun 2021

categories: Lander Module

First tests are promising! I have completed a 3d-printed bracket mount for the digital joystick. I have also completed a short program that reads a single mom-off-mom toggle and latches an LED every time it goes up or down. I wrote it in Python, but my hopes are high that I can transcribe it to Go next. Some resources I should look into for that effort:

  • I have also ordered the 3rd round of parts from Adafruit and Digikey, and finished intake processing for the 2nd round. Upcoming experiments are:
  • write to a 14-segment timer/countdown display (using mission-start time, and also event-start time)
  • write to an OLED display, perhaps by putting a ship graphic overlaid on a landing zone graphic.
  • super extra credit: use an OLED display like an attitude gauge!
  • write a “main alarm” sequence, with buzzer When the 3rd batch of stuff comes in, I’ll be able to
  • play with I2C I/Os
  • vet some more toggle switches I should not purchase any bulk switches or buttons until after the second production meeting with Deeps, on 8 Jul.

oof, getting this first script done feels good. Hurdle over!

More thoughts, this time about upcoming 3d-prints:

  • should print a couple more joystick brackets
  • should print several more switch guards
  • should test hole size for m2 and m3 screws (for mounting PCBs on)

LED driving, I2C chains, pull-up and -down resistors

27 Jun 2021

categories: Lander Module
tags: gpio i2c

I’ve been getting up to speed on LED driving and button/switch driving, so that I can prototype a Raspberry Pi with code that reads a switch, and turns on and off an LED. A couple of thoughts here:

The RPi 0W has 26 available GPIO pins. This feels like a lot, but if I pair one or two LEDs with each toggle switch, I’ll run out quickly.

Next I found this AW9523 breakout, which controls 16 I/O over I2C. If I give up 2 ports on the main board itself for I2C, and I can chain 4 of these expanders together, that gives me a total of 88 I/O ports!

The printer code I’ve been working with so far in Tissubots takes the serial pins away too (Tx/Rx are GPIO 14 and 15), so we’re looking at about 86 pins.

what about our 14-segment digit displays? those run on I2C as well! first, know that they can be chained up to 8 in a row, so I only need one bus to drive all the segment displays on the whole console.

Can I run a second I2C bus on the pi? This instructable seems to think I can run 5 additional busses beyond the builtin one, if I modify the /boot/config.txt.

Where does that leave us? Out of the 26 available GPIO pins, maybe:

2 for tx/rx to printer
2 for I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: all segmented displays (up to 8 4-digit backpacks)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
12 remaining pins on RPi
64 * 5 + 12 = 332! :flushed:

ok so it’s time to order some of those expanders I guess.
I won’t use all those pins, obviously. In fact, I will probably set up one chain for just LEDs (using its nifty constant-current feature), and one chain just for buttons/switches/joysticks (using pull-up or -down resistors). I still have 3 (supposed) available I2C buses! maybe if I use a buzzer that requires its own breakout? or I could add in a little OLED display (4-wire SPI).

A “pull-down” resistor goes between digital pin and ground. Then put the button between voltage and the digital pin. The resistor pulls the pin down unless the button is pressed (connecting voltage).

A “pull-up” resistor is like “pull-down”, but swap the ground and supply nodes. All else being equal, it seems to me it would save power if we use pull-down. How to select the resistance: resistor should be “1/10 less than the input impedance of the digital pin” (does this mean 90% of the input impedance?) (or 10kOhm if you can’t be bothered).

RPi has onboard pull-up and pull-down resistors, but if we put all the buttons and switches on expanders we’ll need to use resistors in connection to the expander.

It would be especially cool if each panel on the console ended in its expander. That way it would be very quick to swap out a dud panel. Just need a board near the RPi that has all the JSTs for the different expanders. Maybe…huh, maybe even a Hat for it! Can I make my own RPi hat?

toggle switch guard print #1

18 Jun 2021

categories: Lander Module
tags: 3dp fdm

I printed out the “space shuttle toggle switch guard”. In plating I selected the single guard then did “Add Part” to expand it to a row of 5. Then, in print settings I made sure to go into Expert > Infill and set “Solid infill threshold area” to 16mm^2. This ensures there’s a solid infill for the upright portions of the guard, extending just below the joint with the side plates. Overall, quality was pretty low, probably due to all the jumping around, and bridging. For the next attempt, I may want to re-model the holes for the switches, since the switches I bought are nowhere near fitting the holes as-is. I might also want to try a build in a different orientation? or with different infill options (was it really necessary to use solid, or to use infill at all?) Anyway, good first attempt!

Oh, for the second iteration I could avoid the 12-hour time by just printing squares with holes in, and inset the squares to the guard I have! CA glue will be a key part of the build anyway.

In other news, first Digi-Key order arrived and it is great! Lots of buttons to push and the joysticks live up to their name (especially the ball-top one).

For the next round of orders I want to try to get a large square button or two, for a “main alarm” function. These can be pricey, but with only 1 on the board I think it’s worth it. I also want to try out some “standard round” toggle switches, because I can print out the cover to make it look more spacey.

Project start, core principles

17 Jun 2021

categories: Lander Module

A couple weeks ago Dr Professor asked me if I want to build a thing for Caravan Rally (happening this October). So far we’ve been talking about a “lander module” experience. Here are some parameters:

  1. it should be fun, engaging and diverting
  2. it should involve 2-3 people working together
  3. it should last about 5 minutes
  4. it should entail the operators landing a spacecraft
  5. it should be able to answer the question “how well did the operators land the spacecraft?”

Immediately my mind jumped to Moon Lander, and to the Apollo 11 VR experience. Drawing from those, and from this awesome Kerbal controllerf1, I’m building a game/toy/gadget that fits the above parameters.

I’m tracking parts and tickets in an Airtable.

Project is due in mid-September.

I will have regular meetings with Dr Professor to provide progress reports.


The main piece of this is a console that can fit in someone’s lap, have a bunch of knobs and switches and gauges on it, and be an operable computer for landing a spaceship.

The LM is meant to be operated by one person in a Caravan vehicle.


I’ve purchased a TI-99/4A to provide the “chassis” for this console.

I am experimenting with various buttons and switches that light up. I intend to build these into panels which can be screwed to the chassis, and plugged into a pcb. The pcb will connect the panels to power, and to a central controller like a Raspberry Pi or Arduino.

If I design any PCBs, their cad files will be stored in [a private] repository.

The whole thing will be powered by battery that may potentially be charged by USB and/or cigarette lighter.

Here are some ideas for devices that the console could use:

  • sliders, buttons, and switches. Momentary vs toggle.
  • a joystick, e.g. for precise control of maneuvering thrusters
  • dial or linear gauges. Not sure yet how to achieve this except perhaps a decal’d voltage meter. Perhaps a stepper motor and small screw.
  • 7-segment LCD indicators, e.g. for a mission timer
  • OLED or e-ink screen, e.g. for precise graphics
  • thermal receipt printer, e.g. for printing event summary, and/or scenario parameters
  • extra-special credit: real-looking attitude indicators
  • speakers, for playing sound effects of explosions etc.
  • buzzers, for when an alarm goes off.

More flighty ideas include:

  • the computer networks to a “GM” computer that allows a second human to control the sequence parameters
  • the computer networks to a small switch computer in each other car, to indicate caravan readiness
  • the computer has an audio output (cable, bluetooth, fm transmitter) for making the ship sounds be more…immersive
  • an on-board accelerometer and/or microphone, to implement an interaction like “if this gauge goes dead, try tapping on it”


The sequence code is another key part of this deliverable. It should fulfill the primary parameters, and if possible fulfill these secondary parameters:

  • the sequence should develop iteratively, so that I can always deliver a serviceable experience.
  • the layers of the application should stay separate, so that I may reuse them in future projects (that may or may not involve spaceships).

All source code will be stored in [a private] repository.


Another piece of this is a section of the Flight Manual dedicated to operation of the Lander Module (LM). This document will be read and interpreted by others in the Caravan vehicle.

The whole Flight Manual document will include more elements than I provide from this project.


Here’s where the fun starts. In order to keep it simple and deliver an MVP, I feel I should focus on core competencies:

  1. Main sequence. Player must push buttons in correct order to transition through multiple stages of landing.
  2. Controls include momentary and toggle inputs
  3. Indicators include a mission timer (counting up), event timer (counting down), and various LEDs
  4. Stages are: Atmospheric Entry, Main Drag (Parachute), Maneuvering, Touchdown

For each stage, the controls and indicators do slightly different things. For instance:

  • During Atmo the controls change the ship’s attitude, and the indicators show attitude, heat levels, and altitude. Final action to change stage is to eject the heat shield in a specific heat/altitude window.
  • During Main Drag, the controls are really just to deploy parachutes, and the indications are altitude, vertical speed, and ground speed. Stage exit is to cut the parachutes in a specific altitude/speed window.
  • During Maneuvering, controls are to align the ship with the landing zone, and make sure you don’t crash. Indicators are speeds, and some kind of “pointed-in-the-right-direction”-ness. Stage-exit action is to deploy landing gear when you’re in position and have 0 ground speed.
  • During Touchdown, controls are to burn the landing thruster. Indicators are speeds, and whether or not you went to space today.

That’s probably as simple as I’m willing to make it. If and when that’s done, I can implement new layers to it. For instance:

  • Parametric stages: These variables affect how the controls operate, but probably shouldn’t make the experience harder, just different. After all, the operators of this will likely get one “real” shot with it, so we can’t expect them to try many times, growing and learning.
    • Maybe the landing zone has really low/high gravity.
    • Maybe it has a heavy/light atmosphere.
    • The fuel or RCS mass starts at different levels?
  • Alarms: when the alarm goes off, it will blink various LEDs around the console. Based on which LEDs they are, there’s a different resolution pattern to perform (as detailed clearly in the Appendix of the LM Flight Manual).
    • the Heat Shield won’t separate, gotta blow the backup clamps
    • chutes won’t open, gotta deploy the backups
    • landing gear won’t deploy, cut throttle and blow airbags
  • Glitches:
    • maybe a DRO wonks out and starts showing garbage.
    • Maybe the whole console goes dead until you “power cycle” it.
  • New Sequences:
    • There’s an opportunity for a single “Launch” sequence at the beginning of the Rally. Maybe we could use this console for that too.
    • Maybe there’s a Training sequence for people to play with in the car before they have to do the real thing.
    • Maybe there’s a choice of landing zone.
  • More complex stages:
    • the Drag stage splits into two, for fast chutes and slow chutes
  • More complex inputs and outputs:
    • the Touchdown stage gets a screen and a joystick, and a “Moon Lander”-esque feel.

Questions for Design Team:

  • should we implement a Training Mode that lets them practice landing, say, on the Moon?
  • will we encourage teams to write their own margin notes in the Flight Manual?!