I like clocks and I’ve done a couple of other clock projects before. A clock with six of these round screens with each screen displaying a single hours, minutes or seconds digit would be fun and not too expensive.
I wanted an interesting shape for a PCB for the clock, something other than a green rectangle. Never one to miss a bad pun I settled on a clock in the shape of a crocodile, hence the name Clocodile.
The resolution of these small displays is typically 240 by 240 pixels with 16 bits per pixel. Even though the LCD itself is circular, the bitmap memory mapped to the LCD is still rectangular with pixels in the four corners of the bitmap being invisible.
A single screen image therefore takes 115,200 bytes of storage, and to store a full set of the digits 0 to 9 takes a little over 1MB. The original Raspberry Pi Pico has Flash storage of 2MB which is only enough for a single set of digits to be stored. (As mentioned above a fraction of the pixels are invisible, 1 – π/4 or about 21%, so it wouldn’t be necessary to store all 57,600 pixels of an image in Flash memory but that complicates DMA handling and I didn’t think it worth the extra effort.)
The Pico 2 has double the Flash memory so three sets of digits or fonts can be stored. Better but still fairly limited. However if we reduce the resolution of each stored image by a factor of two horizontally and vertically we can increase the number of stored fonts to a good dozen. At 120 x 120 pixels images are still crisp and detailed.
The displays have SPI interfaces and the PIO state machines in the processor can easily handle the SPI protocol. Each stored pixel needs to be transmitted twice to the display and each complete pixel line sent twice. There’s a quirk of the RP2350 microcontroller that can be exploited for the former. If a 16-bit half-word is written to a 32-bit register, such as a PIO FIFO, the bus duplicates the half-word into the upper 16 bits of the 32-bit word rather than leaving them as zero. The PIO can then clock all 32 bits out to the display to write a double pixel. This simplifies the DMA code and reduces overall system bus bandwidth.
The current font needs to be copied from Flash into RAM since DMA’ing from Flash through its 4-bit quad SPI interface would be a real bus bottleneck.
Each display needs a PIO state machine and a DMA channel. The Pico 2 has 12 of the former and 16 of the latter so more than enough. At midnight all six digits change at the same time and it was satisfying to see all six DMA channels running simultaneously with smooth transitions.
There are a variety of different digit fonts in the firmware - classic red and blue 7-segment LEDs as well as an amber-backlit 7-segment LCD, flip digits, various whimsical and animal fonts and of course there is a Nixie tube set. Finally a ‘Matrix raining code’ mode with digits falling down the screen. Not very practical for telling the time perhaps but visually appealing.
I also implemented a dozen or so transition effects between digits such as slides and scrolls, blinds, expansions and dissolves, as well as a realistic mode for the flip digits.
There are six pushbuttons at the front of the board for manually setting the time, changing the font and transition effect, switching between 12-hour and 24-hour mode and dimming the displays for night time.
I used the W variant of the Pico 2 which has Wi-Fi connectivity and therefore allowed the current time to be fetched from the Internet. Raspberry Pi’s SDK for the Pico has sample code to get the time via NTP from a pool of time servers. This code needed little modification. NTP returns the current UTC (GMT) time which generally won’t correspond to local time. Some means of specifying the offset from UTC to local time was needed.
I developed a simple command line interface to set parameters such as the Wi-Fi credentials (Network Name/SSID and password), the offset from UTC and how often the current time...
Read more »
James Hutchby - MadLab