need help for a menu to setup Clock Modul DS1307

Hi,

I have problems to program a menu for setup a clock for my project.
The project is a LED Aquarium lamp and the code below is running very good.
Unfortunately the clock shows after some days the wrong time (the module is faster than the real time).
Now what I need is the code for a menu to set the clock.

I use a Arduino Mega 2560 with SainSmart 1602 (16x2) and a RTC Clock Modul DS1307 and arduino 1.0.
The SainSmart 1602 has 6 buttons http://www.sainsmart.com/sainsmart-1602-lcd-keypad-shield-for-arduino-duemilanove-uno-mega2560-mega1280.html.

Can anyone help me with the code for a menu?
Is it also possible to have a additional menu to set the time for dimming? (it is not needful but nice to have)

Here is the actual code from the project and its function very well, except the faster running clock module :slight_smile:

#include <Wire.h>
#include <LiquidCrystal.h>
#define DS1307_ADDRESS 0x68  
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

const int Blue1Pin = 2;
const int Blue2Pin = 3;
const int White3Pin = 11;
const int White4Pin = 12;
const int Night1Pin = 13;
const unsigned long HOUR = 60 * 60;
const unsigned long MINUTE = 60;
const int TARGET_BRIGHTNESS = (255 * 3) / 4;  

void setup()
{  
lcd.begin(16, 2);

Wire.begin();
}

byte bcdToDec(byte val)  {
return ( (val/16*10) + (val%16) );
}

void loop()
{
lcd.clear(); 
lcd.setCursor(0,0);
lcd.print("<");
lcd.setCursor(4,0);

Wire.beginTransmission(DS1307_ADDRESS);
Wire.write((byte)0);
Wire.endTransmission();

Wire.requestFrom(DS1307_ADDRESS, 3);

int RTCSecond = bcdToDec(Wire.read());
int RTCMinute = bcdToDec(Wire.read());
int RTCHour = bcdToDec(Wire.read() & 0b111111); 

if(RTCHour < 10) {
lcd.print("0");
}
lcd.print(RTCHour);
lcd.print(":");
if(RTCMinute < 10) {
lcd.print("0");
}
lcd.print(RTCMinute);
lcd.print(":");
if(RTCSecond < 10) {
lcd.print("0");
}
lcd.print(RTCSecond);
lcd.setCursor(13,0);
lcd.print(">");
unsigned long time = RTCHour * HOUR + RTCMinute * MINUTE + RTCSecond;  // Time in seconds

analogWrite(Blue1Pin,   brightness(time, 7*HOUR,                 19*HOUR));
analogWrite(Blue2Pin,   brightness(time, 7*HOUR+30*MINUTE,                 19*HOUR+30*MINUTE));
analogWrite(White3Pin, brightness(time, 8*HOUR+30*MINUTE,                 16*HOUR+30*MINUTE));
analogWrite(White4Pin, brightness(time, 9*HOUR+30*MINUTE,                 17*HOUR+30*MINUTE));
analogWrite(Night1Pin, TARGET_BRIGHTNESS);

lcd.setCursor(0,1); 
if(((brightness(time,  8*HOUR+30*MINUTE,                 16*HOUR+30*MINUTE))*100/255) < 10) {
lcd.print("0");
}
lcd.print((brightness(time,  8*HOUR+30*MINUTE,                 16*HOUR+30*MINUTE))*100/255);
lcd.print("%");

lcd.setCursor(4,1);
if(((brightness(time, 7*HOUR,                 19*HOUR))*100/255) < 10) {
lcd.print("0");
}
lcd.print((brightness(time, 7*HOUR,                 19*HOUR))*100/255);
lcd.print("%");

lcd.setCursor(8,1);
if(((brightness(time, 7*HOUR+30*MINUTE,                 19*HOUR+30*MINUTE))*100/255) < 10) {
lcd.print("0");
}
lcd.print((brightness(time, 7*HOUR+30*MINUTE,                 19*HOUR+30*MINUTE))*100/255);
lcd.print("%");

lcd.setCursor(12,1);
if(((brightness(time, 9*HOUR+30*MINUTE,                 17*HOUR+30*MINUTE))*100/255) < 10) {
lcd.print("0");
}
lcd.print((brightness(time, 9*HOUR+30*MINUTE,                 17*HOUR+30*MINUTE))*100/255);
lcd.print("%");

delay(1000);
}

byte brightness(unsigned long time, unsigned long fadeUpStart, unsigned long fadeDownStart)
{
if (time >= fadeUpStart + HOUR  && time <= fadeDownStart)
return TARGET_BRIGHTNESS;

if (time >= fadeUpStart && time <= fadeUpStart + HOUR)
{
unsigned long seconds = time - fadeUpStart;   
return TARGET_BRIGHTNESS * seconds / (HOUR); 
}

if (time >= fadeDownStart && time <= fadeDownStart + HOUR)  
{
unsigned long seconds = (fadeDownStart + (HOUR)) - time;   
return TARGET_BRIGHTNESS * seconds / (HOUR);  
}

return 0;
}

Here is a relevant post about your LCD shield:

http://arduino.cc/forum/index.php/topic,96747.0.html

You have exactly one example code from the seller. Pretty much what you get is what you paid for. I encourage you study it. I have a library for menus and things but it's not written for this shield. Some modification is needed but I don't have this shield to modify my library with.

Hi,

thank you for the reply.
It would be nice if you post or send me the library for menus and things, so I have a reference point to implement and change the code. (i hope :wink: )

regards

I have attached some test code I wrote to adjust date and time on a DS3231 using a rotary encoder with integral push button. I have altered the code to use buttons to simulate the encoder turning so it should work okay using 3 buttons now. The DS3231 is similar to the DS1307 so the attached library might work without alteration, if not then this is the library to use GitHub - davidhbrown/RealTimeClockDS1307: Yet another DS1307 Real-Time Clock library for Arduino (obsolete) As I don't have a LCD I will leave it to you to replace the Serial.print stuff with LCD relevant stuff.

A tip to improve your DS1307 accuracy is to apply a time offset every hour. Say your gaining 12 seconds per day this equates to half a second per hour. The below code snippet will retard the RTC by 500 milliseconds per hour. Just work out how much the clock is gaining per hour and adjust delayComp as needed.

const long delayComp = 500;                 // half second per hour drift

    static boolean driftApplied = false;
    RTC.readClock();
    int m=RTC.getMinutes();

    // RTC Drift compensation
    if(m == 0)                              //Is it top of hour
    {
        if(!driftApplied){                  //Have I already done drift compensation
            delay(delayComp);               //Apply delay
            RTC.setClock();                 //Set clock
            driftApplied=true;              //Signal drift applied
        }
    }
    else {                                  //Not top of hour
        driftApplied = false;               //Reset drift applied
    }
    // Do rest of clock code here

ClockSet.ino (7.18 KB)

RealTimeClockDS3231.cpp (11 KB)

RealTimeClockDS3231.h (4.4 KB)

Thank you, this is a good idea with the offset. I will measure the clock change and change the millis in the code.
The rest of the code I will check later @home.

Thank you very much, this can help me.

I have a working alarm clock sample code among other code.