Comparing TIME

Hi,
As you can see in this code mins come from rtc which is the current time and keeps on changing every minutes. In order to print the minutes on mins correctly it must be view as HEX. Minit on the other hand is suppose to come from an input from a keypad which in this code I just declare it as a value.

In order to light on the LED the current minutes must be equal to the set time in minutes. But mins and minit are not the same type of variable. How can I fix this?
Sorry for my english though :frowning:

int ledR=12;
int ledB=13;
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void loop()
{
  int minit=35;
  Wire.beginTransmission(0x68);
  Wire.write(0);  // location pointer
  Wire.endTransmission();

  Wire.requestFrom(0x68, 7); // send 7 bytes
  byte secs = Wire.read();
  byte mins = Wire.read();
  byte hrs = Wire.read();
  byte day = Wire.read();
  byte date = Wire.read();
  byte month = Wire.read();
  byte year = Wire.read();

  // hours, minutes, seconds

  Serial.print("The time is "); 
  if (hrs < 10) Serial.print("0");
  Serial.print(hrs,HEX);    
  Serial.print(":");
  if (mins < 10) Serial.print("0");
  Serial.print(mins, HEX);
  Serial.print(":");
  if (secs < 10) Serial.print("0");
  Serial.println(secs, HEX);

  // use MM-DD-YYYY

  Serial.print("The date is "); 
  if (month < 10) Serial.print("0");
  Serial.print(month,HEX);    
  Serial.print("-");
  if (date < 10) Serial.print("0");
  Serial.print(date,HEX);
  Serial.print("-");
  Serial.print("20");
  if (year < 10) Serial.print("0");
  Serial.println(year,HEX);
  Serial.println();
 

  Serial.print(" ");
  Serial.println();
  Serial.print(mins);
  Serial.print(" ");
  Serial.print(minit);
  Serial.println();
  
  if(mins==minit)
  {
    digitalWrite(ledB,HIGH);
    delay(500);
  }
  
 
}

Try not to think of it as hex, but BCD (binary-coded decimal) instead.int minit=0x35;

AWOL: Try not to think of it as hex, but BCD (binary-coded decimal) instead.int minit=0x35;

Thank you soo much. I lost a lot of hours trying to figure that out :D

qistie: Hi, How can I fix this?

The internal number format of your RTC is "BCD" (Binary Coded Decimal.

In BCD, four bits are used coding one decimal digit.

So 8 bits (one byte) of BCD makes two(!) decimal digits.

After doing "byte mins = Wire.read();" you have to do BCD to decimal decoding to get decimal minutes.

Typical function to do so;

byte BcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}

And when reading values from RTC you better do something like:

byte mins = BcdToDec(Wire.read());

ALL values in the RTC are binary coded decimals, you better keep that in mind!

jurs: And when reading values from RTC you better do something like:

byte mins = BcdToDec(Wire.read());

ALL values in the RTC are binary coded decimals, you better keep that in mind!

Okay got it! :) And now I need to compare a value from rtc, for example the minutes with a value got from keypad and store in an array. I need it to be when I store 20 (which mean minute=20) and the function will act when the minute from rtc is 20. If from rtc is in BCD, how can I compare it with an integer?

 if(mins==minutes)
  {

   }

Well you’d obviously have to do that conversion first and compare to that result.

Where is the rest of the code? Based on this line you are using some sort of rtc library

  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

The library may have other API functions that could make the tasks easier. i.e. functions that return integer values rather than BCD values, and functions that work with epoch based time which is the ideal format for time comparisons.

--- bill

Where is the rest of the code? You still have not shown us any includes or the declaration of rtc

So we don't know which rtc library you are using.

Sorry for the inconvenient. I have edited the code.

qistie: Sorry for the inconvenient. I have edited the code.

which still cannot be everything...

even the Wire library is missing, not to mention:

bperrybap: Where is the rest of the code? You still have not shown us any includes or the declaration of rtc

So we don't know which rtc library you are using.

BulldogLowell:
even the Wire library is missing, not to mention:

I have already included the whole code.

qistie:
This is the rest of the code

#include <Time.h>

#include <TimeLib.h>
#include <RTClib.h>
#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
RTC_DS1307 rtc;

Given the libraries you are using, it seems very odd to use a library to set the time but then read the rtc chip directly for everything else. Why? The libraries you are using with the sketch have code to make accessing and setting the time easier and do not require talking to the rtc directly.

You need to go read about the libraries you are using. You are using the Time library. When using the Time library with an RTC, you need to set a synchronization function to get the time from the rtc. There are plenty of API functions available in those libraries (mainly the Time library) to access time in various ways. You can get the time components as integers. But if you are going to compare times, using epoch based time is much better and much simpler.

So stepping back a long ways, what is the real goal?

--- bill

Also I fixed the first code, and run it at when the time on my pc almost hit 25 minutes. But the LED doesnt turn on but I can see the serial monitor do the delay act before it print it next code. My wiring is not the problem.
Did my comparing method is wrong? How should I do it?

int ledR=12;
int ledB=13;
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  pinMode(ledB,OUTPUT);
}

void loop()
{
  int minit=0x25;
  Wire.beginTransmission(0x68);
  Wire.write(0);  // location pointer
  Wire.endTransmission();

  Wire.requestFrom(0x68, 7); // send 7 bytes
  byte secs = Wire.read();
  byte mins = Wire.read();
  byte hrs = Wire.read();
  byte day = Wire.read();
  byte date = Wire.read();
  byte month = Wire.read();
  byte year = Wire.read();

  // hours, minutes, seconds

  Serial.print("The time is "); 
  if (hrs < 10) Serial.print("0");
  Serial.print(hrs,HEX);    
  Serial.print(":");
  if (mins < 10) Serial.print("0");
  Serial.print(mins, HEX);
  Serial.print(":");
  if (secs < 10) Serial.print("0");
  Serial.println(secs, HEX);

  // use MM-DD-YYYY

  Serial.print("The date is "); 
  if (month < 10) Serial.print("0");
  Serial.print(month,HEX);    
  Serial.print("-");
  if (date < 10) Serial.print("0");
  Serial.print(date,HEX);
  Serial.print("-");
  Serial.print("20");
  if (year < 10) Serial.print("0");
  Serial.println(year,HEX);
  Serial.println();
 

  Serial.print(" ");
  Serial.println();
  Serial.print(mins);
  Serial.print(" ");
  Serial.print(minit);
  Serial.println();
  
  if(mins==minit)
  {
    digitalWrite(ledB,HIGH);
    delay(500);
  }
  
 
}
  Serial.print(" ");
  Serial.println();
  Serial.print(mins);
  Serial.print(" ");
  Serial.print(minit);
  Serial.println();

When it prints this part does it print the two as being equal? How are you sure, because it is just spitting out two numbers with no labels or anything. Why don't you label those two in the output so you can see if they ever are really equal?

Delta_G: When it prints this part does it print the two as being equal? How are you sure, because it is just spitting out two numbers with no labels or anything. Why don't you label those two in the output so you can see if they ever are really equal?

Yes it does print both of them as equal when it is the right time but the LED is still does not turn on. I have also labeled it.

  Serial.print(" ");
  Serial.println();
  Serial.print("From RTC :");
  Serial.print(mins);
  Serial.print(" ");
  Serial.print("From declaring:");
  Serial.print(minit);
  Serial.println();
  
  if(mins==minit)
  {
    digitalWrite(ledB,HIGH);
    delay(500);
  }

}

Can you show that output?

Delta_G:
Can you show that output?

I attached the picture of it. The output keep on doing its looping fast before the time is not equal. But when the time is equal it start to delay. I assume its because I put delay is the if(mins=minit).

Capture.PNG

Can you load up a simple blink sketch to blink that led? Can we confirm that it is working and not wired the wrong way round or something simple?

Delta_G: Can you load up a simple blink sketch to blink that led? Can we confirm that it is working and not wired the wrong way round or something simple?

The LED did work on my other sketch that is why I said my wiring wasnt the problem.

jurs: The internal number format of your RTC is "BCD" (Binary Coded Decimal.

In BCD, four bits are used coding one decimal digit.

So 8 bits (one byte) of BCD makes two(!) decimal digits.

After doing "byte mins = Wire.read();" you have to do BCD to decimal decoding to get decimal minutes.

Typical function to do so;

byte BcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}

And when reading values from RTC you better do something like:

byte mins = BcdToDec(Wire.read());

ALL values in the RTC are binary coded decimals, you better keep that in mind!

I understand that we can read it in Decimal. But can it actually be converted to Decimal?