Hi,
I´m trying to build a digital clock, using a DS1307 chip and 6 pcs of 7-segment displays to show seconds, minutes and hours. The displays are connected to my arduino via 2pcs of 74HC595. One of the shiftregister handles the common cathode at the displays, the other one handles the segments at the displays. The code to start the DS1307 chip have I found in the forum and is working fine.
:-/My problem is that when the value of seconds, minutes or hours comes up to 10 or more, does the displays flip out totally. I want to separate the lower four bits and the upper bits in each byte (second, minute and hour). I think that bitmask is the correct way of doing this, but I can´t get it running.
Can someone guide me to get this work, because I haven´t found anything helpful about bitmask, that I understand????
Another issue, is my 10-hour display is brighter than the rest. Probably because this one is the last in the loop and is light up longer, has someone any good idea??
Here is the code:
// ******************************** Code that someone else has done *******************
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
// 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) );
}
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307
(
byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year // 0-99
)
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307
(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
// ******************************** Code for shiftout numbers at displays *******************
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
byte Number1S;
byte Number10S;
byte Number1M;
byte Number10M;
byte Number1h;
byte Number10h;
byte numberArray[10];
// ******************************** Code that someone else has done *******************
void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 0;
minute = 2;
hour = 9;
dayOfWeek = 6;
dayOfMonth = 1;
month = 5;
year = 10;
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
// ******************************** Code for shiftout numbers at displays *******************
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
numberArray[0] = 63; //Value to light up segments showing "0"
numberArray[1] = 6; //Value to light up segments showing "1"
numberArray[2] = 91; //Value to light up segments showing "2"
numberArray[3] = 79; //Value to light up segments showing "3"
numberArray[4] = 102; //Value to light up segments showing "4"
numberArray[5] = 109; //Value to light up segments showing "5"
numberArray[6] = 125; //Value to light up segments showing "6"
numberArray[7] = 7; //Value to light up segments showing "7"
numberArray[8] = 127; //Value to light up segments showing "8"
numberArray[9] = 111; //Value to light up segments showing "9"
}
void loop()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// ******************************** Code for shiftout numbers at displays *******************
// Show numbers at 1S display
Number1S = numberArray[second];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 1);
// "1" is the value to show the number at "1 second display"
shiftOut(dataPin, clockPin, MSBFIRST, Number1S);
//Send out value for 1 second digit
digitalWrite(latchPin, HIGH);
//delay(20);
// Show numbers at 10S display
Number10S = numberArray[second/10];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 2);
// "2" is the value to show the number at "10 second display"
shiftOut(dataPin, clockPin, MSBFIRST, Number10S);
//Send out value for 10 second digit
digitalWrite(latchPin, HIGH);
//delay(20);
// Show numbers at 1M display
Number1M = numberArray[minute];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 4);
// "4" is the value to show the number at "1 Minute display"
shiftOut(dataPin, clockPin, MSBFIRST, Number1M);
//Send out value for 1 minute digit
digitalWrite(latchPin, HIGH);
//delay(20);
// Show numbers at 10M display
Number10M = numberArray[minute/10];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 8);
// "8" is the value to show the number at "10 Minute display"
shiftOut(dataPin, clockPin, MSBFIRST, Number10M);
//Send out value for 10 minute digit
digitalWrite(latchPin, HIGH);
//delay(20);
// Show numbers at 1h display
Number1h = numberArray[hour];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 16);
// "16" is the value to show the number at "1 hour display"
shiftOut(dataPin, clockPin, MSBFIRST, Number1h);
//Send out value for 1 hour digit
digitalWrite(latchPin, HIGH);
//delay(20);
// Show numbers at 10h display
Number10h = numberArray[hour/10];
//ground latchPin and hold low for as long as transmitting
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 32);
// "32" is the value to show the number at "10 hour display"
shiftOut(dataPin, clockPin, MSBFIRST, Number10h);
//Send out value for 10 hour digit
digitalWrite(latchPin, HIGH);
//delay(20);
}