Well, as much as "Raspberry Pi" isn't a standard--it is a de facto standard. I ended up using a controlled version of the Raspberry Pi pinout as my host controller's connector.
After scoping everything out and tossing out some overly expansive ideas, the host controller board needed to include the following hardware interfaces:
- WS2812 for glow
- NRF24L01+ radios
- A few GPIOs: LEDs for blinkenlights, button for last-ditch software repair
- I2S bus for amplified audio
- I2C bus for attached displays and other outputs
I wanted to be able to source and replace the actual computers with ease. But as an independent artist self-financing this project, I didn't have the resources to be able to throw, say, a Compute Module at each of the ~40 machines. Thus, my key design goals for the computers were:
- Long-term support and good availability of supply chain
- Supports the above hardware interfaces
- Minimal cost
You might be thinking, "sounds like a Raspberry Pi Zero to me!" And you're not wrong--I did end up using many Zero Ws, slowly collected over 18 months, as part of this installation. But as a pandemic slowly crept across the globe in early 2020, and supply chains were torn asunder, I renewed my focus on making Maelstrom a multi-platform project through the design of "controller boards" that adapt non-Pi platforms to the Maelstrom/Pi pinout.
I ended up supporting these three platforms in Maelstrom:
- Raspberry Pi (Zero W, 3A, 3B, 4)
- ESP32
- Orange Pi Zero LTS
I was able to develop host controller boards for ESP32 and Orange Pi Zero that support the above hardware interfaces. My software detects the platform and adjusts the pinout and software modules to suit the host machine.
Despite my best efforts, there are some per-platform strangenesses.
ESP32:
- This is a very minimal C port of the Maelstrom Cython codebase that only supports the radio and WS281x for now. It is possible to add more device support down the road but this let me build ~12 of the machines with $4 host controller (vs ~$20 for Zero W, $18 Orange Pi Zero, $40-60 for Pi 3/Pi 4. The lack of SD cards helps bring the cost down.)
- This platform needs 3v3, which I initially planned to provide via 3V3 pins but later had to move to a regulator on the controller board.
Orange Pi Zero LTS:
- I wasn't able to locate Python or C libraries for the WS281X addressable LEDs. I added a microcontroller to this board's I2C bus
- There aren't enough GPIOs, so I added a PCF8574 I2C GPIO expander on the controller board to handle the extras.
Raspberry Pi:
- On some Pi boards, if you externally supply 3V3 via the GPIO header, it keeps the board from booting, perhaps due to power sequencing complexities.
By adapting the ESP32 and Orange Pi Zero LTS to my limited subset of the Raspberry Pi pinout, I ended up with a "Maelstrom pinout." This took a lot of staring at datasheets, library docs, and spreadsheets, and I still got it wrong several times--especially on ESP32, where some of the "GPIOs" are just "GPIs."
There was one big idea I wanted to build out that was totally incompatible with the main Maelstrom pinout, however: "HUB75" RGB LED matrix panels.
I ended up addressing this by making a separate, matrix pinout, only compatible with Raspberry Pi, and adding an extra pinout adjustment in the Maelstrom software. So a Raspberry Pi node will start up, read the EEPROM data from the attached host board--sort of like a HAT--and use that to decide whether it loads the "Maelstrom pinout" or the "Maelstrom matrix pinout."
This introduced a few new weirdnesses to work around in the Maelstrom matrix pinout:
- The matrix pinout, like Orange Pi Zero LTS, was short on GPIOs. I added a PCF8574 I2C GPIO expander here too. This GPIO expander needs to work alongside my directly-attached GPIOs, which use RPi.GPIO.
- I built out a shell script that attaches the PCF8574 as sysfs GPIOs, and launch a secondary instance of my software's GPIO module that uses sysfs GPIO.
- The existing sysfs GPIO Python module, named "gpio," had some performance problems, so I built out a simple shim version that functions like RPi.GPIO. It doesn't have edge detection or pull-up/pull-downs, since sysfs GPIO doesn't support these.
- Raspberry Pi 3 includes a GPIO expander that instantiates at the same sysfs GPIO number (/sys/class/gpio/gpio504) as a PCF8574 on a Pi Zero. If you write to this expander, you can power off the machine or make it unresponsive. (this took … a long time… to figure out.)
- The matrix library, rpi-rgb-led-matrix, is fantastically performant and has some particular pinout needs. Because of these, I needed to move the SPI0 CE pin that the NRF24L01+ radio uses. I built a device tree overlay and a Python DTO loader that remap CE0. (This is the point at which I realized that a second EEPROM on the i2c ID bus would have been handy for HAT autoloading!)
All of these hoops were helpful to jump through. I now have a multiplatform system that works reasonably well across the boundaries, and a given host controller board can be replaced with a completely different architecture in most cases--making it easier to address future electronics failures.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.