Project tutorial

HSVClock © CC BY

A colourful clock with a Seeed TFT shield, fast refresh in landscape mode, simple Touch interface, Daylight Savings Time adjustment.

  • 12 respects

Components and supplies

About this project

HSV Clock

When I visited the US last, I picked up a Seeed 2.8" TFT Touch Shield (V1.0) from a RadioShack. I used it to make a colourful clock for my father for his 80th birthday.


The important points are

  • The clock face is based on a grid of rectangular cells. The cell corners are distorted by small random amounts and each cell is divided by a random diagonal. A random spread of colours is applied across the cells and each triangle is shaded to give a 3D look. Internally, the colours are represented as HSV (Hue, Saturation & Value) but converted to RGB for sending to the LCD. The time is displayed with a simple font by colouring certain cells in the complimentary colours.
  • The enclosure is laser-cut bamboo, designed in Inkscape, cut by Ponoko.
  • Unfortunately, the shield has no mounting holes so I effectively clamp it into the enclosure against the front face. An Arduino Uno piggybacks on the shield via the header pins.
  • I needed I2C access to an external RTC (DS3232). The shield doesn’t expose unused pins so I used a Uno which has extra SDA/SCL pins. I made a low-profile header connector for these which sits under the shield. I pulled power and ground from a similar connector on the ICSP pins, also under the shield.
  • I added simple Daylight Savings Time support to the sketch (one less clock to set twice a year!). Rather than deal with logic like “the last Sunday in September” it relies on a small table of specific start & end dates for future years (for New Zealand in my case).
  • I simplified the Touch library code to make the touch screen just act as a 4x4 grid of de-bounced buttons. For example, the time is set by touching the bottom left and top right corners.
  • I made some fairly heroic efforts to speed up the rendering: a repaint of the cells takes about a quarter of a second. The rendering is based around writing horizontal rows of pixels of a particular colour. I use a modified Bresenham algorithm to compute the horizontal extents of a series of pairs of lines which constitute triangles a given cell. The code which sends the pixels to the LCD is based on the library but in-lined, unrolled, simplified and optimised. Since pixel colour data is written across multiple PORTx’s, all the values are pre-computed when the colour is selected, so setting N pixels in a row to that colour is faster.
  • The LCD is used in landscape orientation. I struggled for a long time to get the screen to update in horizontal rows. The datasheet for the controller is confusing. There are commands to set the “cursor” location, “DRAM Horizontal/Vertical Address Set (R20h, R21h)”. Pixel data is written at the cursor location and the cursor updates, wrapping onto the next line when needed etc. There’s also a command to change the screen orientation, “Entry Mode (R03h)”, which also talks about adjusting the cursor row and column increments. However, I found that changing the orientation to Landscape then positioning the cursor did not work. The solution I eventually found (which may be buried in the datasheet) is to use the “window” command instead of the cursor command; “Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h)”. Setting the coordinates of the top-left corner of the window means pixel data starts there and updates horizontally (in landscape).


The circuit is simply

  • the TFT shield mounted on the Uno.
  • +5VDC, Ground, SDA & SDL go from the labelled pins on the Uno to the RTC module. Shown in the first three photos below (shield removed). Note that for access reasons, power/ground comes from the ICSP1 connector.
if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages[9014] = [{ URL: '', caption: 'Circuit (minus the shield)', type: 'image' }];
      if (typeof(lightBoxImages) == 'undefined') { lightBoxImages = {}; } lightBoxImages[8998] = [{ URL: '', caption: 'Uno with low-profile connectors to RTC', type: 'image' },{ URL: '', caption: 'Low profile connector for SDA/SCL (Yellow)', type: 'image' },{ URL: '', caption: 'Connector for power for RTC from ICSP (and blob of liquid insulation to dim power LED)', type: 'image' },{ URL: '', caption: 'Laser-cut front face of enclosure and \"clamp\" plate to secure the shield.', type: 'image' },{ URL: '', caption: 'Showing clamped shield', type: 'image' },{ URL: '', caption: 'Front of clamped shield', type: 'image' },{ URL: '', caption: 'Assembly', type: 'image' },{ URL: '', caption: 'Gluing', type: 'image' },{ URL: '', caption: 'Assembly', type: 'image' },{ URL: '', caption: 'The stack - shield, Uno, RTC and a bit of foam', type: 'image' },{ URL: '', caption: 'Inside enclosure', type: 'image' },{ URL: '', caption: 'The back showing touch interface: tap top-left & bottom-right to go into time-setting mode.  Top-right & bottom-left to change display mode', type: 'image' },{ URL: '', caption: 'Finished - front', type: 'image' },{ URL: '', caption: 'Finished - back', type: 'image' },{ URL: '', caption: 'Running, 3:07', type: 'image' }];


      Similar projects you might like

      Analog Clock using 1Sheeld Graphical LCD

      Project tutorial by Ahmed El-Hinidy

      • 9 respects

      Colorful Clock

      Project tutorial by zou wei

      • 12 respects


      Project tutorial by ye xiaobo

      • 19 respects

      DCF77 Analyzer/Clock v2.0

      Project tutorial by Erik de Ruiter

      • 80 respects

      Arduino Shield NCS314 NIXIE Tubes Clock IN-14

      Project tutorial by Team GRA_AND_AFCH

      • 91 respects

      Talking Clock 2 - (Bilingual: EN-PT)

      Project showcase by LAGSILVA

      • 64 respects
      Add projectSign up / Login