CINDERCLOCK
This is a demonstration of our work process, written as the design rationale for our first product. Every decision below is here with the reasoning that produced it. If you are deciding whether to hand us a hardware project, this document is the evidence.
Also as PDFs: the 27 page product dossier, which condenses this page and adds the pricing, manufacturing and sourcing plans, and a 6 page executive brief for a faster read.
What is this?
CinderClock, our debut product, is a multi-purpose standalone desktop clock. It is built to keep your phone away from the delicate matters of sleep and focus.
CinderClock launches on Crowd Supply. The launch list gets one message when the campaign date is set and one when it opens. Backers on the list get the launch price.
Nothing else is sent to this list, and the address is not used for anything else.
Why?
After many failures of the iPhone alarm, we asked why we use our phones to wake us up in the first place. The failures had a cause. iOS carries a setting called Attention Aware Features, which quiets alerts when the phone decides you are looking at the screen. Apple separately confirmed a fault in April 2024 that stopped some alarms from sounding at all, and reports continued through 2025.
Back in the day we used phones for the convenience. As our devices got more and more loaded with unnecessary things, the convenience was replaced by burdens:
- Information overload, with notifications accumulated over the night.
- Fiddling with touch controls when you are half asleep.
- Blue light from millions of flickering pixels hitting your eyes after eight hours of being shut.
In search of a dedicated bedside alarm clock, we found that nothing on the market was worth its money. The cheap end is crowded with trash. The expensive end sells clocks that want an app, an account, or a subscription: the Philips SmartSleep lists at $199.99 and the Loftie at $169.99, with Hatch charging $49.99 a year for its content library and Loftie $59.99 for its own. The full spectrum, from landfill ambassadors to gimmick stands, did not have a single member worth the cost with the features we wanted.
So for our first product launch we set out to make our own alarm clock.
Our goal was a standalone device that kept time, played audio, and was programmable. Programmable here means it stores user-created alarm programs and follows them automatically. Most alarm clocks, your phone app included, have very simple programming options. You can set one alarm for a specific time, have it repeat every day, and maybe follow weekdays and weekends. We feel that this is too limiting.
What if you want it to ring only on certain days of the week? Ring 2 days on and 2 days off regardless of the week? Follow your local sunrise and sunset times so you wake up with the sun? Ring for 3 weeks in a row with one week off, if you work shifts?
These are not gimmicks either. Sun following was the feature we wanted for ourselves most. Having an app do that on the phone defeats the first part of the brief. The rest are useful to the many people who never agreed to a 9 to 5.
With this in mind we got to work.
Where it started. Tap any image to enlarge.
Intentions, Constraints, Systems
Whenever we do anything, we always start with core principles. At Endothermal Systems the core principles are Intentions, Constraints, and Systems. Good intentions set you on the right path, good constraints focus your attention, and good systems get you to the destination.
The Intentions with this project were:
- to take control of your sleep back from your phone
- to make the hardware conform to your sleep needs, not the other way around
The Constraints were:
- the device must be standalone, with no reliance on external entities
- mechanical interface
- modular design
A System is a network of methods you can run again and again. The core method we use is of the ideal outcome. Visualize an ideal outcome of whatever you hope to achieve, adhering to the rules of physics. If it satisfies you in that ideal form, then workout the details of how to get there. If, however, the solution you propose cannot satisfy you even in its ideal form, then scrap that idea altogether.
The method of ideal outcome requires you to consider every possible solution you can think of. In theory that is. List out all possible solutions to this problem, evaluate each one according to a defined scale, visualize the ideal outcome of each one, reevaluate, keep the ones that pass, scrap the rest.
If you cannot do this due to limited information, go one level below, break the problem into smaller problems. Try to define ideal solutions to those and find practical candidates for the ideal solutions. Do this until you reach the smallest atomic problem and go back up to the top level problems.
There are more nuanced ways to our System which will become apparent as you read on.

Part one: Requirements
Once the top level constraints are set it is time to define the lower level requirements.
Standalone. The device must be standalone, with no reliance on external entities. Which means:
- connection to the internet must not be needed for it to work
- it must operate on battery power for a prolonged time, 2 weeks or more
- it must be portable, to easily take it to different rooms
Mechanical interface.
- every input must be mechanical, with clear tactile feedback
- each input device must be the best fit for its purpose
Modular design.
- every significant component of the device must be a repairable and replaceable module. This includes the screen, the electronics modules, the enclosure, and the input devices.
- software must accommodate the modular design. There must be appropriate handling in place for when one of the components is missing.
Part two: Components
At the basic level an alarm clock has three components: a display, a computer, and a speaker.
The display
A display can be analog or digital. An analog watch face is of little use on a programmable device, since there is no useful way to show program options on a pair of hands. So the device must have a digital interface, and the question becomes which kind.
The screen is the part you interact with most, so it was chosen first, and the other constraints all touch it. It has to be bright enough to read across a room and dim enough to not wake you up. It has to be low power, because the device runs on a battery. It has to be low fidelity to save power and avoid too much light hitting your eyes in the morning. And it has to be able to carry a menu to display all program options.
Seven technologies could do some of that.
| Option | Can show menus | Power | Cost | The failing |
|---|---|---|---|---|
| 7-segment, 4 digit | No | Low | Low | Commercial parts stop near 14 mm digits and show nothing but digits |
| Chained 7-segment modules | Barely | Medium | Medium | Many modules wired by hand, and the face degrades as the count grows |
| Character LCD (1602 / 2402) | Limited | Backlight always on | Low | Low contrast despite the backlight |
| VFD | Yes | High | Medium | Thermally inefficient, closer to an incandescent lamp, so it drains a battery |
| 7-segment plus small OLED | Yes | Low | Medium | Two screens split the face and the gains cancel |
| Monochrome OLED | Yes | Low | Low | Pixel burn-in under uneven use |
| MicroLED | Yes | Low | Prohibitive | Fabrication complexity prices it for AR headsets and luxury televisions |
If you could combine independent pixel control, LCD wear resistance, VFD brightness, and low power at low cost, you would have made the best screen ever made. In the real world every option fails somewhere, so the job is to choose the failure you can manage.
Burn-in is the only failure in that table that software can address, which selects the monochrome OLED. The management ships as four screen saver methods on a settings-selected idle interval, which move and invert what is displayed so pixel wear evens out.
Finding the part took longer than choosing the technology. We wanted something like the panel on a Bambu Lab P1S printer, large enough to read and detailed enough for menus, and it is not a thing you can search for directly, because you do not know the terms it is sold under in many cases. A 3.12 inch 256 by 64 SSD1322 panel eventually surfaced through a chain of related listings. The 64 pixels of height carry either a large time font or a full menu. The 256 of width carry the time, the date, and the alarm panel at once.
The computer
Computer here does not refer to a PC or a specific chip. It is the general term for a processor that performs computations. The computing part of the clock is two jobs: timekeeping and programmability.
Timekeeping on a digital device wants a crystal oscillator based chip called a real time clock (RTC). The most commonly available one is the DS3231 module. It is reliable, temperature compensated, keeps time offline from its own coin cell, and it works over I2C (a simple communication protocol).
It is designed around a rechargeable coin cell and trickle charges whatever you fit. Put an ordinary non-rechargeable cell in it and the cell will be damaged. The fix is to remove the small resistor connecting the power rail to the battery, which disables the charging circuit, after which a standard cell is fine to use. It is a two minute modification.
For programmability on a relatively simple device you can go with a microprocessor or a microcontroller. Both are computers. Microprocessors are faster but need peripherals around them for memory and input and output. Microcontrollers are complete computing units but less powerful. For low power embedded systems, microcontrollers are the better fit.
One of the most available and best documented microcontrollers right now is the ESP32. Its ease of use and low cost make it a good board for this application, especially given the modularity constraint. It is not the first choice for commercial products, where companies drive cost down to pennies, but the versatility of an ESP32 at a few dollars more than a penny chip is justified here, even more so when we use most of its capabilities.
We chose the ESP32-S3, the more capable model of the S variants. In line with modularity we use a dev board version of the microcontroller, seated on pin headers on our custom PCB rather than soldered to it, and the same treatment goes to every other module on the board.
The speaker
Choosing the right speaker matters for an alarm clock. The sound must be clear and loud, and the part must be easy to source.
The ESP32-S3 has no digital to analog converter and no audio amplifier of any kind. It has an I2S interface, which is a digital audio bus, so an external amplifier is the only path. The common part for the job is the MAX98357A, an I2S class D amplifier that is cheap, widely available, and well documented, and which comes on open hardware breakout boards from several vendors even though the chip itself is a commercial part.
It drives 4 ohm and 8 ohm speakers, and we chose 4 ohms for volume. From a 5 volt supply it delivers 3.2 watts into 4 ohms against 1.4 watts into 8 ohms. The lower impedance draws more current, and that extra current is where the loudness comes from. On a device that runs from a battery this is a deliberate trade: the amplifier only draws that current while an alarm is actually ringing, which is a rounding error, in theory, against the standby current that sets the runtime.
Among the 4 ohm speakers on the market we found a particular 30 by 30 mm unit to be the best. It has clear sound, a small form factor, and an acceptable retail price of about 3 dollars. It has no official name. Many AliExpress vendors carry it in their stores simply as a "30x30 mm speaker".
With these components a proof of concept was put together on a breadboard.


The rest of the board
Screen, computer, and speaker make the skeleton. A consumer product needs more.
An SD card module, the Adafruit 4682, holds a card with push to eject access. This lets us store a large number of audio files and lets users upload their own. A bare SMD socket would have worked, but it would have needed additional small capacitors and an SMD assembly step, which we wanted to avoid. A board like this should be fully through hole for maximum hobby repairability.
Environmental sensing was an easy addition, since the only thing on the I2C bus so far was the clock. A BME280 gives temperature, humidity, and pressure, and the standby face had room on the right for all three. This is what we mean by using the whole chip. Modules like that raise the value of the device at marginal monetary cost and near zero development cost.

A light sensor lets the device adapt its brightness to the room. A BH1750 module handles that, over I2C.
The board also breaks out its live buses on labelled expansion headers: I2C twice, SPI, UART, spare GPIO, and the I2S audio bus. The audio header is the interesting one, because it means the amplifier can be swapped for a different one with no board revision at all. A modularity claim is worth what its connectors are worth.
A note on sourcing. We prefer the most common, best documented part available, because sourcing availability and reliable documentation are what make a product repairable and long lived. Twice in this project the common part did not exist. The display had to be hunted through unrelated listings, and later the charger did too. When no common part satisfies the constraint, the constraint wins and we go hunting.


Part three: Interface
Setting a time takes two motions. You move between fields, and you change the value under the cursor. That single observation removed direct digit entry before any comparison started.
| Control | Two motions | Fast scrolling | Pins | The failing |
|---|---|---|---|---|
| Four buttons | Yes | By auto-repeat | Four | Fixed scroll rate |
| Clickable dial | Yes | Yes | Three | One axis, so field movement and value changes share a motion |
| D-pad | Yes | By auto-repeat | Four or five | Same behaviour as four buttons at the same or higher pin count |
| Analog joystick | Yes | By holding a direction | Three | Analog axes cannot wake the processor from sleep |
To interact with the device we chose only mechanical inputs: one analog joystick, four tactile buttons, and one large arcade button. The joystick gives motion in four directions with variable intensity, closer to the centre or further from it, plus a tactile switch in its stem, for five inputs from one component on three pins.
The joystick moves between fields horizontally and changes field values vertically. Intensity is tied to speed, so holding it at the extreme of its travel increases a value faster than holding it part way in the same direction. The hand sets the rate, the thing the four button option could not offer.
The four buttons give dedicated controls for specific, reusable actions:
A, Action. Dismiss alarms, start and stop timers, and the action button in games.
B, Back. The universal back button, which reverts changes on any screen.
C, Confirm. Confirms a selection and acts as the primary save button, and doubles as a secondary multipurpose button for showing and hiding extra items, such as centiseconds on the stopwatch.
D, Menu. Primary multi-purpose button. Opens the main menu from standby and returns to it from sub-screens. While an alarm is ringing it is the snooze button. On the Display Test screen it toggles inversion, so a panel can be calibrated against both polarities.
Two dedicated buttons and two multipurpose buttons offer great versatility without imposing limits.
The 100 mm arcade button is tied to the Action button and performs the same functions. The two serve different situations. The small Action button is for operations inside the clock interface. The arcade button is for dismissing an alarm early in the morning without aiming at anything, and for flapping the bird in Fly Bird.
The result is a complete control interface that anyone who has stood at an arcade cabinet already knows how to use.


The four keys sit on a separate riser board rather than the main PCB, so the control layout can be changed without touching the main board. Two risers exist: tactile switches, and hot swap mechanical key sockets.
Part four: Audio
Audio took the longest of anything in the project. It is where the difference between assembling parts and engineering a system shows.
The first attempt was the obvious one. Add the standard ESP32-audioI2S library, which drives the MAX98357A over I2S, and move on. It added 500 kb of library to decode MP3 files we did not need, and it carried its own real time operating system inside it, which fought the one we were already running.
Which raises the question of why a clock needs an operating system at all.
A microcontroller runs one loop. Ours draws the screen, reads the joystick, checks the alarm list, and polls the sensors. A full redraw of a 256 by 64 OLED over SPI takes tens of milliseconds. Audio does not tolerate that. The amplifier consumes 44100 samples every second at a fixed rate, and if nothing refills its buffer during a redraw it runs dry and you hear it. So audio cannot share a loop with the interface. It has to be a separate job the chip switches to on its own schedule, which is what FreeRTOS is for, and the ESP32-S3 has two cores, so it does not even have to take turns. Audio gets one core, the interface gets the other. Once you own the scheduler, a library that also wants to own it is a problem.
Switching to the older I2S driver clashed with the new ADC drivers, so the ADC went legacy too, which produced its own downstream errors and semaphore conflicts that crashed the system on boot.
An external MP3 player module, the DFPlayer, was the next attempt. It works, and it has its own decoder chip. But it has a long mounting time, so every sound means connecting to it and waiting while it searches the card. That is unusable for interface clicks. You also cannot browse the card from the device, so you have to already know the exact path of the file you want. Scrapped.
The third approach was to go back to basics. A WAV file is a 44 byte header followed by samples. The header states the sample rate, the bit depth, and the channel count. There is nothing to decode. Once the header is read you are copying bytes from a card to a peripheral, and the peripheral sets the pace.
So the audio is one FreeRTOS task pinned to its own core, doing nothing else. It waits on a queue one item deep, written so a new command overwrites a waiting one instead of stacking behind it. Three commands reach it: play a file, play a tone, stop. On a play command it opens the file, reads the header, and loops: take the SD mutex, read 8 kb, release the mutex, apply volume as an integer multiply, duplicate each mono sample into left and right, hand the block to the I2S driver.
That last call blocks until the DMA has room for it, and that is the entire timing mechanism. The hardware throttles the task at exactly the audio rate, so the task never has to guess how fast to run. The mutex is held only around the card read and never across the write, because the write can block for 93 ms and the file portal needs the card too.
The I2S channel opens once at boot and closes only for light sleep. The driver is configured to push silence into empty buffers and not leave them stale. Closing the channel between sounds makes the amplifier drop its clock, and it takes 50 to 200 ms to lock again, which is longer than a button click, so the click would never be heard at all.
Mono files play through a stereo channel on purpose, because the S3's I2S driver has a bug in mono slot mode where it emits alternating zero samples.
Three things about that path were learned by getting them wrong first, and they are in the corrections section below.
Part five: Programs
A programmable clock has one characteristic failure, which is that you cannot tell what you actually set. Everything in this section is shaped by avoiding it.
The recurrence model rests on one setting called Cycle, which takes the value Weeks or Days and changes the meaning of every row underneath it. In Cycle: Weeks an alarm fires on the weekdays you tick, every Nth week, which expresses "weekdays at 7:00" and "every other Tuesday" with the same two controls. In Cycle: Days it fires every N days counted from a start date and ignores the day of the week entirely, which expresses "every 3 days". When Cycle is set to Days, the day of week row disappears, because it no longer means anything.
Two decisions guard the failure mode directly. The alarm list writes patterns back in plain language, as Daily, Weekdays, Every 3 days, 3d on/2d off, so the list is readable without opening anything. And each editor shows a live next-ring line computed by the same code the scheduler uses to decide whether to fire, so the preview and the behaviour cannot disagree.
What follows is everything the device does.
Alarms. Five types: simple, repeating, on and off duty cycle, sunrise, and sunset. A repeating alarm takes any pattern the calendar allows: every day, every 2 days, every 14 days, weekdays, weekends, chosen days. An on/off alarm adds a duty cycle, so "3 days on, 2 days off" is a setting and not a workaround. Each alarm carries its own sound file and its own volume, under a master volume that caps all of them. A pre-alarm can give a gentler cue some minutes ahead with its own sound. An alarm rings for 5 minutes and then logs itself as missed. History keeps the last ten events with their outcome, which answers the question that follows oversleeping.
Alarms are never silent. If the card is missing or the file is unreadable, a built-in siren plays, and muting the interface sounds does not mute alarms. There is no mute path at all.


Getting it to stop. Dismissal is the 100 mm button, sized to be hit without aiming. Snooze is deliberately harder and offers three modes: a single press, three presses at least half a second apart, or a sequence of randomly drawn joystick directions that each have to be fully released before the next one counts. The random sequence asks for 10 to 30 moves and redraws the direction each time, so it cannot be done in your sleep. Snooze is capped at three per alarm. An alarm can also be gated behind a game, and a third loss dismisses it, because being trapped by a game at 6 a.m. is a worse outcome than getting up late.




Sun follow. Sunrise and sunset are computed on the device from latitude and longitude entered in degrees, minutes and seconds, with the UTC offset derived from longitude and editable. A world map with a crosshair sets a position by eye, so coordinates do not have to be known. Times recompute daily, so a sunrise alarm drifts with the season. Nothing in this touches a network.

Calendar. A month grid with short ticks beside each day number, one tick per alarm, stacked up to four, with monthly totals. The ticks are drawn from the scheduler code rather than recalculated, so the calendar doubles as a check on a recurrence setting. An alarm set to every 3 days should march across the month in threes, and if it does not, the setting is wrong.

Timers and stopwatch. Saved, editable timers with presets, running in the background while you go do something else in the menus. A Pomodoro cycle takes work and rest periods from 1 to 999 minutes and announces each phase change with a countdown and different jingles for work and rest. A stopwatch with four laps and centiseconds, which can be hidden, because a fast changing display is a distraction on a desk. One joystick move from standby opens a quick menu for alarm, timer, and stopwatch.




Ambient. A sound loop with a slow full screen animation, for sleep or focus: Fire, Rain, Blobs, Life, and Waves, at about 10 frames per second, since anything faster reads as busy. Reactive mode drives the animation from the audio, so a sudden sound seeds a spark in the fire or a glider in Life. Pendulum mode ticks on alternate seconds, locked to the second the clock is displaying, with the sound built into the firmware so it needs no card. Sessions run 15, 30, 45, 60 or 90 minutes, or endlessly, with optional fade-out and auto-dim.


Chime. An hourly strike with five modes: off, every hour, a daytime window, sunrise to sunset from your coordinates, or specific chosen hours. It ships set to 08:00 to 22:00. It strikes by count or once, and it always yields. During an alarm, a snooze, a game, or a firmware update it will not start, and if it is already striking it stops.

Games. Eight, at three difficulties each: Ping Pong, Maze, Fly Bird, Space Dudes, Frank, Bricked Out, Wild Runner, and Meltdown. High scores are kept per game and per difficulty.








The clock itself. Two standby faces, 12 or 24 hour, seconds and date optional. Six brightness levels, plus automatic dimming from the light sensor and a night level below the manual minimum. Two font themes. Four screen savers, Checker, Distribute, Jump, and Thermal, which are the burn-in management to even out pixel wear.




Files. Alarm sounds are WAV files on a removable card: PCM, 16-bit, mono, 44100 Hz, with an ffmpeg command in the manual for conversion. To get them onto the card without removing it, the clock raises its own WiFi hotspot with a file portal on it. The WiFi is off at boot, you turn it on by hand, and it closes itself after 5 minutes idle.

Updates. The case has no external USB port. We fitted one early on and it spoiled the face, so it went. Firmware arrives two ways instead. The default is a file dropped into that same portal, which needs no internet, no server, and no account. The other is the clock joining your home WiFi to fetch a release from us over TLS. That path is optional, and the clock never checks for updates on its own.
Both paths flash the same way. The image carries a checksum verified before a single byte of flash is written. It installs to a second partition, and the bootloader reverts to the old one unless the new one reaches its main loop and survives 60 seconds. Alarms, settings, history, and saved timers are not touched. The self test deliberately checks nothing else: not the SD card, and not the clock chip. Losing power at any point leaves you on the firmware you already had.
Documentation. A 28 section manual on the clock's own screen, and the full manual served from the firmware over that hotspot, with no card and no internet needed. The device explains itself without this document.
Part six: Enclosure
Connecting the arcade button to the board and sizing it up settled the scale question immediately. In our heads the device was about two cans of coke. In fact it is about the size of a toaster. That is fine. It is still portable, and the extra bulk helps the tactility.
The finished enclosure measures 140 by 160 by 170 mm, printed in PLA, with PETG as the fallback. The front face is not flat: the bottom speaker section is vertical, and the interface panel is raked back 70 degrees for the best viewing angle from a bedside table. Upright, you cannot see the screen properly.
That angle then decided how the box is made.
The interface plate carries the holes for the screen and the controls, so it cannot sit at an angle to the build plate, or layer lines run diagonally across the whole visible face. It has to be printed parallel to the plate. Printed as one piece the box also needs a great deal of support built on top of internal faces, removing them is hard and ruins the face. The first single piece print took 26 hours at 0.2 mm layer height and came out with a set of serious issues that added up to an unusable prototype. Reprinting with different settings fixed some of them but not enough.
So the box is cut along the same 70 degree plane that set the geometry, into front and back halves. The two pieces join with a sliding dovetail, a stopper piece at the top makes sliding go only one way, and a pair of M2 stopper screws at the bottom prevent unsliding. Small test pairs of just the joint were printed to dial the fit, and it took three tries.


The back panel now prints with almost no support. The front panel uses grid support for easy removal, with top interface layers raised to 6 and a two layer top Z distance, 0.32 mm at 0.16 mm layer height. These settings use more filament, but the support comes off in one piece, which matters more.
The same geometry through the slicer, before and after the cut.
And the same prints on the machine.
Even with manufacturing methods in mind during the design the reality collides with your expectations. Fast iteration is key.
Part seven: Power
Two choices mattered here: the cell and the charger.
We wanted 18650 cells, because a standard 18650 is easy to buy anywhere and the lipo market is a thousand incompatible variants. And we did not want to weld them into a pack because that goes against the repairability. Modules exist for exactly this reason. The cells drop into holders and the leads connect to the circuit, so any cell can be removed and replaced at any time with no welding. The holders add a little resistance, which is negligible at these currents.
The charger was the harder half. The usual charging modules are notorious in the hardware community, and a battery board has to account for over-current, over-voltage, over-temperature, and short circuit protection, plus charge and discharge limits. Nothing on AliExpress carried all of it. The part came from Taobao instead: one board with the full protection set, plus separate leads for battery input and current output, which many boards do not break out at all.
This is the second of the two sourcing cases mentioned earlier. Both times the constraint was safety or capability, and both times the common part was the wrong answer.
What the build corrected
Three decisions were wrong, and the build reported each one. We publish them because a design record without them is a brochure, and because the rule each produced is the part that transfers to the next project.
A fix caused the fault. Audio stuttered early on, so a software ring buffer went in between the card reads and the DMA to smooth the stream, generously sized. It got worse in a specific way: the stutter became rhythmic, roughly three times a second, which is the ring buffer oscillating between its own high and low watermarks at the rate the audio drains it. Deleting the buffer fixed it. The DMA ring already underneath holds 32 descriptors of 512 frames, 64 kb, which is 371 ms of audio, against a card read of about 40 ms. The headroom being added already existed, in hardware, nearly ten times over. The rule: measure the headroom you have before adding a layer meant to increase it.
A part was specified for a reason that did not hold. The processor was chosen as an ESP32-S3 N16R8, with 8 mb of PSRAM, on the expectation that smooth audio would need large buffers there. It does not. A DMA copy path through the PSRAM cache creates coherency problems that are not worth the space, so the working path uses 16 kb of internal SRAM and a 64 kb DMA ring, and the firmware runs on the smaller part as well. The reason we picked the part turned out to be wrong. The part survived on other grounds, at $5 with headroom for everything else the device does. The rule: record the reason a part was chosen, so you find out when it stops being true.
A related result sits next to it: doubling the DMA ring to 128 kb works, and then fails after about three minutes, when the channel is torn down for light sleep and cannot be reopened because the heap has fragmented and there is no longer 128 kb of contiguous DMA-capable memory. 64 kb reallocates every time. The answer to a fragmentation problem was to ask for less.
The echo that accompanied the early stutter was a separate fault with a one line fix. On underrun the driver replays whatever was last in the buffer, which is why a stall sounded like a short loop rather than a gap. Telling it to zero the empty descriptors turns an underrun into silence.
Reasoning twice is not verification. The OLED header was placed mirrored on the first board. The orientation had been reasoned through repeatedly, in the software and against the physical module, flipping the board mentally and by hand, and it still ended up wrong. The rule: check it again on a different day.
One decision was reversed on taste. A full icon set was designed and inserted into every menu, then removed because it did not fit the rest of the interface. Judgement about how a thing looks is part of the engineering, and part of what a client is buying.


The build, in detail
Tap any image to enlarge.
What we do not claim
- Battery runtime on the fitted cells has not been measured, so no figure is stated. The 2 week requirement stands as a design target.
- The device does not light a room. Philips and Hatch put a real sunrise into a dark room and this does not.
- Sunrise and sunset accuracy degrades above roughly 65 degrees of latitude, where the sun may not rise or set on a given day.
- WAV only. Decoding MP3 in real time alongside the rest of the processes is not work for this processor.
- History holds ten entries, the stopwatch holds four laps, and two Pomodoro presets are stored.
- No claim is made about sleep quality.
What is open
The firmware source and the documentation are published under Apache 2.0. The PCB design files and the enclosure models publish at launch, once the board has taken its final revision. The bill of materials is public. Two bundled pixel fonts stay under Creative Commons Attribution-ShareAlike with their attributions intact, and their intermediate BDF files ship as well, so the conversion into the firmware is reproducible.
Attribution has to travel with the work, and a sealed appliance has one place to put it. So it is on a screen the owner can reach.


Conclusion
Our goal of making a multi-purpose standalone desktop clock was achieved.
The key feature of this device is not in any of its functions. The key is how far it can be expanded beyond what it is today, because of the forward looking approach taken at every decision above.
Everything we can open about this project is open. We invite the community to develop it further, to meet the needs of as many people as possible.
This is how we work at Endothermal Systems.
Common questions
Does CinderClock need an app or an account? No. Every feature runs on the device, and there is no companion app, no account, and no service behind it. It can reach the internet for exactly one thing, an update you ask it to fetch, and it works fully without ever doing so.
It has WiFi. Is it really offline? Yes, in the sense that matters: the WiFi is off at boot, it is started deliberately, it serves only to open a file transfer portal and to install firmware. The decision to turn it on is fully yours.
What exactly is open source? The firmware source and the documentation, under Apache 2.0, published now. The PCB design files and the enclosure models publish at launch. The bill of materials is public as well, so the parts list can be checked against the price. Two bundled fonts remain under CC BY-SA with attribution.
How long does the battery last? We do not know yet, so we do not say. The device is designed around a 2 week target and the processor sleeps between seconds to reach it, but the runtime has not been measured on the fitted cells and we will not publish a number until we have taken it.
Why does it cost more than a marketplace alarm clock? It is a different class of object. A marketplace clock is a screen with a small computer behind it and a fixed feature set. CinderClock is a programmable device with a published parts list, replaceable modules, and open design files, built to last and easily repaired.
Can the hardware be modified? Yes. Every active component is a breakout module on pin headers, the main PCB is through hole, and the control riser is a separate board, so the control layout can be changed without touching the main board. The live buses are broken out on labelled headers, including the audio bus, so even the amplifier can be swapped without a board revision.
START A PROJECT →
CinderClock launches on Crowd Supply. The launch list gets one message when the campaign date is set and one when it opens. Backers on the list get the launch price.
Nothing else is sent to this list, and the address is not used for anything else.
P.S. It is called CinderClock because a large white boxy shape looks like a cinder block.
Cinder block. CinderClock. Get it?
Related reading: idea to product · hardware prototype cost · pricing and guarantees.