DS1307 adjusting time

I have managed to add couple of buttons to adjust time on DS1307.

Problem is that I can display adjusted time only, after adjustments are done time just keeps displaying same and it looks like the script is not pulling time from DS1307.

Can someone help with below script? I am very new at this. I think problem is that I am doing:

  1. #define DS1307 B1101000
    -and-
  2. RTC_DS1307 RTC;

I just don’t know how to separate (or combine) these 2.

#include <Wire.h>
#include <RTClib.h>

// I2C address
#define DS1307 B1101000

RTC_DS1307 RTC;



// pinout for the 7 segment display
// Starts top center, clock-wise, then
// center line, then dot
byte segment[] = {
  3, 2, 5, 6, 7, 8, 9, 4
};

byte second = 0, minute = 0, hour = 0;

int led1 = 3;
int led2 = 2;
int led3 = 5;
int led4 = 4;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int led8 = 9;



//************Button*****************//
int P1 = 11; // SET HOURS
int P2 = 12; // SET MINUTES

//************Variables**************//
int hourupg;
int minupg;
int menu = 0;


void updatetime();
void printtime();
void print7digit(byte number);
byte DECTOBCD(byte val);
byte BCDTODEC(byte val);

void setup() {
  byte i;
  Wire.begin();
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);

  for (i = 0; i < 8; i++) {
    pinMode(segment[i], OUTPUT);
    digitalWrite(segment[i], LOW);

    pinMode(P1, INPUT);
    pinMode(P2, INPUT);

    Wire.begin();
    RTC.begin();

    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    // RTC.adjust(DateTime(__DATE__, __TIME__)); //removing "//" to adjust the time
    // The default display shows the date and time
    int menu = 0;

  }
}


void loop() {
  updatetime();
  printtime();


  // check if you press the SET button and increase the menu index
  if (digitalRead(P1))
  {
    DisplaySetHour();
  }
  else if (digitalRead(P2))
  {
    DisplaySetMinute();
  }
  StoreAgg();
  delay(100);
  menu = 0;

}



// Pull current time off the DS1307
void updatetime() {
  Wire.beginTransmission(DS1307);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307, 3);
  // Don't actually use seconds value. Feel free to.
  second = BCDTODEC(Wire.read() & 0x7f);
  minute = BCDTODEC(Wire.read());
  hour   = BCDTODEC(Wire.read() & 0x3f);
}



void DisplaySetHour()
{
  // Hour setting
  DateTime now = RTC.now();
  if (digitalRead(P1) == HIGH)
  {
    if (hourupg == 23)
    {
      hourupg = 0;
    }
    else
    {
      hourupg = hourupg + 1;
    }
  }

  digitalWrite(led2, HIGH); // LETTER H FOR SETTING HOURS
  digitalWrite(led3, HIGH);
  digitalWrite(led7, HIGH);
  digitalWrite(led6, HIGH);
  digitalWrite(led8, HIGH);
  delay(500);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led7, LOW);
  digitalWrite(led6, LOW);
  digitalWrite(led8, LOW);
  delay(500);

}

void DisplaySetMinute()
{
  // Minute setting
  DateTime now = RTC.now();
  if (digitalRead(P2) == HIGH)
  {
    if (minupg == 59)
    {
      minupg = 0;
    }
    else
    {
      minupg = minupg + 1;
    }
  }

  digitalWrite(led1, HIGH); // LETTER F FOR SETTING MINUTES
  digitalWrite(led6, HIGH);
  digitalWrite(led7, HIGH);
  digitalWrite(led8, HIGH);
  delay(500);
  digitalWrite(led1, LOW);
  digitalWrite(led6, LOW);
  digitalWrite(led7, LOW);
  digitalWrite(led8, LOW);
  delay(500);

}



void StoreAgg()
{
  // Variable saving
  RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
  delay(200);
}


// Flash each digit of the time in turn on the 7 segment
void printtime() {
  byte j;
  // Convert from 24 hour to 12 hour mode
  // Should be done on the DS1307. I'm sorry.
  byte temphour = hour % 12;
  if (temphour == 0) {
    // Not zero based, not one based, but 12 based.
    temphour = 12;
  }

  // Only display highest digit if it's nonzero
  if (temphour > 9) {
    print7digit(temphour / 10);
    delay(500); // Repeated magic values in my code? Never!
    for (j = 0; j < 8; j++) {
      digitalWrite(segment[j], LOW);
    }
    delay(150);
  }
  print7digit(temphour % 10);
  // Light the dot on last hour digit
  digitalWrite(segment[7], HIGH);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(500);

  print7digit(minute / 10);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(150);
  print7digit(minute % 10);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(2000);
}

// Display a single digit on the 7 segment
void print7digit(byte number) {
  // Bitfield for digits 0-9
  const byte numtable[] = {
    B00111111,
    B00000110,
    B01011011,
    B01001111,
    B01100110,
    B01101101,
    B01111101,
    B00000111,
    B01111111,
    B01100111
  };
  byte litpins = numtable[number];
  byte i;
  for (i = 0; i < 8; i++) {
    digitalWrite(segment[i], (litpins >> i) & 1);
  }
}

byte DECTOBCD(byte val) {
  return ((val / 10) << 4) + (val % 10);
}
byte BCDTODEC(byte val) {
  return (val >> 4) * 10 + (val & 0xf);
}

Is this the same as your question here?

after adjustments are done time just keeps displaying same and it looks like the script is not pulling time from DS1307.

Every pass through loop() you call StoreAgg() and set the time to the same value. Why would you expect the DS1307 to give you anything different?

void StoreAgg()
{
  // Variable saving
  RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
  delay(200);
}

gfvalvo:
Is this the same as your question here?

No, could not solve that one.

cattledog:
Every pass through loop() you call StoreAgg() and set the time to the same value. Why would you expect the DS1307 to give you anything different?

void StoreAgg()

{
  // Variable saving
  RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
  delay(200);
}

so how do I make it not call it each time it loops but only when time is being adjusted?

so how do I make it not call it each time it loops but only when time is being adjusted?

Many people add another button to be pressed when the adjustment is completed and it triggers a save of the adjusted values. A more complex option would be to add a double press or long press of the hour/minute adjustment button to trigger the save of that value.

cattledog:
Many people add another button to be pressed when the adjustment is completed and it triggers a save of the adjusted values. A more complex option would be to add a double press or long press of the hour/minute adjustment button to trigger the save of that value.

I can easily add another button. How would I script it to trigger a save of the adjusted values?

And thank you for all the help so far.

How would I script it to trigger a save of the adjusted values?

Look at the state change example in the ide examples 02 Digital > StateChangeDetection

You will implement something like this

if (digitalRead() of a button indicates a change in state from not pressed to pressed)
{
//write data to RTC
}

You want to trigger the save from a state change of the button(not pressed to pressed), and not the state of the button(pressed), in order to only save once, and avoid multiple saves as long as the button is held pressed down.

cattledog:
Look at the state change example in the ide examples 02 Digital > StateChangeDetection

You will implement something like this

if (digitalRead() of a button indicates a change in state from not pressed to pressed)
{
//write data to RTC
}

You want to trigger the save from a state change of the button(not pressed to pressed), and not the state of the button(pressed), in order to only save once, and avoid multiple saves as long as the button is held pressed down.

Thank you for all the help cattledog, I added a 3rd button. Turns out I had wiring wrong for the buttons too. I am using only 2 connections on the buttons. Code is fixed and seems to be working... I can set hours, minutes and 3rd button to save.

If you see anything me doing dumb (i am very new to this) please comment.

code here

#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 RTC;

// I2C address
#define DS1307 B1101000

// pinout for the 7 segment display
// Starts top center, clock-wise, then
// center line, then dot
byte segment[] = {
  3, 2, 5, 6, 7, 8, 9, 4
};

byte second = 0, minute = 0, hour = 0;

int led1 = 3;
int led2 = 2;
int led3 = 5;
int led4 = 4;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int led8 = 9;

//************Variables**************//
int hourupg;
int minupg;
int menu = 0;

void updatetime();
void printtime();
void print7digit(byte number);
byte DECTOBCD(byte val);
byte BCDTODEC(byte val);

void setup() {
  byte i;
  Wire.begin();
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);

  for (i = 0; i < 8; i++) {
    pinMode(segment[i], OUTPUT);
    digitalWrite(segment[i], LOW);

    // my addon
    Wire.begin();
    RTC.begin();

    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    // RTC.adjust(DateTime(__DATE__, __TIME__)); //removing "//" to adjust the time
    // The default display shows the date and time
    int menu = 0;
  }
}


void loop() {
  updatetime();
  printtime();

  // check if you press the SET button and increase the menu index
  if (digitalRead(10) == LOW)
  {
    DisplaySetHour();
  }
  else if (digitalRead(11) == LOW)
  {
    DisplaySetMinute();
  }
  StoreAgg();
  delay(100);
  menu = 0;
}

// Pull current time off the DS1307
void updatetime() {
  Wire.beginTransmission(DS1307);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307, 3);
  // Don't actually use seconds value. Feel free to.
  second = BCDTODEC(Wire.read() & 0x7f);
  minute = BCDTODEC(Wire.read());
  hour   = BCDTODEC(Wire.read() & 0x3f);
}

void DisplaySetHour()
{
  // Hour setting
  DateTime now = RTC.now();
  if (digitalRead(10) == LOW)

  digitalWrite(led2, HIGH); // Display letter H to set up hour
  digitalWrite(led3, HIGH);
  digitalWrite(led7, HIGH);
  digitalWrite(led6, HIGH);
  digitalWrite(led8, HIGH);
  delay(500);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led7, LOW);
  digitalWrite(led6, LOW);
  digitalWrite(led8, LOW);
  delay(500);
  {
    if (hourupg == 23)
    {
      hourupg = 0;
    }
    else
    {
      hourupg = hourupg + 1;
      RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
      delay(100);
    }
  }
}

void DisplaySetMinute() {
  // Minute setting
  DateTime now = RTC.now();
  if (digitalRead(11) == LOW)

  digitalWrite(led1, HIGH); // Display letter F to setup minutes
  digitalWrite(led6, HIGH);
  digitalWrite(led7, HIGH);
  digitalWrite(led8, HIGH);
  delay(500);
  digitalWrite(led1, LOW);
  digitalWrite(led6, LOW);
  digitalWrite(led7, LOW);
  digitalWrite(led8, LOW);
  delay(500);
  delay(200);
  {
    if (minupg == 59)
    {
      minupg = 0;
    }
    else
    {
      minupg = minupg + 1;
      RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
    }
  }
}

void StoreAgg() {
  // Variable saving

  DateTime now = RTC.now();
  if (digitalRead(12) == LOW)  {
    RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));
    digitalWrite(led1, HIGH); // display letter E for END
    digitalWrite(led5, HIGH);
    digitalWrite(led6, HIGH);
    digitalWrite(led7, HIGH);
    digitalWrite(led8, HIGH);
    delay(500);
    digitalWrite(led1, LOW);
    digitalWrite(led5, LOW);
    digitalWrite(led6, LOW);
    digitalWrite(led7, LOW);
    digitalWrite(led8, LOW);
    delay(500);
  }
  else
  {
    // do nothing
  }
}


// Flash each digit of the time in turn on the 7 segment
void printtime() {
  byte j;
  // Convert from 24 hour to 12 hour mode
  // Should be done on the DS1307. I'm sorry.
  byte temphour = hour % 12;
  if (temphour == 0) {
    // Not zero based, not one based, but 12 based.
    temphour = 12;
  }

  // Only display highest digit if it's nonzero
  if (temphour > 9) {
    print7digit(temphour / 10);
    delay(500); // Repeated magic values in my code? Never!
    for (j = 0; j < 8; j++) {
      digitalWrite(segment[j], LOW);
    }
    delay(150);
  }
  print7digit(temphour % 10);
  // Light the dot on last hour digit
  digitalWrite(segment[7], HIGH);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(500);

  print7digit(minute / 10);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(150);
  print7digit(minute % 10);
  delay(500);
  for (j = 0; j < 8; j++) {
    digitalWrite(segment[j], LOW);
  }
  delay(2000);
}

// Display a single digit on the 7 segment
void print7digit(byte number) {
  // Bitfield for digits 0-9
  const byte numtable[] = {
    B00111111,
    B00000110,
    B01011011,
    B01001111,
    B01100110,
    B01101101,
    B01111101,
    B00000111,
    B01111111,
    B01100111
  };
  byte litpins = numtable[number];
  byte i;
  for (i = 0; i < 8; i++) {
    digitalWrite(segment[i], (litpins >> i) & 1);
  }
}

byte DECTOBCD(byte val) {
  return ((val / 10) << 4) + (val % 10);
}
byte BCDTODEC(byte val) {
  return (val >> 4) * 10 + (val & 0xf);
}

Code is fixed and seems to be working... I can set hours, minutes and 3rd button to save.If you see anything me doing dumb (i am very new to this) please comment.

This code to save the values to the rtc memory is repeated three places--the hour adjustment, the minute adjustment, and the save button press.

RTC.adjust(DateTime(19, 6, 6, hourupg, minupg, 0));

If you are going to use the save button, it only needs to be when it is pressed and not in the other places.