Sculpture Controller Schematic Capture + Prototyping, PBSI

Sculpture Controller Schematic Capture + Prototyping, PBSI

Tags
Altium
Processing
In 2020 I started a project to re-design our sculpture hardware system. Our old/legacy hardware suffered from being expensive, bulky, and prone to failure. I had a couple of goals with the redesign:
  1. Reduce the ratio of microcontrollers to actuators (microcontrollers were most expensive components in our electrical system)
  1. Make the boards more robust (the existing system had a grounding issue where hot-swapping cables damaged the microcontroller)
  1. Change the distribution voltage to 24V (higher voltage distribution meant we could deliver more power with a less impactful voltage drop, reducing the number of power supplies and distribution cables)
  1. Remain compatible with existing actuators, sensors, and the software topology
 
The mind map I sketched before diving into concept design. This helped me organize my thoughts and also served as a reminder later in the project for any aspects I wasn’t covering.
The mind map I sketched before diving into concept design. This helped me organize my thoughts and also served as a reminder later in the project for any aspects I wasn’t covering.
 
I considered a couple different approaches, including one that I ended up pursuing the following year with my ESP32 board. But at this point I was trying to support as many actuators as possible with each controller. Also, at this point we wanted to stick close to the centralized control system we were using.
 
To get as many actuators as possible for each control board, I planned to use a shift register chain, with power and data daisy chained downstream.
 
A single controller PCB (”NC”) that drives a chain of actuator output boards (”DM”) that each use a PWM driver with a shift register architecture. A single Raspberry Pi could control thousands of actuators with just 3 data lines. I went with a Pi since we were already using them in our legacy hardware system. All it would need was a driver shield (the “NC” PCB).
A single controller PCB (”NC”) that drives a chain of actuator output boards (”DM”) that each use a PWM driver with a shift register architecture. A single Raspberry Pi could control thousands of actuators with just 3 data lines. I went with a Pi since we were already using them in our legacy hardware system. All it would need was a driver shield (the “NC” PCB).

Schematic Capture and Component Selection

notion image
 

Output Driver

The heart of this design was the TLC5971, a 12-output 16-bit PWM LED driver. This IC has a shift register as its input data buffer, which would pass the data into a second register when latched. The internal control circuit would then PWM each of the outputs with the 12 x 16-bit values stored in the second register.
This is incredibly powerful. Compared to a normal shift register, where you have to control the pulse width ‘manually’ with the latch line, the TLC5971 takes care of the PWM’ing so the controller can manage much longer chains with high resolution.
 
Block diagram from the TLC5971’s datasheet, showing the shift register topology.
Block diagram from the TLC5971’s datasheet, showing the shift register topology.
 
One caveat with this chip: it is meant to drive LEDs with its constant current sink outputs, limited to 60mA per channel. We wanted to drive outputs that could pull up to 2A each, so we needed active-low transistors to switch the open drain outputs of the LED driver.

Regulator

For the regulator, I found Alpha & Omega’s line of tiny, cheap, and powerful buck regulators. The regulator modules in our legacy system were $15 each, while most of the AOZ chips are around $2. Many of the chips share the same footprint (a 4mm square QFN), and they come in a range of output capacities. At this point I sized the passives around the regulator based on its datasheet and these application notes, but my testing with it wouldn’t come until much later, while working on the successor to this concept design. I’ve leave most of the notes there instead of on this page.

Transistors

To select the mosfets, I used these helpful application notes from Vishay. Since the LED driver chip had open drain outputs, I needed the transistor to allow current to flow to the actuators when given an active-low control signal. This meant I needed a PMOS, which I had never used before, so to confirm my understanding of the application notes bought one and set up a test. Here it is with the gate resistor values I sized, working as intended:
 
Test to confirm the pmos and gate resistors I selected would work as intended.
Test to confirm the pmos and gate resistors I selected would work as intended.
The schematic for the test.
The schematic for the test.
Though this design never made it past the schematic stage, I was able to bring forward much of my work in selecting the regulator and mosfets to the new board I designed.

Differential Transceivers

These chips make it possible to send serial data at high speed over long distances. A chip at one end of a signal bus transmits a signal and its inverse from one end of the bus to a a receiver on the other end, which reverts the inverted signal and combines the two to eliminate any inductive noise they’ve picked up.
 
Diagram from a set of TI application notes showing the output waveform of a differential line driver. The signal on line B is the inverse of line A. Since both lines travel together through a pair of wires, they pick up the same inductive noise. Then, when the receiver inverts B to re-combine it with A, the noise on B is inverted and cancels out the same noise on A. Source: https://www.ti.com/lit/wp/slla545/slla545.pdf?ts=1669531326162
Diagram from a set of TI application notes showing the output waveform of a differential line driver. The signal on line B is the inverse of line A. Since both lines travel together through a pair of wires, they pick up the same inductive noise. Then, when the receiver inverts B to re-combine it with A, the noise on B is inverted and cancels out the same noise on A. Source: https://www.ti.com/lit/wp/slla545/slla545.pdf?ts=1669531326162
Graphic showing how a signal combined with its inverted counterpart will eliminate the noise. Source: https://www.physics-and-radio-electronics.com/physics/images/constructiveanddestructiveinterference.png
Graphic showing how a signal combined with its inverted counterpart will eliminate the noise. Source: https://www.physics-and-radio-electronics.com/physics/images/constructiveanddestructiveinterference.png
The way these chips are used in this design is a little confusing because of the direction the signals are travelling. In total, 4 data lines are being passed from board to board. Three of those lines are being driven by the controller at the head of the chain; the other one is driven by the ADC of one of the boards to pass a sensor reading back to the controller.
Looking at the diagrams below, you can see the 3 data lines from the controller coming through the input data port (DIN), passing through a receiver and to/though the components that need the data. The lines are then passed through a transceiver that sends the data through the output port (DOUT) to the next board in the chain.
The sensor data, inversely, is being generated by an ADC on one of the boards in the chain and passed back to the controller. So it passes from the ADC through a transceiver and up the chain through DIN. The subsequent boards upstream of the one sending the signal have to pass it along after they receive it through their own DOUT. I’ll explain how that logic works to avoid bus conflicts in the ADC section.
 
Block diagram of how the data lines are routed. SCK (serial clock), SDT (serial data from the controller), and LATCH (register clock) are passed from DIN—>Diff. Receiver—>Shift register + actuator driver—> Diff. Driver—>DOUT. SDR (serial data from the ADC) is passed EITHER through ADC—>Driver—>DIN, if the signal originates from this board; or DOUT—>Receiver—>Driver—>DIN, if the signal originated from further downstream and this board is just passing it back to the controller.
Block diagram of how the data lines are routed. SCK (serial clock), SDT (serial data from the controller), and LATCH (register clock) are passed from DIN—>Diff. Receiver—>Shift register + actuator driver—> Diff. Driver—>DOUT. SDR (serial data from the ADC) is passed EITHER through ADC—>Driver—>DIN, if the signal originates from this board; or DOUT—>Receiver—>Driver—>DIN, if the signal originated from further downstream and this board is just passing it back to the controller.
The signal paths of SCK, SDT, and LATCH on the schematic.
The signal paths of SCK, SDT, and LATCH on the schematic.
The signal path of SDR on the schematic.
The signal path of SDR on the schematic.

ADC

The ADC was tricky to integrate into this design. When you only have one line to send data back to the controller, only one device at a time can send a signal (otherwise you get a bus conflict, which would mess up the data and probably damage the conflicting chips). So, I needed a way to tell one specific ADC that I wanted to take a reading from it, and then make it the only device that would write to the sensor data line.
 
A sketch of what I needed to do; select one ADC at a time to drive the return data line.
A sketch of what I needed to do; select one ADC at a time to drive the return data line.
 
My solution was to use a shift register on each board as chip select. One of the shift register’s outputs would enable/disable the differential receiver, and the other 7 would enable/disable an ADC. This allows for 7 ADCs per board (since most shift registers are 8 bits), but I only put one on the board since that would be our typical use case.
Since there would be a transient state where the shift register enabled one chip and disabled the other, I needed an extra step to make sure the timing never caused a conflict. To do this I used a flip-flop, which can output either a logic high or low (depending on it’s input) timed in this case with a falling edge clock signal (LATCH). Because the flip-flop outputs data on a falling edge, and the shift register outputs data on a rising edge, I could connect them to the same signal line (LATCH) and make sure the receiver (controlled by the shift register) would release the sensor data line before the ADC (controlled by the flip-flop) would start driving it.
 
Sketch of how the ADC chip select protocol works to ensure that a receiver and ADC never have a bus conflict.
Sketch of how the ADC chip select protocol works to ensure that a receiver and ADC never have a bus conflict.
I’ve included my raw protocol notes for the shift register output and ADC input in a text file at the bottom of this page.

Controller

Lastly, the controller I planned to use was the Raspberry Pi Zero. The Pi would get a simple shield with a differential driver + receiver, and an output port to connect to the chain of output boards.
We already had Pis in our systems running Processing scripts, so if we could eventually eliminate the C++ microcontrollers it would greatly simplify our Testbed Control software (no more messaging through USB ports, no more writing code modules in both Processing and C++).
Of course I would need to do some testing to confirm whether the Pi was suitable for this role. My first test was to see how fast I could drive the SPI port (which I would be using as the data and clock lines for the shift register chain), and I found that it could produce a clean signal readable by an arduino without data loss up to 2.5 MHz.
 
This picture was from a slower test, but this is a view of the data I was sending from the Pi to an arduino.
This picture was from a slower test, but this is a view of the data I was sending from the Pi to an arduino.
Then, since I was already planning to have this new generation of electronics hardware be compatible with the legacy system, I wrote a module into our software to run the TLC59711 from the Pi. I created a class of object that the Pi would treat just like a microcontroller in the legacy system, so nothing in its core script had to be changed.
Here’s a test of the Pi controlling the TLC5971, also showcasing the TLC’s 16 bit PWM scale (we were used to 8bit PWM, which is very choppy on the low end) :
 
 
Bringing some of the functional blocks together, I had this test of the Pi sending data through a line driver, receiver, the TLC, and finally through a pmos to a high power LED:
 
notion image
 
I stopped working on this project at a point when our project schedule filled up and I was spread too thin to dedicate enough time to it. By the time things settled and I came back to it, the global supply shortages of certain key parts made me rethink my approach, which lead to the development of the ESP32 board that has been used since.

Appendix A: Protocol Notes

 

Appendix B: Altium

A brief note on my experience with Altium. This concept design was my first PCB design (mostly just schematic capture) since university (where I used Eagle), so the overall quality is pretty low. I have much more experience making PCBs now, though for my other designs I used KiCad primarily because it has the best free tool set. But I think with the best practices I’ve picked up I think my design skills would transfer back to Altium fairly easily (someone just needs to pay for my license…).