This'll be a special one, and hopefully an easily solveable, problem!
I've been working with a DS3231 to keep track of time, in an effort to have a light turn on within a given timespan.
I use the DS3231 to post the time in an HH:MM format, in a 24hour format. For example, 21:02 or some such.
What I've succeeded in doing is substringing the HH into a seperate 2 character string (21), and the MM into a separate 2 character string (02). What I am failing at however, is managing to convert the 21 and 02 into int, a state where I'd much prefer to work with it.
My code is as follows:
#include <Boards.h>
#include <DS3231.h>
#include <SoftwareSerial.h>
DS3231 rtc(SDA, SCL);
#define LIGHT 2
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LIGHT, OUTPUT);
digitalWrite(2, LOW);
rtc.begin();
rtc.setTime(13, 11, 0);
}
int TheTime = 0;
int Aftensluk = 1380;
int TheTimeofSundown = 960; // Supposed to be a variable influneced and changed by what is fetched from Node-red
String TheClock;
String Hours;
String Minutes;
int inthours;
int intminutes;
int hourstoint = 60;
int Converter = 1;
void loop() {
// put your main code here, to run repeatedly:
// Serial.println(rtc.getTimeStr());
delay (1000);
static String TheClock = String(rtc.getTimeStr(FORMAT_SHORT));
static String Hours = TheClock.substring(0,2);
static String Minutes = TheClock.substring(3,5);
int inthours = String (Hours.toInt);
int intminutes = String (Minutes.toInt);
}
However, trying to get this to actually cooperate results in this error:
"invalid use of non-static member function"
Now, I'm not good with static/non-static, or variables in general, so if Ive done something that is obviously wrong, please forgive me!
Where did you get the DS3231 library from ?
Are you sure that you cannot get the hour and minute from it as ints or even bytes rather than as Strings ?
Hey mate, thanks for the rapid answer!
Got it from RinkyDinkElectronics, and while I'm using the function getTimeStr there is also a getTime with the following description:
"Get current data from DS3231.
Parameters: None
Returns: Time-structure
Usage: t = rtc.getTime() // read current time and date."
Why mess around converting a pointer to a string into a String then using substring() to pull the digits from it and then trying to convert them to ints ?
Look at the Serial_Hard example with the library to see how to get the hour and minute directly from the Time structure after calling getTime()
This is a textbook example of an XY problem.
What is an XY problem? http://xyproblem.info/
If you just want to get at the time from a DS3231, well, here is how I do it:
#include <Wire.h>
// variables for storing the time
// second minute hour weekday date month year
byte ss=0, mi=0, hh=0, wd=6, dd=1, mo=1, yy=0;
void setup()
{
Wire.begin();
Serial.begin(9600); // or whatever baud rate you wish to use
// clear /EOSC bit
// Sometimes necessary to ensure that the clock
// keeps running on just battery power. Once set,
// it shouldn't need to be reset but it's a good
// idea to make sure.
// Wire.beginTransmission(0x68); // address DS3231
// Wire.write(0x0E); // select register
// Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
// Wire.endTransmission();
}
void loop()
{
// read the time from the RTC, if we can
boolean gotTheTime = grabTime();
if (gotTheTime) {
// if we are here, then the time has been successfully read
// and stored in global variables (ss, mi, hh, wd, dd, mo, yy)
Serial.print("Got the time: ");
printTime();
}
else {
// if we are here, then we tried to read the time but couldn't
Serial.println("Unable to read time from RTC");
}
delay(500);
}
boolean grabTime() {
// get time from the RTC and put it in global variables
// send request to receive data starting at register 0
Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
Wire.write((byte)0); // start at register 0
Wire.endTransmission();
Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
// check for a reply from the RTC, and use it if we can
if (Wire.available() >= 7) {
// if we're here, we got a reply and it is long enough
// so now we read the time
ss = bcd2bin(Wire.read()); // get seconds
mi = bcd2bin(Wire.read()); // get minutes
hh = bcd2bin(Wire.read()); // get hours
wd = bcd2bin(Wire.read()); // get day of week
dd = bcd2bin(Wire.read()); // get day of month
mo = bcd2bin(Wire.read()); // get month
yy = bcd2bin(Wire.read()); // get year (two digits)
// indicate that we successfully got the time
return true;
}
else {
// indicate that we were unable to read the time
return false;
}
}
byte bcd2bin(byte x) {
// converts from binary-coded decimal to a "regular" binary number
return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}
void printTime() {
// just like it says on the tin
Serial.print ("\'");
if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("(");
switch (wd) {
case 1: Serial.print("Mon"); break;
case 2: Serial.print("Tue"); break;
case 3: Serial.print("Wed"); break;
case 4: Serial.print("Thu"); break;
case 5: Serial.print("Fri"); break;
case 6: Serial.print("Sat"); break;
case 7: Serial.print("Sun"); break;
default: Serial.print("Bad");
}
Serial.print(") ");
if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}
This is a textbook example of an XY problem.
What is an XY problem? http://xyproblem.info/
My programming in a nutshell.
I had hoped to turn the time from string to int to have an easier time doing my if functions, but I've gone back to the string version.
But now I have a whole new problem, that I've no clue why is happeing (shocking I'm sure.) Once my rtc.getTimeStr(FORMAT_SHORT) is used, I can't turn on the LED I have anymore. Format_short gets rid of the seconds, so it only displays HH:MM.
Does anyone have any idea why? Having tried around a bit, it's the moment I start using the rtc.getTimeStr.
If it's any help, the LED was blinking along with the RX LED on the Arduino MEGA, which means it was recieving some kind of byte. It's highly likely to be related, but I can't say for sure due to lack of experience.
#define LIGHT 7
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
String TheTime = rtc.getTimeStr(FORMAT_SHORT);
void setup() {
// put your setup code here, to run once:
rtc.begin();
pinMode(LIGHT, OUTPUT);
String TheTimeofSundown = "16:05";
String Aftensluk = "23:00";
pinMode(LIGHT, OUTPUT);
Serial.begin(115200);
rtc.setTime(16, 03, 0);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(LIGHT, HIGH);
if (String TheTimeofSundown = TheTime)
digitalWrite (LIGHT, HIGH);
if (String Aftensluk = TheTime)
digitalWrite (LIGHT, LOW);
delay (1000);
I did look over it, don't worry, but where the _easy gives me it in HH:MM in a combined effort, which makes it easy to compare it to the info I fetched down from my Node Red, that also arrives in the HH:MM format.
It's not working, shocking I'm sure, so I'll just accept it's not getting anywhere and try _hard. I fear more questions will arrive though. My problem is that t is of course Time now, and I'll be getting a String from my Node-Red. Any suggestion how I make the two compatible?
Your String approach is likely to create memory problems, and I don't understand the issue with node red.
But I think that your current code is not comparing the Strings correctly. You have the = vs == issue previously noted, and there are scope issues with your String variables.
Hey Cattle, I've tried your code but oddly enough, it's leaving my Serial.print empty when I try to print TheTime and when putting TheTimeofSundown and TheTime on 16:05 both, it's still not turning on LIGHT. I fear there is some trouble with the wiring, but I've got the light to shine when simply turned on, with no success with the 16:05.
Thanks for the help to everyone thus far, by the way.
#define LIGHT 7
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
String TheTime = rtc.getTimeStr(FORMAT_SHORT);
String TheTimeofSundown = "16:05";
String Aftensluk = "23:00";
void setup() {
// put your setup code here, to run once:
// put your setup code here, to run once:
rtc.begin();
pinMode(LIGHT, OUTPUT);
Serial.begin(115200);
rtc.setTime(16, 03, 0);
Serial.print(TheTime);
}
void loop() {
// put your main code here, to run repeatedly:
if (TheTimeofSundown == TheTime)
digitalWrite (LIGHT, HIGH);
if ( Aftensluk == TheTime)
digitalWrite (LIGHT, LOW);
delay (1000);
}