Project: Arduino Clock with DVD Player LED Display

A while ago, an Aldi DVD player with a dead laser pickup landed on my desk. Not being economically worth repairing, it was to be scrapped anyhow. I found the front panel had a potted LED module – so I snipped that off and saved it for a future project.

DVD LED Display

Seeing it sit on my desk for weeks made me feel sad – so I decided to grab it and decipher it.

DVD Player LED Display Underside

Looking up the code itself yielded no matches – so it was time for the multimeter. A quick trace shows that there are 5 common cathodes (one for each digit and one for the symbols) and 7 anodes.

DVD LED Display Pinout

That’s not too hard to deal with. I just had to solder some nice resistors (680 ohm in series with each anode – it’s what I had lying around) to it to limit the current to the LEDs and do some coding and I’ll be able to put it to use. I also had a stack of TinyRTC v2 modules I ordered earlier from eBay – so I decided to make a nasty clock out of the DVD LED display.

DVD Player LED Display Clock

The code itself took me about 45 minutes to write. Again, it’s very ugly and commentless (and the variable names aren’t all great) but it was written in one sitting and I’m lazy as usual. I know that if I screw up, it’ll be me debugging the code anyway. It relies on the RTClib by JeeLab as referred to by LadyAda’s excellent DS1307 tutorial. It compiles to a sketch size of just 4,944 bytes (much less than I expected) and is fairly specific to the way I’ve built the hardware.

The premise is quite simple:

  • Use a DS1307 that keeps time as the time source.
  • Read the time periodically from the DS1307 (every 100ms).
  • Break up the time into individual digits/symbols.
  • Map the digits/symbols into anode pin states.
  • Whenever the above is not happening (i.e. spare time), write the given anode pin states for a given cathode combination (the drawscreen function) – cycle through all cathodes one at a time in quick succession (with short delay) as a form of visual multiplexing.

In order to actually develop the system, first I thought about, traced and soldered up the hardware. Then I wrote some code that drove the cathodes to “refresh” the display. Then I wrote some sample anode code that pushed random(0,2) bits to the arrays holding the anode data once a second while I double checked and tweaked the delays inside the drawscreen function. Once that was working, I set my DS1307 to the current time using the ds1307 example sketch (with modification to supply power to the chip). Then, I borrowed code from the ds1307 library example to tie it all together.

/* 
Gough's DVD Player Screen Clock

Pin Allocation
53 = A, 51 = B, 49 = C, 47 = D, 45 = E, 43 = F, 41 = G
39 = Disp 1 Cathode, 37 = Disp 2 Cathode, 35 = Disp 3 Cathode, 33 = Disp 4 Cathode, 31 = Symbol Cathode
18 = GND DS1307, 19 = Vcc DS1307
*/

#include <Wire.h>
#include "RTClib.h"
#define CATHODES 5
#define ELEMENTS 7

RTC_DS1307 RTC;
int symbolpins[ELEMENTS] = {53,51,49,47,45,43,41};
int cathodepins[CATHODES] = {39,37,35,33,31};
int secondbits[ELEMENTS];
int characterdata[10][ELEMENTS] = { {1,1,1,1,1,1,0},
                                    {0,1,1,0,0,0,0},
                                    {1,1,0,1,1,0,1},
                                    {1,1,1,1,0,0,1},
                                    {0,1,1,0,0,1,1},
                                    {1,0,1,1,0,1,1},
                                    {1,0,1,1,1,1,1},
                                    {1,1,1,0,0,0,0},
                                    {1,1,1,1,1,1,1},
                                    {1,1,1,1,0,1,1} };
int symboldata[CATHODES][ELEMENTS] = {0};
unsigned long lasttime;

void setup () { 
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);
  digitalWrite(18, LOW);
  digitalWrite(19, HIGH);

  Wire.begin();
  RTC.begin();

  int i=0;
  while(i<CATHODES) {
    pinMode(cathodepins[i], INPUT);
    i++;
  }
  i=0;
  while(i<ELEMENTS) {
    pinMode(symbolpins[i], OUTPUT);
    i++;
  }
  i=0;
  while(i<ELEMENTS) {
    digitalWrite(symbolpins[i], LOW);
    i++;
  } 
  lasttime=millis();
}

void loop () {
  int l=0;
  int m=0;
  int o=0;

  if((millis()-lasttime)>=100) {
    DateTime now = RTC.now();
    while(m<CATHODES) {
      l=0;
      if(m==0) {
        o=(now.hour()/10);
      } else if (m==1) {
        o=(now.hour()%10);       
      } else if (m==2) {
        o=(now.minute()/10);        
      } else if (m==3) {
        o=(now.minute()%10);           
      } else if (m==4) {
        secondbits[0]=(now.second()>>5)&(0x01);
        secondbits[1]=(now.second()>>4)&(0x01);
        secondbits[2]=(now.second()>>3)&(0x01);
        secondbits[3]=(now.second()>>2)&(0x01);
        secondbits[4]=1;
        secondbits[5]=(now.second()>>1)&(0x01);
        secondbits[6]=(now.second())&(0x01);
      }
      while(l<ELEMENTS) {
        if(m<4) {
          symboldata[m][l] = characterdata[o][l];
        } else {
          symboldata[m][l] = secondbits[l];
        }
        l++;
      }
      m++;
    }
    m=0;
    lasttime=millis();
  } else {
    drawscreen();  
  }
}

void drawscreen(void) {
  int i = 0;
  int j = 0;
  int k = 0;
  int p;
  while (i<CATHODES) {
    j=0;
    k=0;
    p=0;
    while(p<CATHODES) {
      pinMode(cathodepins[p], INPUT);
      p++;
    }
    while(j<ELEMENTS) {
      digitalWrite(symbolpins[j],symboldata[i][j]);
      j++;
    }
    while(k<CATHODES) {
      if(i==k) {
        pinMode(cathodepins[k],OUTPUT);
        digitalWrite(cathodepins[k],LOW);
      } else {
        pinMode(cathodepins[k],INPUT);
      }
      k++;
    }
    delay(2);
    i++;  
  }
  p=0;
  while(p<CATHODES) {
    pinMode(cathodepins[p], INPUT);
    p++;
  }
}

Of course, there are some intricacies – due to the way I wanted to avoid the non-standard pin-spacing of the Uno – I opted to use a Mega 1280 clone I had lying around (a DFRobot one, no less).

I had the display plug into the far row of the double-row of connectors, hence the unusual pin numbering – odd numbered pins. The display itself only had 4 seven segment displays – enough for hours and minutes. I decided to use the 7 remaining symbols as binary digit representations of the seconds digit (2^6 is 64), with the : symbol remaining permanently lit.

I also opted to have the DS1307 (TinyRTC with LIR2032 rechargeable coin cell) plug in directly to the header, so the power supply to the DS1307 comes from pin 18 and 19.

The code could be sped up by using direct port level access to do the writes, however, that would mean the code would require more adaptation to be used on different Arduinos.

But hey – it works. And it looks good! It recycles an LED module that would have otherwise been thrown out – and I get to stretch my fingers with some coding.

Of course, you don’t need to use a Mega for this – any Arduino is powerful enough. It just means a little more work negotiating those non-standard pins.

About lui_gough

I’m a bit of a nut for electronics, computing, photography, radio, satellite and other technical hobbies. Click for more about me!

This entry was posted in Computing, Electronics and tagged , . Bookmark the permalink.

2 Responses to Project: Arduino Clock with DVD Player LED Display

  1. Pingback: Review: Unbranded 30000mAh 2 Port USB Power Bank | Gough's Tech Zone

  2. marci2004 says:

    How can i do it with Raspberry Pi 3?

Error: Comment is Missing!