LED Scrolling Clock

This is a clock I made using an RGB LED Dot Matrix unit. The time data is received from an DS1107 chip and then set out to the display. I am driving the display using 4 x 74HC595N Shift Registers, 8 bits for Red, 8 for Blue, 8 for Green and the final 8 are multiplexing the rows.

The demo shows the time and date being scrolled across in 7 different colours.

http://www.vimeo.com/4104339

Excellent!

It's very good :) Can you post more information like the code, shematic, etc ;)

2nd that. It's too great not to be replicated by someone eager to learn.

/me

I am still learning eagle so i'll do the schematic once I figure it out. If I can't do that i'll just hand draw something.

I'll post the code soon.

Yeah, I'm having a lo of trouble with Eagle. I know it's the thing to use; but I just can't seem to get to grips with it. even following tutorials to the letter doesn't seem to work.

/me

I agree. I would like to find a nice alternative if there is one out there that is eay to use.

I agree. I would like to find a nice alternative if there is one out there that is eay to use.

pad2pad is quite simple. I started with pad2pad and after I'd made some boards I switches to Eagle. When you get past the controls and the enormous part library. Eagle is the best in my opinion.

This is the first PCB program I have ever used and found it fairly easy. It's free so you can design any size board you want and not be limited to a certain size like some programs force upon you. http://www.freepcb.com/ I made two PCBs with this software and used the toner transfer method to make them myself. However it will also convert its files in Gerber format to be sent to manufacture houses if wanted.

FreePCB does not do schematics. Looks OK though.

OK here is the code…

#define OFF B11111111;
#include <TimerOne.h>
#include <avr/pgmspace.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h> 

static byte font[][8] PROGMEM = {
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000000,
      B00000100
      },
      
      {
      B00001010,
      B00001010,
      B00001010,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000000,
      B00001010,
      B00011111,
      B00001010,
      B00011111,
      B00001010,
      B00011111,
      B00001010
      },
      
      {
      B00000111,
      B00001100,
      B00010100,
      B00001100,
      B00000110,
      B00000101,
      B00000110,
      B00011100
      },
      
      {
      B00011001,
      B00011010,
      B00000010,
      B00000100,
      B00000100,
      B00001000,
      B00001011,
      B00010011
      },
      
      {
      B00000110,
      B00001010,
      B00010010,
      B00010100,
      B00001001,
      B00010110,
      B00010110,
      B00001001
      },
      
      {
      B00000100,
      B00000100,
      B00000100,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000010,
      B00000100,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00000100,
      B00000010
      },
      
      {
      B00001000,
      B00000100,
      B00000010,
      B00000010,
      B00000010,
      B00000010,
      B00000100,
      B00001000
      },
      
      {
      B00010101,
      B00001110,
      B00011111,
      B00001110,
      B00010101,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000000,
      B00000000,
      B00000100,
      B00000100,
      B00011111,
      B00000100,
      B00000100,
      B00000000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000110,
      B00000100,
      B00001000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00001110,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000100
      },
      
      {
      B00000001,
      B00000010,
      B00000010,
      B00000100,
      B00000100,
      B00001000,
      B00001000,
      B00010000
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00010011,
      B00010101,
      B00011001,
      B00010001,
      B00001110
      },
      
      {
      B00000100,
      B00001100,
      B00010100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00011111
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00000010,
      B00000100,
      B00001000,
      B00010000,
      B00011111
      },
      
      {
      B00001110,
      B00010001,
      B00000001,
      B00001110,
      B00000001,
      B00000001,
      B00010001,
      B00001110
      },
      
      {
      B00010000,
      B00010000,
      B00010100,
      B00010100,
      B00011111,
      B00000100,
      B00000100,
        B00000100
      },
      
      {
      B00011111,
      B00010000,
      B00010000,
      B00011110,
      B00000001,
      B00000001,
      B00000001,
      B00011110
      },
      
      {
      B00000111,
      B00001000,
      B00010000,
      B00011110,
      B00010001,
      B00010001,
      B00010001,
      B00001110
      },
      
      {
      B00011111,
      B00000001,
      B00000001,
      B00000001,
      B00000010,
      B00000100,
      B00001000,
      B00010000
      },
      
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00001110,
      B00010001,
      B00010001,
      B00010001,
      B00001110
      },
      
      {
      B00001111,
      B00010001,
      B00010001,
      B00001111,
      B00000001,
      B00000001,
      B00000001,
        B00000001
      },
      
      
      {
      B00000000,
      B00000100,
      B00000100,
      B00000000,
      B00000000,
      B00000100,
      B00000100,
      B00000000
      },
      
      {
      B00000000,
      B00000100,
      B00000100,
      B00000000,
      B00000000,
      B00000100,
      B00000100,
      B00001000
      },
      
      {
      B00000001,
      B00000010,
      B00000100,
      B00001000,
      B00001000,
      B00000100,
      B00000010,
      B00000001
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00011110,
      B00000000,
      B00011110,
      B00000000,
      B00000000
      },
      
      {
      B00010000,
      B00001000,
      B00000100,
      B00000010,
      B00000010,
      B00000100,
      B00001000,
      B00010000
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00000010,
      B00000100,
      B00000100,
      B00000000,
      B00000100
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00010101,
      B00010101,
      B00010001,
      B00010001,
      B00011110
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00010001,
      B00011111,
      B00010001,
      B00010001,
      B00010001
      },
      
      {
      B00011110,
      B00010001,
      B00010001,
      B00011110,
      B00010001,
      B00010001,
      B00010001,
      B00011110
      },
      
      {
      B00000110,
      B00001000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00001000,
      B00000110
      },
      
      {
      B00011100,
      B00010010,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010010,
      B00011100
      },
      
      {
      B00011111,
      B00010000,
      B00010000,
      B00011110,
      B00010000,
      B00010000,
      B00010000,
      B00011111
      },
      
      {
      B00011111,
      B00010000,
      B00010000,
      B00011110,
      B00010000,
      B00010000,
      B00010000,
      B00010000
      },
      
      {
      B00001110,
      B00010001,
      B00010000,
      B00010000,
      B00010111,
      B00010001,
      B00010001,
      B00001110
      },
      
      {
      B00010001,
      B00010001,
      B00010001,
      B00011111,
      B00010001,
      B00010001,
      B00010001,
      B00010001
      },
      
      {
      B00001110,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00001110
      },
      
      {
      B00011111,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00010100,
      B00001100
      },
      
      {
      B00010001,
      B00010010,
      B00010100,
      B00011000,
      B00011000,
      B00010100,
      B00010010,
      B00010001
      },
      
      {
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00011110
      },
      
      {
      B00010001,
      B00011011,
      B00011111,
      B00010101,
      B00010001,
      B00010001,
      B00010001,
      B00010001
      },
      
      {
      B00010001,
      B00011001,
      B00011001,
      B00010101,
      B00010101,
      B00010011,
      B00010011,
      B00010001
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00001110
      },
      
      {
      B00011110,
      B00010001,
      B00010001,
      B00011110,
      B00010000,
      B00010000,
      B00010000,
      B00010000
      },
      
      {
      B00001110,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010101,
      B00010011,
      B00001111
      },
      
      {
      B00011110,
      B00010001,
      B00010001,
      B00011110,
      B00011000,
      B00010100,
      B00010010,
      B00010001
      },
      
      {
      B00000111,
      B00001000,
      B00010000,
      B00001000,
      B00000100,
      B00000010,
      B00000010,
      B00011100
      },
      
      {
      B00011111,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100
      },
      
      {
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00001110
      },
      
      {
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00001010,
      B00000100
      },
      
      {
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010001,
      B00010101,
      B00010101,
      B00001010
      },
      
      {
      B00010001,
      B00011011,
      B00001010,
      B00000100,
      B00000100,
      B00001010,
      B00011011,
      B00010001
      },
      
      {
      B00010001,
      B00010001,
      B00001010,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100
      },
      
      {
      B00011111,
      B00000001,
      B00000010,
      B00000100,
      B00001000,
      B00010000,
      B00010000,
      B00011111
      },
      
      {
      B00001110,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00001000,
      B00001110
      },
      
      {
      B00010000,
      B00001000,
      B00001000,
      B00000100,
      B00000100,
      B00000010,
      B00000010,
      B00000001
      },
      
      {
      B00001110,
      B00000010,
      B00000010,
      B00000010,
      B00000010,
      B00000010,
      B00000010,
      B00001110
      },
      
      {
      B00000100,
      B00001010,
      B00010001,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00011111
      },
      
      {
      B00001000,
      B00000100,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000,
      B00000000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001110,
      B00010010,
      B00010010,
      B00010010,
      B00001111
      },
      
      {
      B00000000,
      B00010000,
      B00010000,
      B00010000,
      B00011100,
      B00010010,
      B00010010,
      B00011100
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001110,
      B00010000,
      B00010000,
      B00010000,
      B00001110
      },
      
      {
      B00000000,
      B00000001,
      B00000001,
      B00000001,
      B00000111,
      B00001001,
      B00001001,
      B00000111
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00011100,
      B00010010,
      B00011110,
      B00010000,
      B00001110
      },
      
      {
      B00000000,
      B00000011,
      B00000100,
      B00000100,
      B00000110,
      B00000100,
      B00000100,
      B00000100
      },
      
      {
      B00000000,
      B00001110,
      B00001010,
      B00001010,
      B00001110,
      B00000010,
      B00000010,
      B00001100
      },
      
      {
      B00000000,
      B00010000,
      B00010000,
      B00010000,
      B00011100,
      B00010010,
      B00010010,
      B00010010
      },
      
      {
      B00000000,
      B00000000,
      B00000100,
      B00000000,
      B00000100,
      B00000100,
      B00000100,
      B00000100
      },
      
      {
      B00000000,
      B00000010,
      B00000000,
      B00000010,
      B00000010,
      B00000010,
      B00000010,
      B00001100
      },
      
      {
      B00000000,
      B00010000,
      B00010000,
      B00010100,
      B00011000,
      B00011000,
      B00010100,
      B00010000
      },
      
      {
      B00000000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00010000,
      B00001100
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001010,
      B00010101,
      B00010001,
      B00010001,
      B00010001
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00010100,
      B00011010,
      B00010010,
      B00010010,
      B00010010
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001100,
      B00010010,
      B00010010,
      B00010010,
      B00001100
      },
      
      {
      B00000000,
      B00011100,
      B00010010,
      B00010010,
      B00011100,
      B00010000,
      B00010000,
      B00010000
      },
      
      {
      B00000000,
      B00001110,
      B00010010,
      B00010010,
      B00001110,
      B00000010,
      B00000010,
      B00000001
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001010,
      B00001100,
      B00001000,
      B00001000,
      B00001000
      },
      
      {
      B00000000,
      B00000000,
      B00001110,
      B00010000,
      B00001000,
      B00000100,
      B00000010,
      B00011110
      },
      
      {
      B00000000,
      B00010000,
      B00010000,
      B00011100,
      B00010000,
      B00010000,
      B00010000,
      B00001100
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00010010,
      B00010010,
      B00010010,
      B00010010,
      B00001100
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00010001,
      B00010001,
      B00010001,
      B00001010,
      B00000100
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00010001,
      B00010001,
      B00010001,
      B00010101,
      B00001010
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00010001,
      B00001010,
      B00000100,
      B00001010,
      B00010001
      },

Part 2…

      {
      B00000000,
      B00000000,
      B00010001,
      B00001010,
      B00000100,
      B00001000,
      B00001000,
      B00010000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00011111,
      B00000010,
      B00000100,
      B00001000,
      B00011111
      },
      
      {
      B00000010,
      B00000100,
      B00000100,
      B00000100,
      B00001000,
      B00000100,
      B00000100,
      B00000010
      },
      
      {
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100,
      B00000100
      },
      
      {
      B00001000,
      B00000100,
      B00000100,
      B00000100,
      B00000010,
      B00000100,
      B00000100,
      B00001000
      },
      
      {
      B00000000,
      B00000000,
      B00000000,
      B00001010,
      B00011110,
      B00010100,
      B00000000,
      B00000000
      }
};

int tMin, tHour, tSec, tDay, tMonth, tYear;
char cMin, cHour, cSec, cDay, cMonth, cYear;
  char time[30];

//Pin connected to ST_CP (Latch) of 74HC595N
byte latchPin = 8;
////Pin connected to DS (Data) of 74HC595
byte dataPin = 11;
//Pin connected to SH_CP (clock) of 74HC595
byte clockPin = 12;

uint8_t red[8], green[8], blue[8];


void setup() {
  Serial.begin(9600);
  
  RTC.stop();
  RTC.set(DS1307_SEC,30);        //set the seconds
  RTC.set(DS1307_MIN,34);     //set the minutes
  RTC.set(DS1307_HR,9);       //set the hours
  RTC.set(DS1307_DOW,6);       //set the day of the week
  RTC.set(DS1307_DATE,11);       //set the date
  RTC.set(DS1307_MTH,4);        //set the month
  RTC.set(DS1307_YR,9);         //set the year
  RTC.start();

   //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);


  Timer1.initialize(10000);         // initialize timer1 nad set interrupt period
  Timer1.attachInterrupt(screenUpdate); 
}

void loop() {

  for (int i=1; i<8; i++) {
    getTime();
    scrollLeft( time, 40, i);
      }
  
}


void screenUpdate() {
uint8_t row = B00000001;
 for (byte k = 0; k < 9; k++) {
    digitalWrite(latchPin, LOW); // Open up the latch ready to receive data

      shiftOut(dataPin, clockPin, LSBFIRST, blue[k] ); // BLUE
      shiftOut(dataPin, clockPin, LSBFIRST, red[k] ); // RED  
      shiftOut(dataPin, clockPin, LSBFIRST, green[k] ); // GREEN
      shiftOut(dataPin, clockPin, LSBFIRST, row ); 

   digitalWrite(latchPin, HIGH); // Close the latch, sending the data in the registers out to the matrix
    row = row << 1;
 }
}

void scrollLeft(char myString[], int speed, byte colour) {
 if (colour>7) {return;}

uint8_t firstChrRow, secondChrRow;
uint8_t ledOutput, redOutput, greenOutput, blueOutput;
byte chrPointer = 0; // Initialise the string position pointer
byte Char1, Char2;
byte scrollBit = 0;
byte strLength = 0;

unsigned long time;
unsigned long counter;
  
    while (myString[strLength]) {  /* Increment count till we reach the string */ 
    strLength++;}
     counter = millis();
  while (chrPointer < (strLength-1)) {
   time = millis();
  if (time > (counter + speed)) {
     Char1 = myString[chrPointer];
     Char2 = myString[chrPointer+1];
     for (byte y= 0; y<8; y++) {
         firstChrRow = -(pgm_read_byte(&(font[Char1 - 32][y])))-1;
       secondChrRow = -(pgm_read_byte(&(font[Char2 - 32][y])))-1;

       ledOutput = (firstChrRow << scrollBit) | (secondChrRow >> (8 - scrollBit) );
       byte ON = ledOutput;
        switch (colour) {
          case 1:
            redOutput = OFF; greenOutput = OFF; blueOutput = ON;
            break;
          case 2:
            redOutput = OFF; greenOutput = ON; blueOutput = OFF;
            break;
          case 3:
            redOutput = OFF; greenOutput = ON; blueOutput = ON;
            break;
          case 4:
            redOutput = ON; greenOutput = OFF; blueOutput = OFF;
            break;
          case 5:
            redOutput = ON; greenOutput = OFF; blueOutput = ON;
            break;
          case 6:
            redOutput = ON; greenOutput = ON; blueOutput = OFF;
            break;
          case 7:
            redOutput = ON; greenOutput = ON; blueOutput = ON;
            break;
        }
          
         red[y] =  redOutput;
         green[y] = greenOutput;
         blue[y] = blueOutput;
       }
     scrollBit++; 
     if (scrollBit > 7) { 
     scrollBit = 0;
     chrPointer++; 

     }
           counter = millis();
    } 
     
  }
}


void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut?
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {      
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}

void getTime()
{
  time[0] = (char)NULL;
  char stringvalue[5];  // since your value is only 4 digits long 
    strcat(time, " ");
  
  tHour = RTC.get(DS1307_HR,true); //read the hour and also update all the values by pushing in true
  itoa(tHour, stringvalue, 10);
    if (tHour<10) {strcat(time, "0");}
  strcat(time, stringvalue);
  strcat(time, ":");
  
  tMin = RTC.get(DS1307_MIN,false);//read minutes without update (false)
  itoa(tMin, stringvalue, 10);
  if (tMin<10) {strcat(time, "0");}
  strcat(time, stringvalue);
  strcat(time, ":");
  
  tSec = RTC.get(DS1307_SEC,false);//read seconds
  itoa(tSec, stringvalue, 10);
  if (tSec<10) {strcat(time, "0");}
  strcat(time, stringvalue);
  strcat(time, "  ");
  
  tDay = RTC.get(DS1307_DATE,false);//read date
  itoa(tDay, stringvalue, 10);
  if (tDay<10) {strcat(time, "0");}
  strcat(time, stringvalue);
  strcat(time, "/");
  
  tMonth = RTC.get(DS1307_MTH,false);//read month
  itoa(tMonth, stringvalue, 10);
  if (tMonth<10) {strcat(time, "0");}
  strcat(time, stringvalue);
  strcat(time, "/");
  
  tYear = RTC.get(DS1307_YR,false); //read year 
  itoa(tYear, stringvalue, 10);
  strcat(time, stringvalue);
  strcat(time, "   ");

}

OK it's not great, but i've never made a schematic before and I also had to make my own part for the RGB Matrix, but here is the schematic...

PDF of the schematic is here.. http://www.amateur-astronomy.org/Images/RGBClock.pdf

If you want to post code in an easier manor, why not post it here.

http://www.arduino.pastebin.com/

It's a custom section I made. Just better than multiple code post and some formatting!

/me

http://www.arduino.pastebin.com/

Nifty!

Mike Mc, I've made an Eagle library for the SparkFun and the LEDsee.com RGB matrix parts. (I still haven't added bi-color or mono-color variants.) It has accurate pinouts, silkscreen and border guides for both commonly available 60mm varieties.

http://halley.cc/arduino/matrix.lbr Just drop it in your EAGLE's lbr folder, and restart. You can then select the AROW (anode row LEDsee/Seeedstudio) or CROW (cathode row SparkFun) parts.

That's excellent. Thanks for that.

OK hopefully this schematic is a bit easier to understand....

For some reason, this circuit will not work if Ground is connected to Pin 8 on the final IC in the chain (IC4). No idea why.

Looks clean, Mike Mc.

I haven't had any problem with GND rails on the 595s... maybe you have hooked up something that shouldn't be? (Would be bad if you grounded a pin9 H* signal for example.)

The latching order of your 595s is different from madworm's and mine. Absolutely nothing wrong with that, it's totally arbitrary. Just mentioned it because if they shared the same latching order, then software for different folks' matrix apps would be easier to share back and forth.

Are you really running the Atmel on the internal oscillator, no external at all? How's that working for you? Guess it would work well if you are only latching the 8 colors, not trying for many shades of brightness. Saves a little money and complexity.

I have to try one of those realtime clock parts.

Ed I didn’t put the rest of the Arduino circuitry - I just took it as read as I was being lazy - it was just to emphasise the pinouts used.

I’ll take a look at your schematic and re-arrange my code and circuit so it will work with your code and vice versa.