Mark Hofmeister
It's not entirely clear where the line between art and engineering lies. I believe that true engineering forces an engineer to burn his or her artistic side into the engineered work.
​
A Pittsburgh-native artist, Ross McBride, contacted my local makerspace, HackPGH, with a call for electronics help. Ross has designed a multitude of beautiful watches and built a robust product brand, named Normal Timepieces, mainly marketed to those interested in Japanese minimalism and subtle personal expression.
​
Ross is moving towards a new generation of eclectic abstract kinetic sculptures that serve as timepieces. I'm thrilled to have designed the electronics for one of these timepieces and hope to continue to work with Ross. Though legally I am the "engineer" and he is the "Artist," there's a dance between art and engineering in both of our work towards this project.
Final Product Coming Soon!

System Requirements
I began work on this project with the mechanical enclosure & user interface almost entirely designed. I had to fit my tech package within pre-defined mechanical, electrical, and UI functionality constraints. My challenges were exacerbated by the goal to sell this product to international customers.
Specifically,
-
Tangible, Graphical, and Audial User Interface: The user must set display brightness, change the time, configure an alarm, and snooze the alarm in a preconfigured manner. The alarm sound must be effective but pleasant.
-
Electronics Package: The PCBs must have a specific shape with exact mounting hole locations
-
International Power Constraints: The device must be able to be plugged into wall power independent of international location. This means that it must work with 120VAC and 240VAC wall power, as well as with different outlet configurations.
-
Uninterruptible Power Supply: If wall power is to fail, the clock timer must be able to remain functional, requiring the use of a backup battery.
-
Shipping: The device must be able to be shipped to most countries
-
Economical: The device must be as inexpensive as is realistic without sacrificing quality.
Human-Centered Design
Ross came to me with a mechanical housing complete with a tangible user interface, which included a main clock LED face, buttons to control the time, alarms, and display brightness, and supplemental indicator LEDs. Of course, before sinking the hours and money into a PCB design based on this interface, I decided to sub-contract a peer of mine Samsher Sidhu to do some UI testing with a "quick-n-dirty" prototype to simulate the contours of the real thing.


We're employing a technique called "Velcro prototyping." You can see that the "buttons" are entirely reconfigurable by the user. Therefore, test users can show us the interface that they want to use.
​
The current user interface was generally intuitive, and the UI layout remained largely the same, save for a rotation in the line of buttons on the back of the clock, which will be seen in later versions of the device.
System design
With complete electronics design autonomy, I was able to fully specify the hardware and firmware architecture.
This is a high-end, artisan-quality clock, so the customized functionality must be precise. Therefore, I decided to use a low-end STM32 MCU. These have integrated RTCs and a HAL that is low-level enough to allow me enough manipulation, yet abstract enough to have a built-in timer/backup battery/serial communications driver. This pre-defined functionality saves time, and saving time saves my client money.
​
I also used a dedicated Analog Devices MAX6958 I2C-to-Quad 7-segment display driver to simplify the display logic. This would end up being a mistake, as we'll see later on.

prototyping

Luckily, this is a very prototyping-friendly system. I used an STM32 Nucelo dev board and a mess of wires to prototype the 7-segment display and button interrupt testing.
​
To simplify wiring, I only used 1 LED for each segment of each digit. This was a mistake - though writing to the display was easy, this simplification would come back to bite me later on in development and take much more time to redesign the system.

Mistakes
As mentioned above, the largest mistake that I made was using a dedicated 7-segment display driver, which did not meet the voltage/current requirements of my system.
​
The LED display requires a maximum of 3 LEDs per segment, as opposed to my breadboard display, which used 1 LED per segment. I found that there was realistically no way to wire the LEDs to remain within the maximum current of ~30 mA and maximum voltage of ~5.5V per pin of the LED driver.



The MAX6958 uses a multiplexing scheme to cycle between the 4 displays in a PWM-like fashion. The waveform of just 1 pin is shown on the left. The functionality requires that 8 pins supply the positive voltage to 8 segments of a single digit while another pin pulls low to serve as a drain for the entire segment.
​
Unfortunately, this means that I had no way of using this driver for 3 LEDs per segment. Wiring the LEDs in parallel would keep the voltage in required to power the LEDs within the output range of the IC, but would far exceed the sink pin's current limit. Wiring the LEDs in series would allow for the sink current to drop back to an acceptable range, but the driver's output voltages cannot go high enough to overcome the forward voltage drop of 3 LEDs.
​
The waveform of the driver shows that the output channels idle at ~1.9V, prohibiting the use of MOSFETs to drive the LEDs from a higher voltage source. Furthermore, this IC is $11. That's absurd. I decided to switch to 4 shift registers wired in series - which are $0.50 each.
I also failed to select the correct microcontroller. I wasn't sure how I was going to provide backup battery functionality to this alarm clock in the case of a power outage, but I imagined it to be some external circuitry to supervise and charge a LiPo battery.
​
Ross and I collectively decided that, to balance shipping/safety regulations and functionality, we would use a coin cell battery as a backup battery for the clock. Due to the low capacity of coin cells, all LEDs would darken, but the time and saved alarms should be maintained.
​
I was already using an STM32G0 platform - the 32-pin STM32G031K8T6, to be exact. I made the switch to the 48-pin cousin of this MCU, the STM32G031C6T6, which has a pin dedicated to a coin cell battery input. In the event of a drop in VCC, the MCU will pull power from a backup battery connected to this pin to power the RTC and backup registers until power is restored. Not only does this save me development time, but it saves us from having to worry about an external battery circuit and any involved latencies.



Updated Circuit Design
After shifting to shift registers, the circuit design was updated as such:

LED PCB - MK. I
The LED PCB layout is tight-tolerance (for LED and mounting hole placement) but straightforward. I'm pushing quite a bit of total current around this board, so big ground and power planes are a help for routing and for thermal dissipation. This board is mostly DC, so I'm not worried about any RF coupling. Since this was a test run, I was liberal with test points and big, fat connectors that made debugging easier. I also selected component values to have as few unique component values as possible, reducing manual labor time/cost of the pick-and-place machine assembly.


Front
Back

I used a hierachircal Altium design with sub-schematic sheets for each digit. This was the first design within which I did so, but it cleaned up my schematic very nicely and made it easy to duplicate designs across multiple sheets.
The hierarchical design can be configured to create component rooms, which is extremely useful for adjusting entire digits. I also made use of color coding to visually section off each individual digit, as well as power rails and ground planes.

As usual, no PCB is right on the first try. Specifically,
-
I didn't make the initial power polygon pour wide enough. It wraps around a considerable distance and can see upwards of 2 Amps, and actually rose in temperature considerably when all LEDs were on, to the point where it was uncomfortable to keep a finger on the trace.
-
I was drawing too much switching current from the shift registers. I didn't have any in-series resistors on the gates of the MOSFETs, so switching 8 LEDs at once per shift register drew tons of initial current, causing some entire segments not to illuminate.
This occurred because the gate capacitances of 8 parallel MOSFET gates added to result in a considerable capacitance value when all 8 transistors switched, drawing a large current due to the I-V characteristics of capacitors:


-
I didn't have proper soldermask separation between vias and component pads. This is fine for hand-soldering, but when these boards are eventually assembled by a pick and place machine, I don't want plated via holes to wick away solder paste that would otherwise secure an SMT pad to a board.
-
I didn't make the auxiliary LEDs PWM-controlled. The PM indicator LED would remain at full brightness regardless of user-entered brightness preference. Unacceptable.

Brain pcb - MK. I
I had more autonomy with the layout of the Brain PCB. Both PCBs have mounting hole requirements that result in large boards, so I was not constrained for space at all. I also spun a small order of MK. I PCBs for testing, so I included many test points and simple plated through-holes to solder in and test functionality like batteries and capacitive touch.

Front

Back
This is a simpler, non-hierarchical design, but it's still important to keep a clean, color-coded, and partitioned schematic.

I also wanted to ensure that my component placement data were correct. This was my first time using assembly drawings to specify my assembly requirements, which is very important to me, especially since I'm never entirely confident that my component rotation values in the CPL file align with the assembly house's received component reels.


The board house got it right and everything looks great.


As usual, no PCB is right on the first try. Specifically,
-
I used the wrong SWD interface footprint. I'm using a POGO pin "plug of nails" connector to eliminate a header component, and I used a footprint for a different (though very similar) connector from the same company.
-
I placed the buzzer in a location that interfered with the mechanical enclosure. That's a failure to ensure correct mechanical integration on my end.
Firmware

I want my entire system to function using interrupts. A low-power, non-computationally-intensive application like this might be able to do loop checking, but there's something so clean and snappy about interrupt-driven code. It also seems to be good practice, especially when more complex systems are involved. Therefore, the main function does nothing more than initialize pins and functions.

Since this is an embedded application, I'm trying to dynamically allocate as little memory as possible during runtime. I also have a dislike for heavy use of conditionals, so I'm storing states in bools and using clever array indexing to smoothen the transition from one state to the next.





I'm also making many calls to STM32's RTC HAL for time management and display. Specifically, I only update the time on the display based on RTC interrupts. For the audio-visual output of an alarm triggering, I'm using a timer to avoid thread-blocking calls to the HAL_Delay function, which is bad practice and seems to mess with the internal RTC.

Flex PCB Mk. I
The user silences the alarm through a touch-activated button, which is orthogonal to both the Brain and LED PCB. Therefore, I created a custom flex PCB to serve as the electrode to which the capacitive touch sensor IC connects. I included 4 channels to allow me to average between them, as cap. sensors can be finicky.



The electrodes work perfectly until they bend. This is my first flex PCB, so I had no concept of bending angles or designing copper without high-risk break points. fractures between the exposed copper and traces can be seen under a microscope.
Rigid PCBs Mk. II
Mk. II of the LED PCB fixes all of the LED power delivery and switching issues from Mk. I. I updated by design to include series resistors on FET gates, added wide power planes, and PWMed the auxilliary LEDs. The LEDs worked reliably and the boards did not have heating problems anymore. It looks almost identical to Mk. I and is not shown here.
Mk. II of the Brain PCB fixes all of the mistakes from Mk. I. I fixed the SWD footprint and buzzer location, making this board mechanically suitable and allowing me to program it reliably. I also replaced the original capacitive touch sensor with a multi-channel IC, which has many more averaging and filtering options. I interfaced this to a screw terminal and was much more careful to avoid parasitic capacitance in my layout.
​
I also added TVS diodes to all connectors/headers that might experience an ESD event.
I included much more descriptive silkscreen layers, including some "quality of life" upgrades. For example, I included boxes in which Ross can assign boards serial numbers and write notes about their functionality (or lack thereof,) making my troubleshooting process much easier and saving us time/money.


These two functional PCBs gave me a platform on which to finalize the firmware. However, I made a grave mistake on both boards - I had improper transient voltage suppression on the input power lines.
​
We're using a commercial off-the-shelf 120V AC to 12V DC adapter like the one on the right. My system runs on the +12V DC. I found that the 12V punches through one of the PCB's 3.3V voltage regulators and fries the system, but only sometimes.
When the barrel jack is plugged into the Brain PCB before the AC plug is connected to wall power, my system boots up and works reliably every time.

However, when the barrel jack is plugged into the Brain PCB after the AC plug is connected to wall power, my system will sometimes blow up.
AC Plug
DC Barrel Jack
This stumped me, but a few application notes [1] and [2] describe exactly my problem: I had low-ESR MLC capacitors on the input to my voltage regulator. Linear Technologies' AN88 illustrates the situation nicely:

When the LC tank intrinsic to the wall adapter is charged up and the jack is plugged into the PCB (simulated by a SW1 closing,) the input capacitor charges towards the 12V seen across the wall adapter's output capacitor. However, when the input capacitor reaches 12V, the wall adapter's inductor (and additional cable inductance) want to keep pushing current into the input capacitor. This raises the input capacitor's voltage to a peak that is above 12V. It's an underdamped system.
My regulator has a maximum input voltage of 15V. Simulating my system with very low resistance in series with the input capacitor shows ringing to a peak above this 15V value depending on the input inductance.


Adding series resistance (even 1 ohm) dampens the system to an acceptable value. I add protections against spurious transients in Mk. III of both the LED PCB and the Brain PCB.
Testing, debugging, & Integration
Once I had the Mk. II boards, I integrated hardware with software and massaged the bugs out of the system. As for MCU functionality, I ended up using the following:
-
3 timers - In addition to the RTC, I use 3 hardware timers. One is used for short delays (~500ms) when blinking displays and beeping the alarm. Another is very slow and measures the 10 minutes between the first snooze and the second alarm beep. The third outputs PWM to the shift register enable pins to dim the display.
-
I2C - I communicate to the capacitive touch sensor on an I2C bus. I found that I had to change the averaging and detection integration factors of the sensor to avoid any spurious touch trigger events, so I do quite a bit of configuration over this bus.
-
RTC Backup Registers - When an external coin cell battery is connected to a VBAT pin, the RTC will continue to run when the main system power fails, saving the user from having to reset the clock time in the event of a power outage or moving the clock from one outlet to another. I save the user-set alarm time in some backup registers that also remain powered by VBAT, preserving both the current time and alarm time across power-outage events.
-
RTC Calibration - To calibrate the 32.768 kHz LSE crystal input as precisely as possible, I measured a 512 Hz output signal derived from the LSE crystal, measured ppm deviation from the ideal, and used this value to set the STM32 smooth calibration function. The RTC circuitry corrects timing error by removing one of every N clock periods from the LSE crystal, allowing the minimization of long-term drift.
-
10 GPIO Outputs
-
5 GPIO External Interrupt Inputs
Flex PCB Mk. II,
Rigid PCBs Mk. III
With the software completed, I created Mk. III of the rigid PCBs and Mk. II of the Flex PCBs to fix any hardware errors from previous revisions.
​
I changed the regulator circuitry on both the Brain and LED PCBs to avoid destruction by transient spikes. I replaced the low-ESR MLCCs on the input and output of the regulator with high-ESR (~2 ohm) electrolytic capacitors. I also included a power TVS diode to clamp any input above 14V, preventing spikes above the regulator's 15V input maximum.

I made both boards black because it's better. I added some silkscreen niceties to the LED PCB:


Due to the form factor of the enclosure, the barrel jack connector and coin cell battery connector exist on a surface that is not parallel or orthogonal to the boards, making connection from PCB to enclosure ports very difficult. Therefore, I decided to use Molex SL-series headers and cable assemblies to interface 12V and coin cell backup power to the Brain PCB.


I then created custom cable assemblies to interface the barrel jack to the on-board header. These connectors latch, so it's very unlikely that they'd become disconnected while being shipped internationally. The 10-pin connector from Brain to LED PCB will be hot-glued in place to prevent disconnection.

Mk. I of the flex PCBs were much too long, so I was able to greatly shorten them. I also used wider traces, tapered trace width transitions, and hatched polygons to make these boards as robust as possible. Adding a stiffener at the screw terminal end would almost double the cost of the boards in low volumes, so we plan to hot glue the connections in the screw terminals to provide a bend buffer.


I had all 3 PCBs manufactured and assembled by PCBWay and they look fantastic. I always have great success with them and I'm thrilled to be partnered with them.

This was my first PCB that used black solder mask. I didn't know that black solder mask has different clearance constraints than green solder mask, but PCBWay worked with me to adjust my design and ensure its manufacturability. They're also quick to provide quotes for both fabrication and assembly, and the results are always spectacular. Just take a look at these sexy boards:




My power section modifications fixed my transient voltage issues from the wall adapter. When the power sections on the Brain/LED PCBs use low-ESR MLCCs on the input of the linear regulator, my oscilloscope shows this transient response:

This transient response spikes to over 18 volts, well above the linear regulator's 15V maximum input voltage. This fries the boards.
However, in the Mk. III versions of the LED and Brain PCB, which use high-ESR electrolytic capacitors on the input of the linear regulator, the response is much more damped and doesn't rise above 12V.

Production Run
A few trivial changes were made to the designs (silkscreen font, etc.) and production runs of 25 units were ordered.






We had 100% yield on the Brain and Flex PCBs. The LED PCBs had 88% yield. There were a few hardware shorts, which I believe is due to a few tight tolerances I had between copper.