Project clock

 

2014-07-13 15.57.47-1

 

This is the result of the project.
You see four elements:

  • left the Arduino Nano
  • back right the Real Time Clock module
  • front right the 8×7 Segment Display and some switches to control the display

 

Arduino Nano

I use the Arduino Nano V3.
This Arduino Nano is similar to the Arduino Uno. Both use an ATmega328. (Do not confuse the Nano with a Nano V2.x – this type use an ATmega168). The source code runs on both systems. There are no difference.

If you want to use the Arduino Uno – no problem! You can use the same Pins. There is nothing to do.

 

Annotations:

The 8×7 Segment Display is described in the arduino section. Look there, if you need additional informations.
I will upload the description of the Real Time Clock in the next few days.

Some words about the switches.
Normally you don’t need the interaction with the clock. The RTC has an battery to store the current date and time informations. But what is, if you want to correct the seconds or the minutes? So I decide to integrate some switches to communicate with the clock.

You see, I use four switches. But in the source code I use only three switches. This is correct. There was a mistake with the glue! The left switch is without function. There was to much glue and so I can’t use this switch. Unfortunately.

Now, I have the following actions with three switches:

Displaying the time:
– right switch: set the seconds back to zero
– middle switch: increase the minutes
– left switch: increase the hours

Displaying the date:
– rigth switch: increase the year
– middle switch: increase the month
– left switch: increase the day

Pressing middle and right switch at the same time – change between date and time.

 

 

Some Details:

2014-07-13 14.41.14   2014-06-22 14.27.26   2014-03-05 19.00.41-1   2014-07-13 18.24.59   2014-07-13 18.24.45   Nano   Project_clock_2

 

The code:

#include "Wire.h"

const int clock = 7; //SCK
const int latch = 5; //RCK
const int data = 6; //DIO

// values are 0 ,1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , nothing , -
byte value[] ={B11000000,
               B11111001, 
               B10100100, 
               B10110000, 
               B10011001, 
               B10010010, 
               B10000010, 
               B11111000, 
               B10000000, 
               B10010000,
               B11111111, 
               B10111111};

// values are 0 ,1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , nothing , -
byte valuedot[] ={B01000000,
                  B01111001, 
                  B00100100, 
                  B00110000, 
                  B00011001, 
                  B00010010, 
                  B00000010, 
                  B01111000, 
                  B00000000, 
                  B00010000,
                  B01111111, 
                  B00111111};

// digits count from left to right --- B00000001 = left digit, B10000000 = right digit
byte digit[] ={B00000001,B00000010,B00000100,B00001000,B00010000,B00100000,B01000000,B10000000};
byte ii = 0;

byte v0, v1,v2,v3,v4,v5,v6,v7;
byte vvalue = value[0];

int state = HIGH; // to safe the state to display
// low = display date
// HIGH = display time

int sw1=12;  // to inc/dec day or reset seconds
int sw2=10;  // to in/dec month or minutes
int sw3=11;  // to inc/dec year or hours

void setup() {
  Wire.begin();
  //Serial.begin(9600);
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(data, OUTPUT);
  pinMode(sw1,INPUT);
  pinMode(sw2,INPUT);
  pinMode(sw3,INPUT);

  cli();//stop interrupts
  //set timer0 interrupt at 980Hz
  TCCR0A = 0;// set entire TCCR0A register to 0
  TCCR0B = 0;// same for TCCR0B
  TCNT0 = 0;//initialize counter value to 0
  OCR0A = 255;//(must be <256) --> 16000000 / (prescaler*255) = 980 Hz
  TCCR0A |= (1 << WGM01);
  TCCR0B |= (1 << CS01) | (1 << CS00); //prescaler = 64
  TIMSK0 |= (1 << OCIE0A);
  sei(); //allow interrupts

  v0=v1=v2=v3=v4=v5=v6=v7=10;
  v2=v5=11;
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
  return ( (val/16*10) + (val%16) );
}

ISR(TIMER0_COMPA_vect){
  ii++;
  if (ii==8) ii=0;

  if (ii==0) { vvalue = v0; }
  else if (ii==1) { vvalue = v1; }
  else if (ii==2) { vvalue = v2; }
  else if (ii==3) { vvalue = v3; }
  else if (ii==4) { vvalue = v4; }
  else if (ii==5) { vvalue = v5; }
  else if (ii==6) { vvalue = v6; }
  else if (ii==7) { vvalue = v7; }

  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,B11111111);
  shiftOut(data,clock,MSBFIRST,B11111111);
  digitalWrite(latch,HIGH);

  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,digit[ii]);
  if (state==LOW && (ii==1 || ii==3))
    shiftOut(data,clock,MSBFIRST,valuedot[vvalue]);
  else
    shiftOut(data,clock,MSBFIRST,value[vvalue]);
  digitalWrite(latch,HIGH);
}

int s,m,hh,d,DD,MM,YY,h;

void clock_data_read() {
  Wire.beginTransmission(0x68);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 8);
  s = bcdToDec(Wire.read());   // Seconds
  m = bcdToDec(Wire.read());   //Minutes
  hh = bcdToDec(Wire.read());  //Hours
  d = bcdToDec(Wire.read());   //Day of Week
  DD = bcdToDec(Wire.read());  //Day
  MM = bcdToDec(Wire.read());  //Month
  YY = bcdToDec(Wire.read());  //Year
  h = bcdToDec(Wire.read());   //Square Wave -- not necessary

  if (state) {
    if (s > 9) {
      v6=int(s/10);
      v7=(s%10); } else {
      v6 = 0;
      v7 = s; }

    if (m > 9) {
      v3=int(m/10);
      v4=(m%10); } else {
      v3 = 0;
      v4 = m; }

    if (hh > 9) {
      v0=int(hh/10);
      v1=(hh%10); } else {
      v0 = 0;
      v1 = hh; }

    v5 = 11;
    v2 = 11;
  } else {
    if (DD > 9) {
      v0 = int(DD/10);
      v1 = (DD%10); } else {
      v0 = 0;
      v1 = DD; }
    if (MM > 9) {
      v2 = int(MM/10);
      v3 = (MM%10); } else {
      v2 = 0;
      v3 = MM; }

    v7=YY%10;
    v6=int(YY/10);
    v5=0;
    v4=2;
  }
}

void wire_transfer() {
  Wire.beginTransmission(0x68);
  Wire.write(0);
  Wire.write(decToBcd(s));
  Wire.write(decToBcd(m));
  Wire.write(decToBcd(hh));
  Wire.write(decToBcd(d));
  Wire.write(decToBcd(DD));
  Wire.write(decToBcd(MM));
  Wire.write(decToBcd(YY));
  Wire.write(0);
  Wire.endTransmission();
}

void reset_seconds() {
  s=0;
  wire_transfer();
}

void inc_minutes() {
  m++;
  if (m>=60) m=0;
  wire_transfer();
}

void inc_hours() {
  hh++;
  if (hh>=24) hh=0;
  wire_transfer();
}

void inc_days() {
  DD++;
  if (DD>=32) DD=0;
  wire_transfer();
}

void inc_month() {
  MM++;
  if (MM>=13) MM=0;
  wire_transfer();
}

void inc_year() {
  YY++;
  if (YY>=50) YY=10;
  wire_transfer();
}

void loop() {
  clock_data_read();
  delay(200);

  int sec_sw = digitalRead(sw3);
  int min_sw = digitalRead(sw2);

  if (min_sw && sec_sw) state = !state;

  if (state && sec_sw && !min_sw) reset_seconds();
  if (!state && sec_sw && !min_sw) inc_year();

  if (state && min_sw && !sec_sw) inc_minutes();
  if (!state && min_sw && !sec_sw) inc_month();

  int hours_sw = digitalRead(sw1);
  if (state && hours_sw) inc_hours();
  if (!state && hours_sw) inc_days();

}

 

 

Advertisements

One thought on “Project clock

  1. thanks for all this! It is really amazing, I don’t know if you can help me using this 8x7display and a 4×4 keypad, with interruption or not, please answer me, thanks in advance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s