4 Knuckles: Modular Circuits for Machine Control
Many machine controller (and most open source / hackable) are controlled with monolithic control boards, where the control logic is centralized and boards include a limited set of IO devices (motor drives, inputs etc). There is a trend towards modular circuit ecosystems i.e. Duet, and (as already noted in Chapter 2 (and elsewhere?)) modular software interfaces.

One of the primary challenges that sets modular hardware apart from modular software is that hardware is more difficult to make generalizeable; not only do specific tasks require specific hardware arrangements, components also need to interface across variable networks and at variable power levels. For example even though motor drivers are all essentially the same, there is a broad range of particular motors to drive, each needing i.e. more or less current, voltage, and packaging.
Another challenge for modular hardware design is to develop a set of modules that can be broadly applied across different tasks. From an economic perspective, it is more productive to develop a smaller set of modules and apply them to many tasks to amortize costs more effectively. From a systems engineering perspective, it is better to make general purpose modules that can be applied across many tasks because this means systems assemblers can pick from a smaller catalog of parts to accomplish their goals. Of course this most of why we want to build modules in the first place: by breaking a system into parts, we can re-assign those parts in new systems. Here the challenge is to design the smallest set of modules.
Developing the complete set of modules and evaluating them properly with respect to those two goals is beyond the scope of this thesis, but I find it useful to bring the topic up and (1) discuss existing work in the domain and (2) offer as a contribution the design patterns that I have found useful during the course of this work. I do this mostly because enabling these modular ecosystems to thrive is a major goal of the other sections of this thesis, in networking (Chapter 2), in systems assembly (Chapter 3) and in motion control (Chapter 5). In each of those sections, my main challenge was to dissassemble systems that work very well on monolithic hardware, and then see how to put them back together if their constituent bits were modular. The dream (that I share with many of my peers, collaborators and forebears) of having a handful of modular circuits that we could quickly throw machines together with is what drives all of that work. You will also see that the next sections are related to that vision: in Section 6.1, I use the knuckles motor driver to learn motor models, this enables that driver to be applied across many different sizes of motor. In Chapter 6, Chapter 7, and Chapter 8, I use models to make very specific controllers out of modular collections of drivers, i.e. showing that generalized hardware can be used to make very high performance systems, given a glut of computing power.
4.1 Other Modular Circuit Ecosystems
4.1.1 GPIO-Based Interfaces and Ecosystems
Qwiic / Stemma (“just a pinout”)
(and other GPIO-based standards, i.e. Hats, FPGA modules ?)
4.1.2 Bus-Based Ecosystems
Duet Control (CAN limited ?)
FabNet
4.1.3 Industrial Modular Ecosystems
Industrial Control and Heterogeneity of Networks + Proprietariness (where it is important to note that we are not complaining about this, Siemens’ gotta get paid, but noting that it is not as productive as open systems)
4.2 Knuckles Backpacks: a Module to PHY Layer
I have spent a lot of time designing circuits for modular machine systems. One of my ongoing frustrations was that the circuit designs were often tied to systems design. I would develop a networking layer, build a series of circuits for that layer (including the correct connector and interface hardware), and then I would subsequently improve or modify the networking layer, rendering that set of circuits defunct. I show some generations in Figure 4.2. This was seriously unproductive, but is representative of something that is true more broadly in networked hardware: link layers are heterogeneous.
That is to say, in different systems contexts, we want to use different types of networking. In a high performance machine controller, we probably reach for EtherCAT, ProfiNET (etc) - these are expensive and complex to integrate. For small systems with just a few devices, a simple USB connection to each module is sufficient and productive, since everyone has USB hardware already “lying around” (Read et al. 2023). In the middle ground we can use simple wired links like CAN or ad-hoc UART based busses, and for remote systems we want to implement wireless links like BLE, WiFi or (for long ranges) protocols like LoRa. Ideally, we would mix and match these systems - using some wireless devices, some wired, etc.
Circuit History
Modular-Things Era Backpack Prototype
To counter this issue, I began developing what I call backpacks. These are PHY level modules, i.e. they interface from our devices’ microcontroller to various links. Early backpacks used a simple eight pin header to interface between devices and link layers, some of which I show in Figure 4.3. This enabled me to simultaneously develop link layers and modules, without coupling the electrical hardware.
Backpacks are basically just a GPIO interface like those discussed above Section 4.1.1. However in this case, rather than some new hardware capability, on the other side of the GPIO set is a piece of networking hardware.
In many cases, the host microcontroller contains the hardware required to interface directly into the physical layer - i.e. the link layer logic is implemented in the host microcontroller. For example just about every microcontroller on the market includes one UART peripheral, and probably one SPI, and often a USB block. In these cases the backpack interface lives between OSI layer 2 (Data Link) and 1 (Physical, aka PHY). For example the backpack at the left of Figure 4.5 promotes UART TTL (which comes out of the microcontroller) to RS485 - a larger, differential voltage level that improves noise immunity. The microcontroller implements the logic that promotes that UART peripheral (which simply sends and receives bytes) into a proper Link Layer (encapsulating packets and catching errors). For some more discussion on how these layers are organized, see Section 2.4.
It is common for more complex link layers like EtherCAT and BLE to be integrated via standalone link layer controllers. This is because link layer operation is a time critical task, and microcontrollers that are running application code are not guaranteed to be available to handle packet frames in time. In these cases, it is common for the link layer controller to be interfaced to the host microcontroller using another protocol that is effectively hidden in the OSI layers model (which, as noted, is a lossy abstraction). For example EtherCAT and Ethernet controllers are normally connected via SPI, USB controllers via UART, etc. These can be accomodated in the backpack ecosystem, integrating the link controller on the backpack and mounting those SPI / UART connections via the backpack pinout.
I want to note that this sneaky insertion of (what is effectively) an additional network link in the OSI model is a common design pattern in embedded device development. There is even a set of standardized link-controller-to-phy interface for Ethernet: the MII/RMII (Media Independent Interface, or the Reduced version) enables ethernet to be broadcast across various media: these are, again, effectively GPIO specificiations. In optical networking, we find things like Small Form-factor Pluggable “network interface modules” (SFPs) that allow individual ports to be reconfigured to use different types of trancievers. These are often even hot-pluggable.
RMII, SFPs
Fritzing-Style Backpack Pinout
| Backpack | GPIO Interface | Network Interface | Image |
|---|---|---|---|
| USB “Dually” | USB + GPIO0, GPIO1 (img here, too) | USB-C (data) and USB-C (power delivery) | |
| UART/RS485 Duplex | ? recall | 2x5 Pin IDC (image ?) | |
| SPITherCAT Sensor | SPI, GND, 5V | 2x7 0.05” IDC | |
| SPITherCAT Power | SPI, GND, VCC | 2x7 0.05” IDC + XT30 (+5v reg) | |
| CANBus Sensor | TX, RX, GND, 5V | 1x4 GST-GH | |
| CANBus Power | TX, RX, VCC, GND | 1x2 GST-GH + XT30 (+5v reg) | |
| Bluetooth/WiFi | SPI, GND, 5V | ESP32 + Antenna, Battery, Charger | |
| Ethernet | SPI, GND, 5V | MagJack + WIZNet Controller |
One way that I like to explain this idea to people is that it enables us to fill in a full matrix of module functions (devices) and network interfaces (backpacks). In a classic networked device paradigm, everytime we want some new device with some network interface, we need to make a new circuit. In this case, we can make network interfaces and devices separately (agreeing on the backpack layout), and fill out entire new rows and columns of that design space.
DIAGRAM: Device, Backpack Matrix
Obviously the sticking point is that we would all have to agree on the backpack layout. While this may seem unlikely, I would contend that it is a design pattern worth looking at. GPIO based interfaces have already been productive in open hardware, and even have two apparent hardware-design rivals (Adafruit and Sparkfun) sharing one design pattern in Qwiic / Stemma (they are the same thing). The shared value in such design patterns is the tricky engineering on either side of the interface doesn’t have to be duplicated relentlessly.
4.3 Knuckles Hubs
OSAP and Pipes are agnostic about device network architectures, i.e. there is no distinction made between “routing” devices and “endpoints.” This means that any knuckles device can implement multiple backpack connectors, enabling it to connect to more than one device. I developed one hub device, pictured below, that uses a high performance embedded device primarily for message passing.
DIAGRAM: Hub PMIC (a DAG!)
This device also provides some power management functions: we can shut off downstream ports’ logic (5v) and device power (0-48v). This provides a convenience for configuring systems-level safety: the hub can turn system components off when i.e. watchdog conditions are not met in the case of watchdog hangups or other failures.
4.4 Knuckles Devices
Description of the set developed… spot notes in the table, some expansion on each in a subsection ?
| Device | Microcontroller | Drivers / Chips | Use Cases | Image |
|---|---|---|---|---|
| H-Bridge | ATSAMD21 | DRV8251A (pmic) | Bi-Directional Current or Voltage Control | |
| FOC Stepper | ATSAMD51 | AS5047 (encoder), DRV8251A (pmic) | See Section 6.1.1 | |
| Loadcell Amplifier | ATSAMD21 | CS5530 (loadcell amplifier) | Measuring forces | |
| Accelerometer | ATSAMD21 | BNO085 (imu) | Measuring motion and orientation, see Section 6.3 | |
| The Deadbugger | ATSAMD21 | none | Adhoc | |
| DAQ | RP2354A | ADCs, DACs | Digital Aquisition and Output | |
| … ? |
4.4.1 Device Re-Use with the H-Bridge
The H-Bridge is a particularely useful circuit across tasks; I want to use it to help us imagine how we can use the same electronic modules for potentially many tasks. Electrical Engineering oriented readers will already be very familiar with these devices: they connect electrical loads to voltage and ground through either a forwards or backwards path using four switches arranged in an “H” looking configuration, hence the name. I have sketched the basic architecture below in Figure 4.10. They are most often used to drive DC motors, but of course any generic electrical load is valid: heaters, solenoids, etc. We can also use each leg independently to drive separate uni-directional loads (each being used as a “low side switch”).
DIAGRAM: H-Bridge Switches


PHOTO: Heater/PCF in-situ
In Figure 4.11 above I show the knuckles h-bridge setup in three contexts: to drive a solenoid, a servo, and the Rheo Printer’s heating element and part cooling fan. Each interfaces into its environment differently (Figure 4.12). The challenge from a systems assembly perspective is how to configure each in software for a specific purpose, even though each device does not “know” by default which context it is in.
WIRING: Solenoid hardware
CODE: Solenoid iface
WIRING: Servo hardware
CODE: Servo iface
WIRING: Heater/PCF hardware
CODE: Heater/PCF iface
The simple solution at the time of writing is to modify the firmware for each new context, modifying it “in software.” This is at least simpler than authoring an entire new firmware, as the networking code and hardware layers are the same: we essentially just reconfigure the device’s API. This serves well enough and has been a productive tool during my time developing machine controllers, but in the future I would like to expand Pipes to enable on-the-fly reconfiguration of embedded codes using dataflow configurations as I discuss in Section 3.4 and as I explored in my masters’ thesis (Read 2020).
4.5 About Power Routing and Delivery
In practice, routing power throughout a system can be as cumbersome as routing networks. For prototypes, it is valuable to have one-plug-for-both, see i.e. XT30+CAN devices that have emerged. In other systems, these concerns are often separated. It is a difficulty… especially because some devices are low power, others are extremely hot and dangerous. Providing a power management service within the knuckles ecosystem is a goal, but difficult to incorporate due to the breadth. The hub has enough PMIC to reset remote devices and shutdown power, but there is some debate as to whether (and how) these concerns could be separated. Messy / unresolved… see Figure 4.9.
4.6 About Hackable Systems
building affordances into modular systems such that these kinds of additions are viable is an important step: they are by nature incomplete,
modularity breaks, we want to include things at the edges - a note about knuckles but also about the whole situation in general, noting benkler.
the need for the backpack breakout on both sides…
i.e. image of the hotend with the microbolo, and being able to stick the RP2350 inline…
MicroBolometer + RP2350
Accelerometer + RP2350 + Backpack
4.7 Other Semi-Standard Knuckles Interfaces
a proposal to standardize the programming / debug port,
a proposal to standardize some GPIOs / plugs: limit switches and other probes, thermistors, …