Help with rtc Clock

Hey!

I´m new with arduino and want to programm a 6 digit nixie clock.
I am using 6 Bulbs 6 driver ic´s SN74141 a arduino mega and a ds1307 real time clock.
Each driver has 4 bcd inputs (ABCD , 1 2 4 8 ).
I only need help with the programm.
I already found a tutorial where you can get the time from the rtc
like 1 byte for secounds ,1 for minutes,1 for hours.
So my question is can i read 1 nibble (4 bit) for lower secounds and 1 nibble for higher? (same for minutes and hours)
And could you say this nibble equals 4 outputs so that the output would have the truth table of the nibble? ( Nibble 0101 = outputs 1-4 0101)
Is this possible?

If not i thougt to do something like this to display 21secounds:

if (lowersecounds == 1) //write 1000
{
digitalWrite(A, HIGH);
digitalWrite(B, LOW;
digitalWrite(C, LOW);
digitalWrite(D, LOW);
}
if (highersecounds == 2) //write 0100
{
digitalWrite(A, LOW);
digitalWrite(B, HIGH;
digitalWrite(C, LOW);
digitalWrite(D, LOW);
}

Thanks for help and sorry english isn´t my native language!

Bob

I will post my newest code everytime in here:

//Nixie Clock Programm
//Designed for 6 bulbs with 6 SN74141/K155id1 drivers
//Driven by an Arduino Mega with an DS1307 RTC
//Base RTC code was from here: http://tronixstuff.com/2014/12/01/tutorial-using-ds1307-and-ds3231-real-time-clock-modules-with-arduino/
//Truthtable SN74141/K155id1:
//D C B A
//0 0 0 0 = 0
//0 0 0 1 = 1
//0 0 1 0 = 2
//0 0 1 1 = 3
//0 1 0 0 = 4
//0 1 0 1 = 5
//0 1 1 0 = 6
//0 1 1 1 = 7
//1 0 0 0 = 8
//1 0 0 1 = 9
//1 0 1 0 = NONE
//1 0 1 1 = NONE
//1 1 0 0 = NONE
//1 1 0 1 = NONE
//1 1 1 0 = NONE
//1 1 1 1 = NONE
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
//Define the input buttons here
int plusMin = 3;
int plusHr = 4;
int minusMin = 5;
int minusHr = 6;
// 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) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS1307 seconds, minutes, hours, day, date, month, year
  // setDS1307time(30,42,21,4,26,11,14);
  //Defining The Ports
  pinMode(plusMin, INPUT);
  pinMode(plusHr, INPUT);
  pinMode(minusMin, INPUT);
  pinMode(minusHr, INPUT);
  DDRA = B11111111;
  DDRC = B11111111;
  DDRK = B11111111;

}
//Time setting Function
void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte
                   dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
//Reading the time
void readDS1307time(byte *second,
                    byte *minute,
                    byte *hour,
                    byte *dayOfWeek,
                    byte *dayOfMonth,
                    byte *month,
                    byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set DS1307 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = Wire.read() & 0x7f; //maybe delete the 0x7f
  *minute = Wire.read();
  *hour = Wire.read() & 0x3f; //maybe delete the 0x3f
  *dayOfWeek = Wire.read();
  *dayOfMonth = Wire.read();
  *month = Wire.read();
  *year = Wire.read();
}
void AntiCathodePoisoning(){
   byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, ACP;
   //If minutes equals 15 or 45
   if ((bcdToDec(minute) == 15 || bcdToDec(minute) == 45) && decToBcd(second) <= 5){
    ACP = ACP + 1;
    PORTA = B00000000;
    PORTC = B00000000;
    PORTK = B00000000;
    delay(100); 
    PORTA = B00010001;
    PORTC = B00010001;
    PORTK = B00010001;
    delay(100);
    PORTA = B00100010;
    PORTC = B00100010;
    PORTK = B00100010;
    delay(100);
    PORTA = B00110011;
    PORTC = B00110011;
    PORTK = B00110011;
    delay(100);
    PORTA = B01000100;
    PORTC = B01000100;
    PORTK = B01000100;
    delay(100);
    PORTA = B01010101;
    PORTC = B01010101;
    PORTK = B01010101;
    delay(100);
    PORTA = B01100110;
    PORTC = B01100110;
    PORTK = B01100110;
    delay(100);
    PORTA = B01110111;
    PORTC = B01110111;
    PORTK = B01110111;
    delay(100);
    PORTA = B10001000;
    PORTC = B10001000;
    PORTK = B10001000;
    delay(100);
    PORTA = B10011001;
    PORTC = B10011001;
    PORTK = B10011001;
    delay(100);
}
else{
  ACP = 0;
}
}
//get the time to the outputs
void displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, ACP;
  // retrieve data from DS3231
  readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  //Not showing the time between 03-05 Am or during AntiCathodePoisoning routine
  if (!bcdToDec(hour) == 03 && !bcdToDec(hour) == 04 && !bcdToDec(hour) == 05 && !ACP == 1) {
    //Write the time to the pins (maybe put them in the loop)
    //Pin 22-29
    PORTA = second;
    //Pin 30-37
    PORTC = minute;
    //Pin A8-A15
    PORTK = hour;
  }
    else if ((bcdToDec(hour) == 03 || bcdToDec(hour) || 04 || bcdToDec(hour) == 05) && ACP == 0){
    // BCD 1111 equals 15 in DEC. 15 is converted in the driver as bulb turned off
    PORTA = B11111111;
    PORTC = B11111111;
    PORTK = B11111111;   
  }
  delay(10); // 10ms because the internal time counting could be not accurate
}
//Setting the time via Buttons
//if you hold the button it will repeat it´s action every 0,5 seconds
void Buttons()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, Min_set, Hr_set;
  //Setting the time via Buttons
  if (digitalRead(minusMin) == HIGH) {
    Min_set = bcdToDec(minute) - 1;
    if(Min_set == -1){
      Min_set == 59;
    }
    setDS1307time(bcdToDec(second), Min_set, bcdToDec(hour), bcdToDec(dayOfWeek), bcdToDec(dayOfMonth), bcdToDec(month), bcdToDec(year));
    delay(500);
  }
  if (digitalRead(plusMin) == HIGH) {
    Min_set = bcdToDec(minute) + 1;
    if(Min_set == 60){
      Min_set == 00;
    }
    setDS1307time(bcdToDec(second), Min_set, bcdToDec(hour), bcdToDec(dayOfWeek), bcdToDec(dayOfMonth), bcdToDec(month), bcdToDec(year));
    delay(500);
  }
  if (digitalRead(minusHr) == HIGH) {
    Hr_set = bcdToDec(hour) - 1;
    if(Hr_set == 0){
     Hr_set = 24;
    }
    setDS1307time(bcdToDec(second), bcdToDec(minute), Hr_set, bcdToDec(dayOfWeek), bcdToDec(dayOfMonth), bcdToDec(month), bcdToDec(year));
    delay(500);
  }
  if (digitalRead(plusHr) == HIGH) {
    Hr_set = bcdToDec(hour) + 1;
    if(Hr_set == 25){
     Hr_set = 1;
    }
    setDS1307time(bcdToDec(second), bcdToDec(minute), Hr_set, bcdToDec(dayOfWeek), bcdToDec(dayOfMonth), bcdToDec(month), bcdToDec(year));
    delay(500);
  }
}

void loop()
{
  displayTime();
  Buttons();
  AntiCathodePoisoning();
}

So i have tried a little bit myself.

Could this code work?
i have only done one part of the secounds now...

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

  const int A=2;
  const int B=3;
  const int C=4;
  const int D=5;
// 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) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS1307 seconds, minutes, hours, day, date, month, year
  // setDS1307time(30,42,21,4,26,11,14);
  pinMode(A0, INPUT);
  pinMode(A, OUTPUT); //LSB
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT); //MSB
 
}
void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS1307time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set DS1307 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, HourNibble10, HourNibble, MinNibble10, MinNibble, SecoundNibble10, SecoundNibble;
  // retrieve data from DS3231
  readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
 HourNibble10 = hour/10;
 HourNibble = hour%10;
 MinNibble10 = minute/10;
 MinNibble = minute%10;
 SecoundNibble10 = second/10;
 SecoundNibble = second%10;
 
 if (SecoundNibble == 0) //write 0000
    {
      digitalWrite(A, LOW);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 1) //write 0001
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 2) //write 0010
    {
      digitalWrite(A, LOW);
      digitalWrite(B, HIGH);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 3) //write 0011
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 4) //write 0100
    {
      digitalWrite(A, LOW);
      digitalWrite(B, LOW);
      digitalWrite(C, HIGH);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 5) //write 0101
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, LOW);
      digitalWrite(C, HIGH);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 6) //write 0110
    {
      digitalWrite(A, LOW);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 7) //write 0111
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, LOW);
    }
     
    if (SecoundNibble == 8) //write 1000
    {
      digitalWrite(A, LOW);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, HIGH);
    }
     
    if (SecoundNibble == 9) //write 1001
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, HIGH);
    } 
  switch(dayOfWeek){
  case 1:
    break;
  case 2:
    break;
  case 3:
    break;
  case 4:
    break;
  case 5:
    break;
  case 6:
    break;
  case 7:
    break;
  }
}

Why not have a look at an existing Arduino/ Nixie project, for example: 404 - 页面不存在
This project has also been implemented by a forum member here, and some corrections were necessary because of an interpretation problem in the schematic.

Thanks a lot but i wanted to do it without the shift registers and have no clue how to change the code....
Would my code work like this?

OK. Here is one without shift registers and uses heavy multiplexing instead.

Your best approach will be to program it (using Serial.print etc. to debug it) and see how far you get, then come back if you have more specific questions.

I also found many tutorials much of them are using multiplexing or shift register i wanted mine to be done withe one arduino mega ( enough outputs) and 6 bcd to dec driver so that my code would be simple.
How can i test the code above?
I have not recived all parts now and can't just programm the arduino and test it...

  1. You should supply a schematic of your hardware layout.
  2. Your testing should begin with the real time clock to ensure you can set/read it
    3: you are going to create a huge amout of code if you duplicate what you have done for low seconds for the other 5 displays. Consider using a function call as illustrated here:
void function displayDigit ( int digit , int A, int B, int C, int D ) {
    // digit is the digit to display
    // A, B, C and D repreent the pins for display driver
    // you could optimise the following for all digits to just 4 lines of code:  
    if (digit == 0) //write 0000
    {
      digitalWrite(A, LOW);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    if (digit == 1) //write 0001
    {
      digitalWrite(A, HIGH);
      digitalWrite(B, LOW);
      digitalWrite(C, LOW);
      digitalWrite(D, LOW);
    }
     
    // etc. etc. for digits 2 to 9
    
 }

// now call the function, once per display driver, to display the required digit.
displayDigit( HourNibble10 , 10, 11, 12, 13)   //assuming these are the pins for the associated driver IC
displayDigit( HourNibble   , 14, 15, 16, 17)   //assuming these are the pins for the associated driver IC
displayDigit( MinNibble10  , 18, 19, 20, 21)   //assuming these are the pins for the associated driver IC
// etc the 3 remaining driver ICs

Your method of selecting bits is painfully verbose. All those if (Nibble = x) statements could be eliminated by just writing the bit values directly, once.

for example:

digitalWrite(A, BitRead(SecondNibble,3) );

Thanks a lot for the help!
I searched the function bitRead(); thats what i needed.
I will add a shematics soon if needed.
Heres my cleaned up code (only done the seconds yet.):

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
//Defining Low Secounds
  const int ALS=2;
  const int BLS=3;
  const int CLS=4;
  const int DLS=5;
  //Defining High Secounds
  const int AHS=6;
  const int BHS=7;
  const int CHS=8;
  const int DHS=9;
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) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS1307 seconds, minutes, hours, day, date, month, year
  // setDS1307time(30,42,21,4,26,11,14);
  pinMode(A0, INPUT);
  pinMode(ALS, OUTPUT); 
  pinMode(BLS, OUTPUT);
  pinMode(CLS, OUTPUT);
  pinMode(DLS, OUTPUT); 
  pinMode(AHS, OUTPUT); 
  pinMode(BHS, OUTPUT);
  pinMode(CHS, OUTPUT);
  pinMode(DHS, OUTPUT); 
 
}
void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS1307time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set DS1307 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = Wire.read();
  *minute = Wire.read();
  *hour = Wire.read();
  *dayOfWeek = Wire.read();
  *dayOfMonth = Wire.read();
  *month = Wire.read();
  *year = Wire.read();
}
void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
digitalWrite(AHS, bitRead(second,7) );
digitalWrite(BHS, bitRead(second,6) );
digitalWrite(CHS, bitRead(second,5) );
digitalWrite(DHS, bitRead(second,4) );
digitalWrite(ALS, bitRead(second,3) );
digitalWrite(BLS, bitRead(second,2) );
digitalWrite(CLS, bitRead(second,1) );
digitalWrite(DLS, bitRead(second,0) );

}

To simplify your code down to around 3 lines of code, you could connect the digits on your arduino, by groups of twos, on a same port (also see this diagram if interested) :wink:

Looks nice! But i think i need pin 0 for rx so i can't use it because i'm using seriel right?
But if i really want to use it could i just say
portd = Wire.read ();
Would it work like this after i configured the pins?
I think it's simpler to don't shrink the code further...
Can anybody please tell me if my rtc part of the script (and the rest) is right or do i have to wait for all my parts to arrive?
Anyway thanks for all your help so far!

You need pin 0 for serial, yes. But the arduino mega has many ports (as seen in the diagram)

If it was my project I would probably use ports A (pins 22-29), C (30-37) and K (A8-A15), then do something like this:

readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
PORTA = second;
PORTC = minute;
PORTK = hour;

Bobnixie:

byte bcdToDec(byte val)

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

Google "C++ bit-shifting operators".

C++ has a number of operators (by operator, I mean a thing like * + - / % ) that manipulate bits of integer-valued operands.

byte bcdToDec(byte val)
{
  return ((val>>>4)*10) + (val & 0x0F) );
}

guix:
You need pin 0 for serial, yes. But the arduino mega has many ports (as seen in the diagram)

If it was my project I would probably use ports A (pins 22-29), C (30-37) and K (A8-A15), then do something like this:

readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

PORTA = second;
PORTC = minute;
PORTK = hour;

Okay i see i thought there would be only 3...
Nice does the timereading from the ds1307 works as simple as this?

Bobnixie:
Hey i changed my code with port manipulation!
I also added a time setting function via buttons.
Can you please look over my code and tell me if i made any mistakes?

Thanks a lot! Heres the code:

#include "Wire.h"

#define DS1307_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal

int plusMin = 3;
int plusHr = 4;
int minusMin = 5;
int minusHr = 6;

byte decToBcd(byte val)
{
 return( (val/1016) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
 return( (val/16
10) + (val%16) );
}
void setup()
{
 Wire.begin();
 Serial.begin(9600);
 // set the initial time here:
 // DS1307 seconds, minutes, hours, day, date, month, year
 // setDS1307time(30,42,21,4,26,11,14);
 //Defining The Ports
 pinMode(plusMin, INPUT);
 pinMode(plusHr, INPUT);
 pinMode(minusMin, INPUT);
 pinMode(minusHr, INPUT);
 DDRA = B11111111;
 DDRC = B11111111;
 DDRK = B11111111;

}
void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
 // sets time and date data to DS3231
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0); // set next input to start at the seconds register
 Wire.write(decToBcd(second)); // set seconds
 Wire.write(decToBcd(minute)); // set minutes
 Wire.write(decToBcd(hour)); // set hours
 Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
 Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
 Wire.write(decToBcd(month)); // set month
 Wire.write(decToBcd(year)); // set year (0 to 99)
 Wire.endTransmission();
}
void readDS1307time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.write(0); // set DS1307 register pointer to 00h
 Wire.endTransmission();
 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
 // request seven bytes of data from DS3231 starting from register 00h
 *second = Wire.read();
 *minute = Wire.read();
 *hour = Wire.read();
 *dayOfWeek = Wire.read();
 *dayOfMonth = Wire.read();
 *month = Wire.read();
 *year = Wire.read();
}
void loop()
{
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, Min_set, Hr_set;
 // retrieve data from DS3231
 readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
PORTA = second;
PORTC = minute;
PORTK = hour;
if(digitalRead(minusMin) == HIGH) {
 Min_set = bcdToDec(hour)-1;
 setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(minusHr) == HIGH) {
 Hr_set = bcdToDec(hour)-1;
 setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(plusMin) == HIGH) {
 Min_set = bcdToDec(hour)+1;
 setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(plusHr) == HIGH) {
 Hr_set = bcdToDec(hour)+1;
 setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
}

  • I think I made a mistake, it should be:
PORTA = decToBcd( second );
...

guix:

  • I think I made a mistake, it should be:
PORTA = decToBcd( second );

...




- Do not read the RTC everytime loop is called, it's useless, and the RTC might not like it (but I could be wrong). See the Blink Without Delay example.

- You need a more robust code for the buttons part. I suggest you use a button library, for example this one: https://github.com/JChristensen/Button

You did not make a mistake!
Second is already in BCD because the RTC sends it in BCD and i have not converted it.
I changed my code so that the time will be read every 10ms it should work like this:

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

int plusMin = 3;
int plusHr = 4;
int minusMin = 5;
int minusHr = 6;
// 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) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS1307 seconds, minutes, hours, day, date, month, year
  // setDS1307time(30,42,21,4,26,11,14);
  //Defining The Ports
  pinMode(plusMin, INPUT);
  pinMode(plusHr, INPUT);
  pinMode(minusMin, INPUT);
  pinMode(minusHr, INPUT);
  DDRA = B11111111;
  DDRC = B11111111;
  DDRK = B11111111;
 
}
//Time setting Function
void setDS1307time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
//Reading the time
void readDS1307time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0); // set DS1307 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = Wire.read();
  *minute = Wire.read();
  *hour = Wire.read();
  *dayOfWeek = Wire.read();
  *dayOfMonth = Wire.read();
  *month = Wire.read();
  *year = Wire.read();
}
//get the time to the outputs
void displayTime()
{
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS1307time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  //Write the time to the pins

delay(10); // 10ms because the internal time counting could be not accurate
}
void loop()
{
   byte second, minute, hour, dayOfWeek, dayOfMonth, month, year, Min_set, Hr_set;
   
  displayTime(); // display the real-time clock data on the Serial Monitor,
  
 //Pin 22-29  
PORTA = second;
//Pin 30-37
PORTC = minute;
//Pin A8-A15
PORTK = hour;

//Setting the time via Buttons
if(digitalRead(minusMin) == HIGH) {
  Min_set = bcdToDec(hour)-1;
  setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(minusHr) == HIGH) {
  Hr_set = bcdToDec(hour)-1;
  setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(plusMin) == HIGH) {
  Min_set = bcdToDec(hour)+1;
  setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
if(digitalRead(plusHr) == HIGH) {
  Hr_set = bcdToDec(hour)+1;
  setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
}
}

Do i need to use this button libary?
Is it to unsafe to ask the button directly for its state?
So the button could say in the moment of pressing something like: "0 1 0 1 0 1" and then stays 1 so that my counter would add 3 hours but i only pressed one time?

The loop() run so fast that when you will press the button, you will have a hard time setting the clock to the correct value, because it will increase the value so fast that you will not be able to release the button in time... The easiest but shittiest way to solve this is to add a delay() so that the code does not repeat too often.

Then, if "second" etc are already in BCD, you cannot just increase their values by 1. You have to convert to DEC, add 1 (and make sure you limit what the value can be), and convert back to BCD.

Ah okay i see thats the problem....
Thanks!
The nice thing with this delay is if you press the button longer it will keep adding a hour or minute after every delay.
So a made a litte (shitty) part for the buttons with a delay like this:

void Buttons()
{
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
//Setting the time via Buttons
if(digitalRead(minusMin) == HIGH) {
  Min_set = bcdToDec(hour)-1;
  setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
  delay(1000);
}
if(digitalRead(minusHr) == HIGH) {
  Hr_set = bcdToDec(hour)-1;
  setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
  delay(1000);
}
if(digitalRead(plusMin) == HIGH) {
  Min_set = bcdToDec(hour)+1;
  setDS1307time(second,Min_set,bcdToDec(hour),bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
  delay(1000);
}
if(digitalRead(plusHr) == HIGH) {
  Hr_set = bcdToDec(hour)+1;
  setDS1307time(second,bcdToDec(minute),Hr_set,bcdToDec(dayOfWeek),bcdToDec(dayOfMonth),bcdToDec(month),bcdToDec(year));
  delay(1000);
}
}