Because binary coded decimal clocks are too easy to read.

Similar projects worth following
Binary Coded Octal clock with auto brightness control, based on a PIC16F688, developed with SDCC.


The heart of this minimalist clock is the zero error Bresenham algorithm. It uses the Timer 0 to generate an interrupt at every 256 machine cycles. At every interrupt an accumulator is added by 256 up to the point where it overflows the amount of machine cycles in 1 second (Fclock/4  or 2000000). Every time the overflow occurs, the clock advances 1 second, and since such value is not divisible by 256, the difference is kept to be added to the next cycle. The side effect is that the 1 second interval have some jitter, but it is not even noticed, as the clock itself counts up every 60 seconds, or 1 minute.

static void irqHandler(void) __interrupt 0 {
    // gets here every TMR0 int (every 256 ticks)
    if (bres>=2000000) // 8MHz cpu = 2000000 cycles per second

 The interrupt routine also increments another counter which is rounded at every 32 counts to generate the timebase for the main function to run at approximately 4ms, which is also the maximum amount of time that every "digit" stays lit. The tickCounter is also used to form a rudimentary PWM, with 32 steps that is used to control the brightness of the LEDs

    tickCounter &= 31;
    if (tickCounter == 0) 
       go=1; // ~4ms per digit
    else if (tickCounter == tOFF ) {   // rudimentary PWM
       RA2=1;                          // Turns off all displays before
       RC2=1;                          // the next cycle

The firmware is developed in SDCC, and a makefile is provided.


The Display consists of a matrix of four octal "digits" with 3 bits each. 

Every time the main program run one of the digits is selected. As we have ~4ms for each LED the overall display rate for the whole display is around 16ms or ~60Hz.

The circuit provides an LDR for sensing the ambient light. A couple of resistors is used along with the LDR to condition the signal on a range from approximately 85 counts in the dark to 150 counts with the lights on. Such value is used to calculate the variable tOFF which controls the duty cycle that every digit is kept active.

On Light ambient every digit stays lit for the whole 4ms (32 out of 32 counts).

And on dark ambient every display is lit at only 1 out of 32 counts

The circuit provides two tactile switches for adjusting the time. One advances the hours and another advances de minutes. The de-bouncing of the keys is performed mainly by software, but some tactile switches can be very noisy, thus a capacitor of 10nf was used to enhance the de-bouncing.

The whole circuit can be seen below.


The circuit is being assembled on a pair of 2x8 cm perf-boards.

The unit is assemble on a handcrafted wooden base...

..and was finished using olive oil.

A micro-usb adapter provides power ( through a wall wart )


Here is a brief demonstration of the auto brightness adjustment;

And here is a demonstration of the time adjustment.


Do not try to do the math using 6 bits. The trick to read this clock is to read every 3-bit digit in binary and multiply the MSBs by 8 before summing to the LSBs.


Hex file for PIC16F688 with DS3231 RTC Module (with bug fixes from may,25)

- 13.45 kB - 05/16/2023 at 20:48



Hex file for PIC16F688 @ 8.000MHz

hex - 4.70 kB - 08/29/2021 at 04:47


  • 1 × PIC16F688 Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers
  • 12 × LED 3mm Yellow
  • 1 × Cristal 8.000 MHz
  • 1 × LDR Resistor Networks / Thick Film Networks
  • 2 × 10k 1/8 W

View all 13 components

  • Bug fixes on RTC variant

    danjovic05/26/2023 at 03:15 0 comments

    Bug fixes:

    1) Handling of 12/24 hour bit :

    Hour indication was wrong when AM/PM bit was set to 12 hour (for instance when the RTC module came from factory. The following code was inserted to convert the AM/PM time to 24 hour.

    // Compute minutes
    minutes = rtc.datetime.minutes.tens * 10 + rtc.datetime.minutes.units;
    // Compute hours, taking 12/24 hour into account
    hours   = ( rtc.datetime.hours.tens & 1) * 10 + rtc.datetime.hours.units; // base time
    if  (rtc.datetime.hours.op12_24) {  // 12 hour mode?
    	if (rtc.datetime.hours.tens >>1 ) { // PM
    		if ( hours !=12) hours = hours + 12;  // 1:00 PM to 11:59 PM ->  13:00 to 23:59
    	} else {
    		if ( hours ==12) hours = hours - 12;  // 12:00 AM to 12:59 AM ->  00:00 to 00:59
    } else { // 24 hour mode
    	hours   = rtc.datetime.hours.tens   * 10 + rtc.datetime.hours.units;

    A second provision was to set the 12/24 hour bit whenever the hour or the minute is advanced right before write the changed time to RTC

    rtc.datetime.hours.op12_24 = 0; // force 24 hour mode

    2) Hour changing every power up:

    This was harder to track and to make a long story short, I have used a workaround and called it a day.

    The RA3/MCLR line behaves like it was receiving ghost presses after power up, causing the clock to advance 1 or 2 hours every time  Such pulses did not appear if the button connected to this line was held down during power up.
    I have initially suspected from the de-bounce capacitor on the pin, and even tried to delay the startup during up one second without any change on the behavior. Nevertheless this problem does not occur on the RA1 button.

    At the end I have found that inverting the logic of the pin, making "un-pressed" as true and "pressed" as false caused the "ghost pulses" do disappear with the only side effect being the time advancing when the button is pressed (instead of when it was pressed then released).

    // Button Stuff 
    #define BUTTON1 RA3  // !RA3
    #define BUTTON2 RA1  // !RA1

  • PCB design

    danjovic05/17/2023 at 05:51 0 comments

    I have just updated the schematic on github repository and added a hand routed, single sided PCB design. The pads of the components have been enlarged to ease the homemade process.

  • RTC Chip Support

    danjovic05/16/2023 at 21:15 0 comments

    The original firmware is precise enough to keep the time, but it lacks one feature: keep the time when the clock is powered off.
    The present firmware allows the use of a DS3231 RTC module (aka Raspberry Pi RTC).

    The XTAL was removed and a 5 pin header was soldered on the board. The fuses were reconfigured to use the internal RC clock that was set to 8MHz. The I2C communication is bit-banged on the former Xtal pins (RA4 and RA5).

    After installation:

    Note: One of the tactile switches was not working and I have replaced both.

    When the RTC does not respond to I2C the clock shows an animation pattern.

  • Side by Side at 10:09

    danjovic09/11/2021 at 14:15 0 comments

    #MonKlock and #clOCkTAL side by side showing the time

  • Adding USB connector adapter

    danjovic09/10/2021 at 22:22 0 comments

    I've just added a micro-USB breakout to power the clock. Such board is hold in place using a couple of Torx head screws I had in my surplus bin.

    Rear view, after trimming and soldering the wires.

  • Wooden "case"

    danjovic09/07/2021 at 05:04 0 comments

    Wooden case for the clock, made out of scrap wood

    After cutting and sanding, I have applied olive oil to protect the wood and to accentuate the wood grain, thus getting a better appearence.

    And the result was satisfactory!

  • Assembled unit, testing light sensor

    danjovic09/02/2021 at 02:10 0 comments

    Finished assembling the clock on a couple of 2x8cm perf-boards. Wiring is done using enamelled wire.

    And here is the video of the clock working. I ran some tests with the buttons and the light sensor. 

  • GRB variant

    danjovic08/29/2021 at 05:06 0 comments

    A variant of the octal clock can be built with WS2812 LEDs using GRB to represent the octal digits.

View all 8 project logs

Enjoy this project?



danjovic wrote 08/29/2021 at 16:28 point

Thanks Ken! I liked the suggestion. I liked the suggestion. I should begin write one page with the pictures of all my clocks. 

  Are you sure? yes | no

Ken Yap wrote 08/29/2021 at 07:35 point

That's a cool concept. 👍 You should set all the clocks in your place to different timezones and host a quiz evening where the winner is the first to assign correct locations to every clock in sight. 😉

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates