Introduction: Berlin Clock

About: Started electronics as a hobby in the seventies, studied it in late seventies, begin 80's, bought my first arduino last november. Love Instructables!

The Berlin Clock, BerlinUhr or Mengenlehreuhr, was probably the very first digital clock.

It has been there since 1975...

Lots of info you can find here: https://en.wikipedia.org/wiki/Mengenlehreuhr

How is it made, how do you tell the time?

In short, there are fous rows of lights. The upper row gives the hours x 5, the next the "single hours" from 1 to 4. The third row gives us the "minutes x5", the bottom row the minutes.

On the picture shown, (actually one lamp is broken...) the time is: 2x5 hours plus 3 hours + 6x5 minutes + 2minutes.

So it is 13 :32. OK, I suppose we Europeans are more used to tell time in 24h. format, so does the clock.

The biggest light on top blinks every second.

I thought this colock might be some fun to make in Arduino.

Step 1: Some Electronics

What do we need for this project?

First of all, (of course), our Arduino.

I use one of my Uno's that are lying everywhere near my computer.

Since we talk about a clock, we might use a RTC. I used a cheap one with a DS 1307.

For the "display", we need some LED's. I used 13 yellow ones, 5mm, and 11 Reds. (I actually used RGB's for the reds, as I had not enough reds lying around...)

A breadboard, a print-board with only holes and "solder-islands". I just used a part of the so-called "Euro card-format".

2 resistors I used. One of 220Ohms (the seconds LED), and another of 68K.

And one extra IC: MAX7219.

The MAX is an 8-digit LED display driver. Many of us know it as it is used in LED matrices as well.

For the easy of it, I also used the "LedControl" Arduino library. If you still don't have it, you can download it from here:

https://github.com/wayoda/LedControl

Step 2: Setting It Up.

You can find a very nice data sheet for that MAX 7219 at this place:

https://www.sparkfun.com/datasheets/Components/Gen...

I won't go in to that data sheet any further, but it's worth using it, it's a kind of "fun" IC.

A jump to the Arduino.

On that scheme you see a very simple construction: I use SDA and SCL to use the clock (A 1307 breakout), and four more outputs: DataIn, Clock and Chipselect that go to the MAX 7219, and OUT 13 that we use for our blinking "seconds"LED.

The most things do happen in the Arduino: it reads the clock, converts it to the different kinds of output, and then sends the data to the 7219.

When you read the code, you'll see I just use my own language, Dutch, for that. For example: the int "vijfuren" I use is the variable that counts "Five-hours", same for the "vijfminuten" and "vijfminuten1": those give the "Five-minutes" output.

In the sketch I also use the year, month, day of month and weekday, in this particularly sketch I don't need them, but maybe later, I could add a calendar to it.

In the Fritzing(c) layout, the IC is not wired: I did that for the ease of it, as it has lots of outputs.

Lets sum them up:

pin 4 and 9 are connected to the GND,

19 is VCC

18, ISet, is connected to VCC with a resistor: this one limits the current that goes to the outputs. First, I tried with a 20K resistor, but after 10minutes or so, everything went dark... Now, with a 686K resistor, the clock is still running (after more than 24hours). But there is a difference between the brightness of the red and yellows, I think it's due to the fact that the red ones are in fact RGB Leds. I have to sort that out...

pin 1 is DataIn, this one comes from the Arduino, pin 12

pin 12 is Load, coming from Arduino pin 10

pin 13 is Clk, coming from Arduino 11.

So far for the inputs of the 7219.

Taking a look at the outputs:

The 7219 has the possibility to power 8 7seg displays.

These outputs, DIG 0 to DIG 4 are used here to drive the "lines" of the LED's: since the "five-minutes"-line has 11 LED's in it, I use DIG 1 and DIG 2 to drive them.

The other outputs: Segments A to G an DP (of a normal 7Seg display).

I this case (with LedControl), I send Binary Words to them (byteform, like B01010100).

And there I made a mistake. Some logic told me that SEG A would be the MSB, B teh second most significant bit, and so on, until DP, which I thought would be the least significant bit (LSB). Wrong... For one reason or another, the makers of the IC thought that DP would be the MSB. Can't see the logic of that...

That made me change my coding, as I already soldered the LED's...

Step 3: The LED's

On this schematic, you see how the LED's are connected together. I only drew the first three, the others go the same way.

The seconds LED is connected straight to Pin 13.

The picture shows "how it works". It's 17:47 o'clock...

The little film was shot a little before, on 17:45, changing to 17:46.

Ok, the bottom row is not that clear, it's on a breadboard. I hope you believe me that it really works. (it does!).

Oh, one more step to come...

Step 4: Step "last", the Code.


#include <LedControl.h>
#include <Wire.h>

const int DS1307 = 0x68;

// A5 =SCL, A4 =SDA

const char* days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

const char* months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

byte second = 0; byte minute = 0; byte hour = 0; byte weekday = 0;

byte monthday = 0;

byte month = 0;

byte year = 0;

byte lastMinute = 0;

byte lastSecond =0;

int Led =13;

byte nul = B0000000;

byte een =B01000000;

byte twee = B01100000;

byte drie = B01110000;

byte vier = B01111000;

byte vijf = B01111100;

byte zes = B01111110;

byte zeven = B01111111;

byte acht = B11111111;

byte negen = B01000000;

byte tien = B01100000;

byte elf = B01110000; i

nt a=0; int b =0; int c =0;

int vijfMinTwee=0;

int uitgang = LOW;

/*pin 12 is connected to the DataIn pin 11 is connected to the CLK pin 10 is connected to LOAD */

LedControl lc= LedControl(12,11,10,1);

unsigned long delaytime=100;

void setup() {

Wire.begin(); Serial.begin(9600);

pinMode (Led, OUTPUT);

lc.shutdown(0,false);

/* Set the brightness to a medium values */

lc.setIntensity(0,8);

/* and clear the display */

lc.clearDisplay(0);

}

void loop() {

readTime();

digitalWrite(Led,uitgang);

if (second != lastSecond){

if (uitgang == LOW) uitgang =HIGH;

else uitgang =LOW;

digitalWrite (Led, uitgang);

lastSecond = second;

}

if (minute != lastMinute) { printTime(); lastMinute = minute;

}

}

byte bcdToDec(byte val) {

return ((val/16*10) + (val%16));

}

void printTime() {

char buffer[3];

long minuten = minute;

long uren = hour;

int vijfmin =minuten /5;

int eenminuut = minuten -(vijfmin * 5);

int vijfuren = uren/5;

int eenuren = uren - (vijfuren *5);

a = vijfmin;

digitaal();

vijfmin = b;

vijfMinTwee = c;

a = eenminuut;

digitaal();

eenminuut = b;

a= vijfuren;

digitaal();

vijfuren = b;

a = eenuren;

digitaal();

eenuren = b;

lc.setRow(0,4,vijfuren);

lc.setRow(0,3,eenuren);

lc.setRow(0,1,vijfmin);

lc.setRow(0,2,vijfMinTwee);

lc.setRow(0,0,eenminuut);

}

void readTime() {

Wire.beginTransmission(DS1307);

Wire.write(byte(0));

Wire.endTransmission();

Wire.requestFrom(DS1307, 7);

second = bcdToDec(Wire.read());

minute = bcdToDec(Wire.read());

hour = bcdToDec(Wire.read());

weekday = bcdToDec(Wire.read());

monthday = bcdToDec(Wire.read());

month = bcdToDec(Wire.read());

year = bcdToDec(Wire.read()); }

void digitaal(){

switch (a){

case 0:

b= nul; c= nul;

break;

case 1:

b = een; c= nul;

break;

case 2:

b = twee; c= nul;

break;

case 3:

b = drie; c= nul;

break;

case 4:

b = vier; c= nul;

break;

case 5:

b = vijf; c= nul;

break;

case 6:

b = zes; c= nul;

break;

case 7:

b = zeven; c= nul;

break;

case 8:

b = acht; c= nul;

break;

case 9:

b = acht; c = negen;

break;

case 10:

b= acht; c = tien;

break;

case 11:

b=acht; c = elf;

break;

}

}

Pretty straightforward, I believe.

Another benefit from this sketch: now you learn how to count in Dutch... From 0 to 11... ;-)

Hope you enjoy this!

Marc.