Go Down

Topic: DS1307 RTC (without RTClib.h) code problem (Read 950 times) previous topic - next topic

nifwan

I made a school bell that can activate autonomously based on real time clock (I'm using Tiny RTC I2C module). the code can be executed smoothly but then i realized a flaw.

my code assume that all months is equal to 31 days. While in reality number of days in one month can vary between 28 to 31 days.

this problem will make me have to correct the time every month (which I don't want to). I want to make my RTC synchronized with the actual world clock and date(for at least one year).

Code: [Select]
void get3231Date()
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x00); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes

  if(Wire.available()) {
    seconds = Wire.read(); // get seconds
    minutes = Wire.read(); // get minutes
    hours   = Wire.read();   // get hours
    day     = Wire.read();
    date    = Wire.read();
    month   = Wire.read(); //temp month
    year    = Wire.read();
       
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
  else {
    Serial.print("RTC is not available");
    Serial.println();
    digitalWrite(LEDInternal, HIGH);
  }
 
  switch (day) {
    // hari 1 adalah minggu, hari 2 adalah senin, dst
    case 1:
      strcpy(weekDay, "Minggu");
      break;
    case 2:
      strcpy(weekDay, "Senin");
      break;
    case 3:
      strcpy(weekDay, "Selasa");
      break;
    case 4:
      strcpy(weekDay, "Rabu");
      break;
    case 5:
      strcpy(weekDay, "Kamis");
      break;
    case 6:
      strcpy(weekDay, "Jumat");
      break;
    case 7:
      strcpy(weekDay, "Sabtu");
      break;
  }
}


note: notice that the code was made for DS3231 but it it can be used for DS1307
i'm using DS1307 and arduino Nano

wildbill

What's the requirement for when the bell should ring?

In a simple case, I would expect the bell to ring at the same times of day for every weekday that the school operates. Then the number of days in each month doesn't matter. Why does it in your case?


cattledog

Quote
my code assume that all months is equal to 31 days. While in reality number of days in one month can vary between 28 to 31 days.
I see nothing in the code you posted that makes an assumption about every month being 31 days?

The DS1307 certainly knows how many days are in each month. From the DS1307 datasheet

Quote
The date at the end of the month is automatically
adjusted for months with fewer than 31 days, including corrections for leap year.

nifwan

thanks for the information guys. but if you don't mind can you please tell me what this mean
Code: [Select]
seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));


it will be very helpful if I know what is this during my presentation

Nick_Pyner

#4
Jun 30, 2019, 10:10 am Last Edit: Jun 30, 2019, 10:14 am by Nick_Pyner
That all looks far too complicated. If you want to use RTC without a library, you might try this....
http://bildr.org/2011/03/ds1307-arduino/

cattledog

Quote
thanks for the information guys. but if you don't mind can you please tell me what this mean
You previously read the byte values of the DS1307 storage registers into your variables. See the DS1307 data sheet for the detailed register descriptions.

The time/date values are held in "Binary Coded Decimal". Google this term.

The code you asked about is converting the BCD values into regular decimal values using bit masks with the bitwise & operator to isolate the tens and ones.
https://playground.arduino.cc/Code/BitMath/

Go Up