An Arduino-based graphical “flip clock”. Bonus faces because there’s room. Really minimal enclosure.

Public Chat
Similar projects worth following
I'd had the idea for a graphical flip clock for a while (run-length encode half-digit foreground/background data, draw every n-th row to get the look of a tipped split flap) but it was on the back burner. Then I found a pretty nice 3.5” 320x480 colour LCD (ILI948x driver) on a local market website. After implementing the clock I found I had room in the sketch and was inspired by the colourfulness of the LCD, so slapped in some other faces based on code from earlier projects; a cubist clock, a triangle clock and a pong clock.
The LCD is a shield socketed onto a blank intermediate shield with RTC and push-buttons directly attached. The intermediate shield is socketed to a Uno, creating a quite thick "sandwich".

I went with an ultra minimal enclosure, front and back clear acrylic plates.

The main clock display is the day, date and month in smallish flip-style digits across the top of the LCD (landscape mode).  The time is in big digits across the bottom. As a bonus, across the middle there’s a blinking/flipping colon and also a coloured digit indicating the number of days until I need to put out either the rubbish bin (red) or the recycling (yellow). It’s alternate weeks and I keep forgetting (this display is optional).  

The time digits change with a detailed 3-step animation (top flap at 41°, 90° and 131°).  The angles come from skipping every 4th row of the digit data, so it’s acos(3/4)=41°, close enough to 45°!

The LCD inspired me to add in some additional clock “faces”:


The LCD colours are appealing, so I experiment with coloured cubes. The look is based on this font

Triangle Clock

An adaptation of an eariler project with a triangulated irregular network (TIN) style face, more pretty colours.


There was a little program memory left, so I squeezed in a very simple Pong Clock, again using code from an earlier project.

The sketch uses all but around 100 bytes of the Uno’s program storage space.

There are two push-buttons, Set and Adj. Pressing Adj from time display cycles through the faces (including a pseudo-face which randomly cycles through faces). Pressing Set from time display goes to the configuration screen. This uses the flip clock look. As well as setting the date and time it configures the red/yellow bin cycle (or none)

The clocks use a simple automatic DLS adjustment class which takes a table of start/end dates.

The LCD shield uses an ILI948x driver.  As always, the trick is finding some code which successfully initialises the display (including orientation).  The only other interaction is a) setting a “window” on the screen and b) filling it with colour data.

The viewing angle is fairly important, from the wrong angle the display is quite washed out.

This shield has a built-in SD-card reader, but no touch screen.  Fortunately that leaves pins 10,11,12,13 and A5 free. I connected SET/ADJ push-buttons to 10 & A5 and used 11 & 12 as SDA/SCL for a software I2C to the DS3231 real time clock module.

There was a lot of software in this project so when the time came to go from prototype to final assembly I decided to go to the other extreme and keep it as simple and minimalistic.   It starts with a blank stackable shield. This gave me access to the pins I needed for the RTC and the two switches. I mounted all directly to it. The LCD shield goes on top, and Uno underneath to create a quite thick sandwich.  This sandwich would actually have been enough, since it stands up OK. But I decided to add some protection in the form of two laser-cut clear acrylic plates. The Uno is attached to the back plate. The front plate is attached to the back plate with stacks of standoffs.

There is no backlight control and the thing is quite bright. To keep the build simple, there’s no LDR to sense ambient light and dim the display. Instead, there’s a bit of a hack in the sketch to optionally blank it between selected hard-coded hours (eg 7pm-7am). All that does is make the display black, but there’s still a glow - the copper tape is an attempt to reduce this light leakage.  I plan a separate project with an LDR and a relay…


Flickr album (pictures, with captions!)

Flickr Album

Screen shots

Photographing the screen was tricky. I modified the sketch to optionally send the LCD commands and data out the serial port.  I wrote a small Python program to read in a file of the serial output and re-create the image as a PNG.

Zipfile of *original* sketch. Latest is on GitHub

x-zip-compressed - 50.61 kB - 08/16/2019 at 03:13


  • Mega support etc

    Mark Wilson05/05/2023 at 03:16 0 comments

    UPDATE 5th May 2023:

    The sketch is now on GitHub (, original remains here as a zip). This includes:

    • Support for Arduino Mega/Mega 2560 (in addition to Uno)
    • Digit wrap is now correct - 10's of minutes going from :59 to :00 won't flash :60
    • Optional blank flap in 12-hour mode. " 307" vs "0307", see ENABLE_BLANK_TENS in Config.h
    • Automatic DLS adjustment is off by default, see ENABLE_AUTO_DLS in Config.h
    • The LCD driver has support for variants the otherwise jumble the screen, see LCD_FIXED_ORIGIN in ILI948x.h

View project log

Enjoy this project?



FooPlinger wrote 02/16/2024 at 17:07 point

I have this somewhat together, trying to wire directly to the Uno, but all I can get on the clock is it being set to 12:65.  It never changes, and when I try to set it, those settings are not saved.   Any clue as to what I may be doing wrong here?

  Are you sure? yes | no

Mark Wilson wrote 02/16/2024 at 22:50 point

Not talking to the RTC. What have you tried? I guess check continuity from UNO to 5V and Gnd on RTC, also pins 12 (SCL) and 11 (SDA). Note these are not the built-in I2C pins.  Check your documentation for the RTC, is its address 0x68?

  Are you sure? yes | no

FooPlinger wrote 02/29/2024 at 15:17 point

I moved everything back over to a breadboard, and reconnected, now I have it working. Thank you!

  Are you sure? yes | no

jimkunowsky wrote 12/03/2023 at 23:18 point

In case someone wants to build this fine project and is having trouble finding the correct display I just purchased one from  3.5" TFT LCD Display for 2560.  

  Are you sure? yes | no

mleenen wrote 10/19/2023 at 17:41 point

Hi, just a question. I have a 3.5"TFT SPI  480x320 LCD laying here. However the pins are different. Is it possible to connect my LCS using your program/ILI948x.h? My pins are:
VCC, GND, CS, RESET, DC/RS, SDI(MOSI), SCK, LED, SDO(MISO). Plus 5 others for touch and 4 others for SD-card). BTW, very nice programming! Very inspiring.

  Are you sure? yes | no

FooPlinger wrote 07/11/2023 at 18:52 point

Do you have a link to the exact display you used?  I assume this is the middle 'shield'

  Are you sure? yes | no

Mark Wilson wrote 07/11/2023 at 19:01 point

XC4482 is the middle shield. I don't have a link to the LCD, it's not Jaycar. Shows up sometimes on TradeMe

  Are you sure? yes | no

nickxippas wrote 04/25/2023 at 10:56 point

3D housing

  Are you sure? yes | no

Mark Wilson wrote 04/25/2023 at 18:59 point

That looks great, thanks!

  Are you sure? yes | no

itsworthing wrote 09/08/2022 at 17:53 point

Best one I've seen for ages.  I intend to put one in my classic 70's car.

  Are you sure? yes | no

Mark Wilson wrote 09/08/2022 at 21:30 point


  Are you sure? yes | no

Ragoth wrote 01/22/2022 at 01:12 point

The "BEST DIGITAL CLOCK", I have ever seen using Arduino UNO and TFT LCD. Hats off to your design, for your efforts and time.  Thanks for sharing it.

  Are you sure? yes | no

Mark Wilson wrote 01/22/2022 at 02:45 point

Very kind, thanks!

  Are you sure? yes | no

tk11 wrote 07/10/2021 at 06:50 point

superb project, bravo. what a modification for an operation with an arduino mega 2560.thierry

  Are you sure? yes | no

adrian wrote 06/12/2021 at 13:51 point


This is a very interesting project and your code is beautifully written - well done.

I wonder if you would share with me how you created the RLE array sequences for each of the large digits, please? I'd like to recreate them to work on 4 (or 6) separate 128x160 TFT displays.

What was the based font you used for the digits?

Many thanks,

... Adrian

  Are you sure? yes | no

Mark Wilson wrote 06/12/2021 at 22:31 point

Thanks!  I whipped up a Visual Studio program which paints each character in turn and scans the pixels to produce the RLE data, and spits out formatted C++ code for the arrays. I used "Arial"/"Arial Monospaced MT" for digits/letters and turned anti-aliasing OFF.

  Are you sure? yes | no

adrian wrote 06/13/2021 at 01:39 point

Many thanks, Mark.

  Are you sure? yes | no

jonbunker wrote 04/25/2021 at 13:56 point

Hi, all you wonderful tinkerers!

I love this project, and it would make a wonderful edition to my massive collection of strange clocks. Unfortunately, I am very ancient and have (hopefully only temporarily?) lost the use of my right arm... I wondered if somebody could make this for me?

Extremely happy to pay going rate + donate to charity or whatever.

I am in London

Thanks in advance! Jon

  Are you sure? yes | no

w5nmr wrote 02/28/2021 at 11:35 point

Hello, super project.

is it possible to synchronize RTC with DCF77? can someone post the code?
Thanks a lot !
translated by Google

  Are you sure? yes | no

rycho2012 wrote 01/12/2021 at 13:42 point

P.S. Workaround for the problem. In SmallChars.cpp file, I put 'X' at the end of both rowData and char_map. In this way I dropped the character 'X' but all others are available.


  Are you sure? yes | no

rycho2012 wrote 01/11/2021 at 19:46 point

Hi Mark, I copied your project and it works fantastic. I followed all the customization tips you discribed. I also tried to use the full character set in SmallChars.cpp file, unfortunately I can't display the last character. I uncommented all blocked characters rowData and I also extended the character map as follows: const char PROGMEM char_map [] = "0123456789: ABCDEFGHIJKLMNOPQRSTUVWXYZ \ xFF"; // all. 

What else should I change to use the full letter set? 
Best regards, Richard

  Are you sure? yes | no

Mark Wilson wrote 04/14/2020 at 06:41 point

If like Jim (barrow4491) your display is mirrored, alter the two landscape #define MADCTL0x36 lines at the top of ILI948x.cpp.  For left-right mirroring, invert b7 of the constants.  For up-down mirroring, invert b6.

  Are you sure? yes | no

nickxippas wrote 04/18/2023 at 10:39 point

Hi Mark, I copied your project and it works fantastic. I followed all the customization tips you discribed. unfortunately the screen is all scrambled the top is at the bottom and the bottom on the top can you help

  Are you sure? yes | no

Mark Wilson wrote 04/18/2023 at 19:17 point

Scrambled?  You mean the pixels are jumbled up? Or is it just upside-down?

  Are you sure? yes | no

nickxippas wrote 04/18/2023 at 20:38 point

i've sent you a picture top is at the bottom and bottom is at the top

  Are you sure? yes | no

Mark Wilson wrote 05/05/2023 at 03:36 point

The variant nicksippas had is supported in the version on GitHub.  See the LCD_FIXED_ORIGIN define

  Are you sure? yes | no

barrow4491 wrote 04/12/2020 at 06:54 point

Mark all good but the clock is mirror reverse


  Are you sure? yes | no

barrow4491 wrote 04/12/2020 at 01:29 point


  Are you sure? yes | no

barrow4491 wrote 04/12/2020 at 01:29 point

mark, thanks for that

  Are you sure? yes | no

barrow4491 wrote 04/11/2020 at 08:35 point

Thanks for the prompt response, I am a bit of a newbie with Arduino and am probably doing something stupid. 

I don't know whether it is the correct way to do it, but i am using the "add file" command when the compiler comes up with  the message "ILI948x.h: no such file or directory" for example and it adds a tab of that name and so on.

When all the files are added this way it will not upload an comes up with the error regarding unable to load to Arduino Uno

I really want to know how to correctly add the .h files to the sketch so it will compile. When I unzip your file it just gives me a list of .h and .cpp files with one .ino file (FlipClock)

Thanks in advance


  Are you sure? yes | no

Mark Wilson wrote 04/11/2020 at 22:45 point

It should compile as-is when unzipped, but we should take this off-line. I will msg you.

  Are you sure? yes | no

barrow4491 wrote 04/12/2020 at 01:35 point

Mark ,

I appreciate that, my address is



  Are you sure? yes | no

barrow4491 wrote 04/11/2020 at 05:36 point

I am having a problem with the code, cant find the libraries

can you please advise

  Are you sure? yes | no

Mark Wilson wrote 04/11/2020 at 06:52 point

What libraries?  I don't think it requires any. What error(s) are you getting?

  Are you sure? yes | no

Mark Wilson wrote 11/22/2019 at 00:33 point

See also LDRelay,

Turns the device off in the evening when the room gets dark, then back on in the morning when it's light!

  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