Hello,
I have an Arduino uno, DS3234 RTC and 8pc of 8digit led. But It gets wrong time and date (randomly?) for example it's 2013/12/01 now. I don't know if the rtc is bad or something in the code? Any idea?
#include <SPI.h>
#include <LedControl.h>
#include <avr/interrupt.h>
const byte DIN = 6; // Pin 1 on the Max72xx
const byte CLK = 8; // Pin 13 on the Max72xx
const byte LOADCS = 7; // Pin 12 on the Max72xx
const byte cs=10; //chip select for RTC
byte sleep = 0; // sleep flag
byte sticks = 2; // pin for the clapper
byte run = 0;
byte years=0;
byte months=0;
byte days=0;
byte error=0; // error flag to trigger error code in boot
volatile byte hSecond=0; // these are our time variables
volatile byte seconds=0;
volatile byte minutes=0;
volatile byte hours=0;
LedControl lc=LedControl(DIN,CLK,LOADCS,1); // DIN, CLK, Load/CS, 1 = only one chip MAX chip attached
byte chip_id = 0; // This is not strictly reqd, but if using more than one display this will be needed
byte row = 0; // Set the starting position
byte ledBrightness = 10; // range is 0-15. 0=lowest, 15 = full power
volatile unsigned char tick_flag = 0;
volatile unsigned char sync_flag = 0;
volatile unsigned char date_flag = 0;
void setup() {
pinMode(DIN, OUTPUT); // once only, lets make the 7219 pins outputs
pinMode(CLK, OUTPUT);
pinMode(LOADCS, OUTPUT);
pinMode(sticks, INPUT);
pinMode(cs,OUTPUT); // chip select for RTC
for(int index=0;index<lc.getDeviceCount();index++) // take pins out of power save mode
{
lc.shutdown(index,false);
}
lc.setIntensity(0,ledBrightness);
RTC_init();
//SetTimeDate(9,03,14,22,37,30); //day(1-31), month(1-12), year(0-99), hour(0-23), minute(0-59), second(0-59) only if needed
ReadTimeDate(); // load current RTC time into time variables
if (hours == 0) {
error=1;
}
boot();
ReadTimeDate();
//clearSPI();
Serial.print("muxik");
noInterrupts();
//This sets Timer1 to interrupt every 1/30 of a second, assunming a clock of 16MHz.
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; //initialize counter value to 0
// set compare match register to desired timer count: 100hz
OCR1A = 8333; //prescaler at 32 //19999;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS11 bits for 8 prescaler:
TCCR1B |= (1 << CS11)|(1 << CS10);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);//|(1 << OCIE1B);
interrupts();
}
ISR(TIMER1_COMPA_vect) // This code executes at each interrupt of Timer1
{
hSecond++;
tick_flag = 1; // signal loop that the led should be updated
if (hSecond < 30) return;
seconds++;
hSecond = 0;
if (seconds < 60) return;
minutes++;
seconds = 0;
if (minutes < 60) return;
hours++;
sync_flag = 1;
minutes = 0;
if (hours == 24) {
hours = 0;
}
}
void loop()
{
if(digitalRead(sticks)==LOW) {
date_flag=1;
delay(500);
//lc.setIntensity(0,3);
lc.clearDisplay(chip_id);
}
else {
date_flag=0;
run=0;
lc.setIntensity(0,ledBrightness);
}
if(tick_flag&&sleep==0&&date_flag==0) {
led_print(hours, 6); // Print the hour
led_print(minutes, 4); // Print the minutes
led_print(seconds, 2); // Print the seconds
led_print(hSecond, 0); //Print the hundreths of seconds
tick_flag = 0;
}
if(date_flag==1&&run==0) {
date();
run=1;
//lc.clearDisplay(chip_id);
}
if(hours<06 && hours>01) { //sets a sleep flag so the clock display is off late at night to save battery
sleep=1;
//lc.setIntensity(0,3);
lc.clearDisplay(chip_id);
}
else {
sleep=0;
//lc.setIntensity(0,ledBrightness);
}
if(sync_flag) {
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
ReadTimeDate();
//clearSPI();
sync_flag = 0;
}
}
//=====================================
int RTC_init(){
// start the SPI library:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3); // both mode 1 & 3 should work
//set control register
digitalWrite(cs, LOW);
SPI.transfer(0x8E);
SPI.transfer(0x60); //60= disable Osciallator and Battery SQ wave @1hz, temp compensation, Alarms disabled
digitalWrite(cs, HIGH);
delay(10);
}
//=====================================
void clearSPI() {
SPI.begin();
SPI.end();
}
//=====================================
String ReadTimeDate(){
String temp;
int TimeDate [7]; //second,minute,hour,null,day,month,year
for(int i=0; i<=6;i++){
if(i==3)
i++;
digitalWrite(cs, LOW);
SPI.transfer(i+0x00);
unsigned int n = SPI.transfer(0x00);
digitalWrite(cs, HIGH);
int a=n & B00001111;
if(i==2){
int b=(n & B00110000)>>4; //24 hour mode
if(b==B00000010)
b=20;
else if(b==B00000001)
b=10;
TimeDate[i]=a+b;
}
else if(i==4){
int b=(n & B00110000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==5){
int b=(n & B00010000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==6){
int b=(n & B11110000)>>4;
TimeDate[i]=a+b*10;
}
else{
int b=(n & B01110000)>>4;
TimeDate[i]=a+b*10;
}
}
hours = TimeDate[2];
minutes = TimeDate[1];
seconds = TimeDate[0];
years = TimeDate[6];
months = TimeDate[5];
days = TimeDate[4];
return(temp);
}
//=====================================
int SetTimeDate(int d, int mo, int y, int h, int mi, int s){
int TimeDate [7]={s,mi,h,0,d,mo,y};
for(int i=0; i<=6;i++){
if(i==3)
i++;
int b= TimeDate[i]/10;
int a= TimeDate[i]-b*10;
if(i==2){
if (b==2)
b=B00000010;
else if (b==1)
b=B00000001;
}
TimeDate[i]= a+(b<<4);
digitalWrite(cs, LOW);
SPI.transfer(i+0x80);
SPI.transfer(TimeDate[i]);
digitalWrite(cs, HIGH);
}
}
void led_print(int time_int, int pos){ // Ask for the number and the position to print
byte ones, tens; // A couple of variables to fill with digits
ones=time_int%10; // %10 divides by ten and extracts the remainder
tens=time_int/10%10; // Handy for splitting the digits in two for printing
lc.setDigit(chip_id, pos, (byte) ones, true); // These two lines send the digits to the Max7221
lc.setDigit(chip_id, pos+1, (byte) tens, false); // one by one
}
void date() {
digitalWrite(LOADCS, HIGH);
lc.clearDisplay(chip_id);
led_print(days, 6); // Print the day
led_print(months, 4); // Print the month
lc.setChar(chip_id, 3, 2, false); // "2"
lc.setChar(chip_id, 2, 0, false); // "0"
led_print(years, 0); // Print the year
digitalWrite(LOADCS, HIGH);
delay(500);
//lc.clearDisplay(chip_id);
//detachInterrupt(0);
}
void boot() {
ledSync();
ledBat();
ledDash();
if (error) {
ledSyncEr();
error=0;
}
delay(1000);
lc.clearDisplay(chip_id);
}
void ledSync() {
lc.clearDisplay(chip_id);
lc.setRow(chip_id, 6, 61); // "d"
lc.setRow(chip_id, 5, 13); // "c"
lc.setRow(chip_id, 4, 29); // "o"
lc.setRow(chip_id, 3, 61); // "d"
lc.setRow(chip_id, 2, 79); // "E"
lc.setChar(chip_id, 1, 3, true); // "3"
lc.setChar(chip_id, 0, 0, false); // "0"
delay(500);
}
void ledSyncEr() {
lc.clearDisplay(chip_id);
lc.setRow(chip_id, 7, 91); // "S or 5"
lc.setRow(chip_id, 6, 21); // "n"
lc.setRow(chip_id, 5, 13); // "c"
lc.setRow(chip_id, 3, 79); // "E"
lc.setRow(chip_id, 2, 5); // "r"
lc.setChar(chip_id, 1, 3, false); // "3"
lc.setChar(chip_id, 0, 0, false); // "0"
delay(500);
}
void ledBat() {
lc.clearDisplay(chip_id);
lc.setRow(chip_id, 6, 31); //"b"
lc.setRow(chip_id, 5, 119); //"A"
lc.setRow(chip_id, 4, 15); //"t"
lc.setChar(chip_id, 1, 7, true); // "7"
lc.setChar(chip_id, 0, 0, false); // "0"
delay(500);
}
void ledDash() {
lc.clearDisplay(chip_id);
delay(500);
for (int r=0; r<=7; r++){
lc.setChar(chip_id, r, '-', false); // "-"
}
delay(300);
}
