Wednesday, March 25, 2026

Large dot matrix clock, timer and scrolling message display

First completed: August 2014. Additional work carried out late 2025/early 2026.

Introduction

Previously, the author had made a very small dot matrix clock, but he had ambitions to make something much bigger, with a new goal of making a display similar in size to the 6-inch jumbo radio-controlled LED clock/timer but with all the versatility of a dot matrix display.

This new design would be an expansion of the first design with a number of enhancements:

Selection of dot matrix displays
  • Larger dot matrix displays, 5mm LED size, 120mm overall display height with two rows of displays
  • Changed to 74HC595 shift registers to add latch feature, essential if shift registers are to be used for row drivers as well
  • Much more powerful power supply
  • MOSFETs for row drivers due to much higher current requirements

The principle of operation is exactly the same as before, just expanded to a bigger display. The new display would be 96x16 pixels, requiring 12 displays across and two rows. 14 shift registers (two for rows, 12 for columns) were cascaded so that a single data pin on the microcontroller would supply data to all of them.

Column drivers Data Data Column drivers Column drivers Row drivers Row drivers Data Data Data input

Hardware design

To ensure that the maximum current rating of the shift register wouldn't be exceeded when a large number of pixels are on, some small PNP transistors were selected for the column drivers (each one would only have to drive one pixel at a time) and large N-channel MOSFETs were selected for the row drivers as each one would have to drive an entire row of pixels.

It is common to overdrive multiplexed LEDs because driving them at their normal continuous rated current would result in a dim display once multiplexing is introduced. The trouble with that is that the LEDs will be quickly destroyed if the microcontroller freezes up for any reason and leaves a row continuously illumnated. The 75 ohm resistors used for the columns limit LED current to about 43mA, which achieves a good level of brightness without immediately destroying the display if a row is illumnated continuously. This also results in a maximum possible current for a fully illuminated row of 4.096A.

Here is the design for the row drivers:

SVG Image created as display-circuit-RowDrivers1.svg date 2026/03/01 14:33:52 Image generated by Eeschema-SVG 1 1 2 2 3 3 Q101 Q101 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q103 Q103 STP36NF06L STP36NF06L GND GND 1 1 2 2 3 3 Q102 Q102 STP36NF06L STP36NF06L GND GND GND GND GND GND 1 1 2 2 3 3 Q99 Q99 STP36NF06L STP36NF06L GND GND GND GND GND GND 1 1 2 2 3 3 Q104 Q104 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q? Q? STP36NF06L STP36NF06L GND GND 1 1 2 2 3 3 Q100 Q100 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q98 Q98 STP36NF06L STP36NF06L GND GND +5V +5V GND GND SER SER 14 14 SRCLK SRCLK 11 11 ~{SRCLR} ~{SRCLR} 10 10 RCLK RCLK 12 12 ~{OE} ~{OE} 13 13 VCC VCC 16 16 GND GND 8 8 QA QA 15 15 QB QB 1 1 QC QC 2 2 QD QD 3 3 QE QE 4 4 QF QF 5 5 QG QG 6 6 QH QH 7 7 QH' QH' 9 9 U13 U13 74HC595 74HC595 ROW6 ROW6 ROW7 ROW7 ROW2 ROW2 ROW3 ROW3 ROW1 ROW1 D_OUT D_OUT D_IN D_IN CLK CLK ROW8 ROW8 ROW5 ROW5 ROW4 ROW4 OE OE LAT LAT GND GND Q102 Q102 STP36NF06L STP36NF06L 1 1 2 2 3 3 GND GND Q101 Q101 STP36NF06L STP36NF06L 1 1 2 2 3 3 GND GND GND GND Q103 Q103 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q104 Q104 STP36NF06L STP36NF06L 1 1 2 2 3 3 GND GND GND GND Q99 Q99 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q? Q? STP36NF06L STP36NF06L 1 1 2 2 3 3 GND GND Q100 Q100 STP36NF06L STP36NF06L 1 1 2 2 3 3 Q98 Q98 STP36NF06L STP36NF06L 1 1 2 2 3 3 GND GND +5V +5V GND GND U13 U13 74HC595 74HC595 SER SER 14 14 SRCLK SRCLK 11 11 ~{SRCLR} ~{SRCLR} 10 10 RCLK RCLK 12 12 ~{OE} ~{OE} 13 13 VCC VCC 16 16 GND GND 8 8 QA QA 15 15 QB QB 1 1 QC QC 2 2 QD QD 3 3 QE QE 4 4 QF QF 5 5 QG QG 6 6 QH QH 7 7 QH' QH' 9 9 GND GND

Here is the design for the column drivers:

SVG Image created as display-circuit-DisplayBlock1.svg date 2026/03/01 14:33:52 Image generated by Eeschema-SVG R14 R14 75 75 +5V +5V +5V +5V 2 2 1 1 3 3 Q4 Q4 BC556 BC556 GND GND R13 R13 1k 1k +5V +5V 2 2 1 1 3 3 Q7 Q7 BC556 BC556 GND GND +5V +5V R1 R1 9 9 R2 R2 14 14 R3 R3 8 8 R4 R4 12 12 R5 R5 1 1 R6 R6 7 7 R7 R7 2 2 R8 R8 5 5 C1 C1 13 13 C2 C2 3 3 C3 C3 4 4 C4 C4 10 10 C5 C5 6 6 C6 C6 11 11 C7 C7 15 15 C8 C8 16 16 LED2 LED2 ~ ~ R8 R8 75 75 R12 R12 75 75 R3 R3 1k 1k +5V +5V R1 R1 9 9 R2 R2 14 14 R3 R3 8 8 R4 R4 12 12 R5 R5 1 1 R6 R6 7 7 R7 R7 2 2 R8 R8 5 5 C1 C1 13 13 C2 C2 3 3 C3 C3 4 4 C4 C4 10 10 C5 C5 6 6 C6 C6 11 11 C7 C7 15 15 C8 C8 16 16 LED1 LED1 ~ ~ SER SER 14 14 SRCLK SRCLK 11 11 ~{SRCLR} ~{SRCLR} 10 10 RCLK RCLK 12 12 ~{OE} ~{OE} 13 13 VCC VCC 16 16 GND GND 8 8 QA QA 15 15 QB QB 1 1 QC QC 2 2 QD QD 3 3 QE QE 4 4 QF QF 5 5 QG QG 6 6 QH QH 7 7 QH' QH' 9 9 U1 U1 74HC595 74HC595 R11 R11 1k 1k R10 R10 75 75 2 2 1 1 3 3 Q6 Q6 BC556 BC556 R9 R9 1k 1k 2 2 1 1 3 3 Q5 Q5 BC556 BC556 +5V +5V R5 R5 1k 1k R16 R16 75 75 +5V +5V 2 2 1 1 3 3 Q2 Q2 BC556 BC556 R4 R4 75 75 +5V +5V 2 2 1 1 3 3 Q8 Q8 BC556 BC556 2 2 1 1 3 3 Q3 Q3 BC556 BC556 R6 R6 75 75 R7 R7 1k 1k R15 R15 1k 1k 2 2 1 1 3 3 Q1 Q1 BC556 BC556 +5V +5V R2 R2 75 75 R1 R1 1k 1k ROW2 ROW2 ROW1 ROW1 ROW14 ROW14 ROW15 ROW15 D_OUT D_OUT ROW16 ROW16 D_IN D_IN CLK CLK OE OE LAT LAT ROW8 ROW8 ROW13 ROW13 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW10 ROW10 ROW9 ROW9 ROW11 ROW11 ROW12 ROW12 ROW3 ROW3 COL8 COL8 COL8 COL8 COL2 COL2 COL6 COL6 COL3 COL3 COL3 COL3 COL5 COL5 COL4 COL4 COL1 COL1 COL7 COL7 COL4 COL4 COL6 COL6 COL1 COL1 COL2 COL2 COL2 COL2 COL1 COL1 COL4 COL4 COL6 COL6 COL7 COL7 COL8 COL8 COL7 COL7 COL3 COL3 COL5 COL5 COL5 COL5 +5V +5V Q7 Q7 BC556 BC556 2 2 1 1 3 3 +5V +5V Q5 Q5 BC556 BC556 2 2 1 1 3 3 +5V +5V +5V +5V Q2 Q2 BC556 BC556 2 2 1 1 3 3 R4 R4 75 75 Q3 Q3 BC556 BC556 2 2 1 1 3 3 R6 R6 75 75 Q1 Q1 BC556 BC556 2 2 1 1 3 3 +5V +5V R2 R2 75 75 +5V +5V Q4 Q4 BC556 BC556 2 2 1 1 3 3 R8 R8 75 75 R10 R10 75 75 R14 R14 75 75 R16 R16 75 75 +5V +5V Q8 Q8 BC556 BC556 2 2 1 1 3 3 +5V +5V Q6 Q6 BC556 BC556 2 2 1 1 3 3 R12 R12 75 75 +5V +5V U1 U1 74HC595 74HC595 SER SER 14 14 SRCLK SRCLK 11 11 ~{SRCLR} ~{SRCLR} 10 10 RCLK RCLK 12 12 ~{OE} ~{OE} 13 13 VCC VCC 16 16 GND GND 8 8 QA QA 15 15 QB QB 1 1 QC QC 2 2 QD QD 3 3 QE QE 4 4 QF QF 5 5 QG QG 6 6 QH QH 7 7 QH' QH' 9 9 GND GND GND GND

And the overall circuit diagram of the entire display module:

SVG Image created as display-circuit.svg date 2026/03/01 14:33:52 Image generated by Eeschema-SVG CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock12 DisplayBlock12 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock8 DisplayBlock8 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock7 DisplayBlock7 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock11 DisplayBlock11 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock6 DisplayBlock6 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock9 DisplayBlock9 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock5 DisplayBlock5 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock10 DisplayBlock10 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock4 DisplayBlock4 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock3 DisplayBlock3 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock2 DisplayBlock2 File: colblock.kicad_sch File: colblock.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 RowDrivers1 RowDrivers1 File: rowdrivers.kicad_sch File: rowdrivers.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 RowDrivers2 RowDrivers2 File: rowdrivers.kicad_sch File: rowdrivers.kicad_sch CLK CLK D_IN D_IN D_OUT D_OUT LAT LAT OE OE ROW1 ROW1 ROW2 ROW2 ROW3 ROW3 ROW4 ROW4 ROW5 ROW5 ROW6 ROW6 ROW7 ROW7 ROW8 ROW8 ROW9 ROW9 ROW10 ROW10 ROW11 ROW11 ROW12 ROW12 ROW13 ROW13 ROW14 ROW14 ROW15 ROW15 ROW16 ROW16 DisplayBlock1 DisplayBlock1 File: colblock.kicad_sch File: colblock.kicad_sch DISP_D DISP_D DISP_LAT DISP_LAT DISP_CLK DISP_CLK DISP_OE DISP_OE

Assembly

The displays were painstakingly assembled onto a very large piece of stripboard and soldered by hand. This option made sense at the time, but in 2026, a proper custom-made PCB would make more sense given how cheap they are nowadays.

The control electronics were assembled onto a smaller piece of stripboard. As with the small display, an ATmega328p was used here. The two shift registers for the row drivers are contained on this board along with some other circuitry including a power supply voltage supervisor IC which turns off the output enable signals on the shift registers to ensure that a row does not get stuck on when the power supply voltage is falling during power-down.

Software development

The SPI interface is bit-banged in code using direct register access to the port I/O which makes that technique adequately fast. As the row driver shift registers are first in the chain followed by the column drivers from left to right, the pixel data for the rightmost column must be shifted out first followed by the rest of the display in right-left order, then the 16 row enable signals are shifted out last. This arrangement allows some time to be saved in the brightness control procedure; brightness control is achieved by turning all the rows off a certain duration after a row is turned on, but as all the rows are off, there is no need to update the column data so only the 16 bits for row control need to be shifted out for this cycle.

[Add waveform captures]

As with the small display, a timer interrupt is used for the display code. The radio controlled time reception is also handled in the timer interrupt as is reading an LDR to automatically set the brightness level. The actual 'application software' is implemented in functions which are called from the main loop which just holds the menu structure.

The 'applications' implemented are:

  • Big clock - time displayed using 16 pixel high digits
  • Small clock - time and date displayed using 7 pixel high digits
  • Stopwatch - shows just the timer with 16 pixel high digits or timer and lap or split time simultaneiously with 7 pixel high digits
  • Labour timer - similar to the stopwatch, but also displays the cost of the time based on an hourly labour rate set in the settings
  • Countdown to time - counts down to a specific time on any day of the week (maximum 7 days in the future)
  • Serial display - shows received text on a 16x2 grid, similar to a 16x2 HD44780-compatible LCD
  • Message display - shows received text as a scrolling message. Special character codes can be used to insert any part of the current time and date into the message.

Software development was mainly carried out in 2014, then it was worked on again in 2026 to add the 'Numbers Game' application which replicates the numbers round from a popular TV game show which has letters and numbers.

Display brightness problem in newer versions of Arduino IDE

It was discovered that when the code was recompiled in a newer version of Arduino IDE, the brightness of the individual rows was no longer consistent. A lot of time was spent trying different compiler optimisation levels, using pragmas to disable optimisation of the timer interrupt and rewriting the code in different ways but none of them fixed the problem.

Of course, one option was to just use the old IDE, but the newer IDE produces smaller code, which would free up some program memory for new features. The program took up nearly all of the program memory under the old compiler prior to the addition of the 'Numbers Game' application.

Shift register control waveform with pre-1.5.x Arduino IDE:

Shift register control waveform with 1.5.x or later Arduino IDE:

The author eventually resorted to asking ChatGPT about the issue. It explained that the AVR only has instructions for shifting a single bit at a time (true) and that the older compiler apparently used a "partially unrolled strategy" which pre-selected the relevant byte from the 16-bit display data then shifted the bits in the relevant half whereas the newer one used the generic libcc helper which operated directly on the 16-bit register. The timing from the old compiler seemed just too consistent for that to be the case but the explanation of the behaviour of the new compiler was believable.

As AI has a tendency to make stuff up, the assembly language generated from the original code will be analysed to see if the AI's assessment is accurate.

But first, the AI suggested a new implementation for the display bit calculation which moved the shift outside the loop, meaning it no longer had to be executed for every column, and this resolved the problem.

uint16_t mask = (uint16_t)1 << rowcounter;

for (loopcounter = 0; loopcounter < cols; loopcounter++) {
uint8_t bit = (display[cols - loopcounter - 1] & mask) ? 0 : 1;

PORTD = (bit << 2) | 0x08; // data + clock high
asm("nop");
PORTD = PORTD & 0x04; // clock low, retain data
}

To extract the assembly language file, the avr-objdump program (avr-objdump -I. --all-headers -S file.elf) was used on the compiled binary (.elf file). To get the .elf file in Arduino 2.x, go to Sketch > Export Compiled Binary and this will generate a folder inside the project folder with the .elf file inside. In Arduino 1.0.x, verify your project then go into your temp folder, sort by date modified, and go into the newest folder to find the .elf file.

Old compiler assembly code:

5c02: 80 91 af 02 lds r24, 0x02AF ; 0x8002af <rowcounter>
5c06: 48 2f mov r20, r24
5c08: 50 e0 ldi r21, 0x00 ; 0
5c0a: 21 e0 ldi r18, 0x01 ; 1
5c0c: 30 e0 ldi r19, 0x00 ; 0
5c0e: 02 c0 rjmp .+4 ; 0x5c14 <__vector_11+0x136>
5c10: 22 0f add r18, r18
5c12: 33 1f adc r19, r19
5c14: 8a 95 dec r24
5c16: e2 f7 brpl .-8 ; 0x5c10 <__vector_11+0x132>
5c18: ef e6 ldi r30, 0x6F ; 111
5c1a: f3 e0 ldi r31, 0x03 ; 3
5c1c: 80 81 ld r24, Z
5c1e: 91 81 ldd r25, Z+1 ; 0x01
5c20: 82 23 and r24, r18
5c22: 93 23 and r25, r19
5c24: 89 2b or r24, r25
5c26: 11 f4 brne .+4 ; 0x5c2c <__vector_11+0x14e>
5c28: 84 e0 ldi r24, 0x04 ; 4
5c2a: 01 c0 rjmp .+2 ; 0x5c2e <__vector_11+0x150>
5c2c: 80 e0 ldi r24, 0x00 ; 0
5c2e: 8b b9 out 0x0b, r24 ; 11

New compiler assembly code:

4514: 20 91 fb 02 lds r18, 0x02FB ; 0x8002fb <rowcounter>
4518: 92 91 ld r25, -Z
451a: 82 91 ld r24, -Z
451c: 02 c0 rjmp .+4 ; 0x4522 <__vector_11+0x96>
451e: 95 95 asr r25
4520: 87 95 ror r24
4522: 2a 95 dec r18
4524: e2 f7 brpl .-8 ; 0x451e <__vector_11+0x92>
4526: 80 fd sbrc r24, 0
4528: 91 c0 rjmp .+290 ; 0x464c <__vector_11+0x1c0>
452a: 84 e0 ldi r24, 0x04 ; 4
452c: 8b b9 out 0x0b, r24 ; 11

As well as being completely different to the new compiler's code, it is noteworthy that the old compiler's output did not match ChatGPT's explanation of how the old compiler generated the code. In the old compiler's code, the ror instruction is nowhere to be seen, and the code much more closely resembles the mask-shifting code that the AI wrote instead. The left shift of the mask is implemented by adding it to itself (add r18, r18). The new compiler's code, which fits in with ChatGPT's explanation of how the newer compiler performs the right shift, takes up less program memory, though none of the various compiler optimisation options were able to make it work like the old compiler did.

More hardware

After assembly of the electronics was completed, it was discovered that some STP36NF06 MOSFETs had been purchased instead of STP36BF06L. The difference is the former is not logic level. It just about worked at 5V exactly but the slightest voltage drop would result in the rows with the logic level MOSFETs being brighter than the ones without. New logic level MOSFETs were eventually ordered to replace the non-logic level ones and the improvement in the consistency of the brightness of the display was noticeable.

Originally, the only mechanical strength in the hardware came from the stripboard and solder joints. Thin strips of stripboard were soldered along the bottom edge of the display and bolted to a piece of wood. This made it very weak mechanically, as the strips on the stripboard have little mechanical strength and will rip off quite easily. This all changed in 2025 when the author designed a 3D printed case for the display.

The case was designed in sections for the reasons of the display being far too big to fit on most 3D printers and the fact that much less filament would be wasted in the case of a design error being made as long as it was discovered before the whole case was printed.

Remote control

The serial port on the AVR microcontroller, usually used for programming it using the Arduino bootloader, was also used to enable the display to be controlled from a computer. This is where the text to display in the 'Serial Display' and 'Message Display' modes would be entered. The five buttons from the side of the display were also replicated here.

The discovery of these low cost Bluetooth TTL UART adapters resulted in another idea...

The open-source Bluetooth-spp-terminal was tested and the display responded as expected once the correct commands were entered.

This app was modified in Android Studio to add a set of buttons similar to the desktop application. This worked, and resulted in an app with all the same functions as the desktop version. No changes were needed to the display's firmware to add support for the mobile app.

Large dot matrix clock, timer and scrolling message display

First completed: August 2014. Additional work carried out late 2025/early 2026. Introduction Previously, the author had made a very small ...