Notes from Windward: #70


A Digital Ship's Bell Clock

adventures of a micronaut

November 2:


building Arduino aptitude
and problem solving skills

     Ship's bells have been used to sound the time onboard ships as early as the 15th Century. Unlike land based civilian clock bells, the strikes of the bell do not accord to the number of the hour. Instead, there are up to eight bells, one added for each half-hour of a four-hour watch. Bells would be struck every half-hour, and in a pattern of pairs for easier counting, with any odd bells at the end of the sequence.

Opalyn ringing the lunch bell

     A digital ship's bell clock exemplifies the basic core functions of many future Windward Arduino projects:

  • keeping track of time,

  • triggering events accordingly,

  • enabling user interaction through buttons and a display.

     Because of that, it makes for a great learning and exercise project, yielding experience that all subsequent projects can profit from.

     Abbreviations used in this article:


Getting Started

     The first puzzle to solve is teaching the Arduino's uC how to talk to the RTC. The uC is very good at doing a lot of different things at the same time, especially keeping oversight over what others are doing and acting on that. But if you're doing lots of things at once, it's hard to keep track of time. Therefor we want to delegate issues of time to a specialty chip, the clock chip or RTC. The clock chip does just that: Keep track of time and date and disclose that information upon request.

collaboration between these two
components is essential

     On a project like this, I find the datasheet for each component before I do anything else. A datasheet is a document that outlines the properties and functions of a specific electronic component.

a collage of data sheets

     Microchip datasheets contain, among other things, a collection of maps explaining the anatomy of the chip's brain and body. Those maps are what I am looking for; with their help I can find the short and long term memory, the "speech center," how the chip wants to be addressed, what part of it is ear and what is mouth? Those are the things I need to know if I want to create a network of chips working as a team.

     This information is the brick and mortar from which I construct the program code. Like any good architect, I don't just start stacking bricks and see what happens; I go out there and look at houses that other people have built. In this case, that means searching the Internet for projects that were realized using the same or similar components and analyzing the techniques that those people used. No need to reinvent the wheel.

snippet of the Arduino programming
software environment

     Looking at different examples also gives me some hardware related questions to think about. Should I have an additional chip that is responsible for working with the 7-segment display or can I let the uC handle the display by itself? Is the uC's output current strong enough to drive a little speaker or will I need a dedicated amplifier?

     Going over the numbers in my head, I decide that I can safely run both the display and the speaker directly off the uC. That's the route I like since the less complex the hardware setup is, the less error prone a project will be.

The Clock Ticks

     While researching other projects online, I found a piece of program code that lets me both set and read the internal time of the clock chip through my laptop. This means I can verify that the uC and clock chip are communicating correctly without yet adding the display to the setup.

     Getting your hardware running step by step rather than as a whole makes for a lot easier trouble shooting throughout development. I used a flat ribbon cable to connect the two components through the uC's I2C ports, and that was really all it took to make them work together.

the final hardware arrangement,
but we're not there yet

     Getting the uC and RTC talking was a breeze compared to the 7-segment display. Since I decided to not use a dedicated chip to control the display, the uC has to do all that work by it's self.

     This work consists of two parts:

  1. Requesting and storing time data from the clock chip

  2. Converting that data and relaying it to the display.

     A 7-segment display gets that name because each digit consists of seven illuminated segments. 4 digits times 7 segments adds up to a total of 28 segments.

a mechanical drawing of a 7-segment
4 digit display

     28 segments cannot be controlled by the uC individually. I have to resort to trickery to make this work, playing off the visual inertia of the human eye. By displaying only one digit at a time, but all four in quick succession, a few hundred times per second, it seems as if all four digit are constantly lit. This is what makes CRT monitors and TVs work too. Again, there is no need to reinvent the wheel. Many others have used this trick before me; knowing and understanding what others have done, and why, speeds up development a great deal.

     I had no major problems getting the display up and running, but this method has implications further down the road: I can never allow any program code to ever pause operations for more than a few milliseconds, otherwise the display will flicker or even "freeze," exposing the bluff.

     Other things to consider when dealing with 7-segment based displays: Use separate current limiting resistors for each segment; otherwise digit brightness will appear uneven.

Moving From the Breadboard to a DIY Shield

     So far I've done all my work on an experimental breadboard setup. That kind of environment allows me to implement design changes quickly, but discourages complex circuits. To keep things organized, I moved the 7-segment display and it's peripherals onto a separate piece of perforation board, which I designed to conveniently plug on to the Arduino project board.

intermediate hardware setup

     Now I have enough room on the breadboard for the speaker and button circuit, which will follow soon.

The Bell Rings

     Creating the program code that deals with the bell strike pattern and generating the ringing sound was the most complicated part of this project. It was also the only part in which I had no relevant precedent to draw inspiration from.

     I knew from the very beginning that I was going to use the PWM function of the uC to generate the sound. Being able to manipulate the pulse width of my signal allows me to change its perceived amplitude, making it slightly more than just a square-wave beep.

     Also, the PWM signal runs at a soothing, preset 460Hz without interrupting any of the other operations the uC is involved in. That's important because I'm trying to keep operations in a constant flow so the display doesn't flicker or freeze.

     I hooked up the little speaker to confirm the validity of my approach and let it beep around for a bit. The ringing algorithm I came up with can be described in two parts: One part creates the actual ringing sound and groups the sounds into pairs. The other part is a so called "lookup table". It contains the information on which hours receive X number of strikes. Again, the tricky part was writing the software in a cyclical manner. No straightforward pauses or delays. Parts that require specialized timing just count the number of cycles the main program loop progresses through, and trigger certain events at a certain number of cycles.

diagram describing stages the main program loop

Sewing on Buttons

     So far I have been setting the time on my clock chip through my laptop, but that is not an option for a clock that will be sitting on a desk. The button interface I decided on consists of two push buttons to change hours and minutes, and a switch to enable/disable the "set time" mode.

     When using buttons and switches as input devices with a uC, de-jumping is an important issue. On the instant of being switched or pressed, switches and buttons jump back and forth for a millisecond or so, causing confusion for the software. The solution is easy: Upon initial changing of the input signal, wait a few milliseconds and sample that input again, only use the second sampling as valid information for further processing. Bridging the physical contacts with a small capacitor also helps.

experimental button and speaker setup

     Other than that, I also added an "auto-run" function, where a button being depressed for a certain amount of time will trigger the minutes or hours to count up continuously. The way a device responds to user input through buttons may seem trivial, but that is what truly shapes the users experience with a product. If one press of a button adds one minute at a time and another press suddenly adds four minutes, the device feels crude and unreliable - two words you don't want to associate with a clock. If you can change minutes faster by pressing the button multiple times in short successions than by keeping it depressed and letting the auto-run do it for you, your auto-run function is pointless.

Moving from the Arduino Project Board to Dorkboard

     At this point all my hardware is running properly. The clock displays the time, the bell rings at the appropriate times and the buttons let me reset the time if need be. Now I need to make everything compact enough to fit into a case.

moving from a luxury sedan to an e-bike

     That means two things: Migrating from the Arduino Project board to a tiny, bare bone Arduino Clone, the Dorkboard and designing a main carrier board, which will plug on to the Dorkboard. The carrier board will hold the Real Time Clock Module, the display, the speaker and connect with the buttons.

the bottom of the carrier board

connects with the Dorkboard and the RTC module

     In a first step I soldered only the display onto the carrier board in order to get an indication of how well the dork board was working with the software. Indeed there were problems to be dealt with. The display kept lighting up in ways it was not supposed to because one of the Dorkboard's I/O ports was not able to drop to a zero volt level. I made sure that my carrier board was not faulty, then I tested out every bit of the software and checked every connection on the Dorkboard itself. I couldn't find the error.

The faulty USB/Serial adapter

     In a last ditch effort, I disconnected the USB/Serial interface and hooked the Dorkboard up to a separate 5 volt power supply. Suddenly everything worked fine! Since the USB/Serial Interface was not going to be part of the final setup, this issue was of no concern to me and I moved on to soldering the remaining components onto the carrier board.

Power struggle: Wall-warts and Voltage Regulators

     The clock runs off a wall-wart power supply. The one I picked is rated at 4.5VDC and 600mA. What I didn't realize was that the 4.5V level only applies if you are actually sinking the full 600mA. My whole setup sinks less than 60ma, and at that current the output voltage is almost 8V - too much for the clock chip.

salvaged voltage regulator

     The remedy: salvaging an old 7805, 5 Volt regulator and mounting on the carrier board. Now all my chips are getting fed their favorite diet: 5 volt Direct Current.

The case is clear

     With the new compact hardware setup functioning properly, the only step left was mounting all the components into a case: a plastic flip-top box made to hold office supplies.

main carrier board mounted in case

     The larger holes got drilled, the smaller ones melted with the tip of my soldering iron. The plug for the power supply is held in place by a solid amount of hot glue.

button and power wiring

Final thoughts

     This has been my first Arduino based project and my first electronics/programming project in quite a few years. It was just the right degree of difficulty to get back into the groove and I am looking forward to many future projects!

the finished product

To check out the software code that runs the clock,
Click Here.


Notes From Windward - Index - Vol. 70