Rtc als tijdsklok/schakelaar

Ik ben voor mijn terrarium bezig een tijdsschakeling te maken met een arduino in combinatie met de ds3231 rtc.
Nu was dat op zich niet heel erg ingewikkeld, ik heb de code gebruikt die bij de ds3231 hoort, en daar heb ik een if statement aan toe gevoegd.
Nu werkte dat bijna zoals de bedoeling was, enkel was ik vergeten wat &&'s toe te voegen waardoor elk uur om .30 de lamp 1 minuut uit ging.
Dus ik had de code geupdate en het weer aangekoppeld, toen kwam ik er achter dat het licht niet weer aan ging. Dat was ook ergens wel logisch, er staat enkel aangegeven dat het licht aan moet gaan om 8.00, als de stroom er even af is geweest, gaat die dus niet weer aan.
Nu wilde ik dat veranderen en het zo maken dat de verlichting tussen 8 en 22.30 aan zou gaan, maar ik kom er niet uit hoe ik dat in de code moet verwerken.
Is er iemand die mij daarbij zou kunnen helpen?

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// 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) );
}
int Light = 2;
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS3231 seconds, minutes, hours, day, date, month, year
  // setDS3231time(00,17,23,3,13,01,15);
  pinMode(Light, OUTPUT);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_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 readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_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 displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
}
void loop()
{
  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
  
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);

  if (hour==8&&minute==00&&second==01) {
    digitalWrite(Light, HIGH);
  }
  if (hour==22&&minute==30&&second==00) {
    digitalWrite(Light, LOW);
}


}

Ook ben ik benieuwd naar hoe ik dat zo kan maken dat als ik een tijd erin wil hebben dat het 's nachts regent tussen 23.00 en 02.00.

Om het simpeler te maken voor de tijd dat het licht aan moet zijn kun je beter het interval instellen:
dus:

  if (hour==8&&minute==00&&second==01) {
    digitalWrite(Light, HIGH);
  }
  if (hour==22&&minute==30&&second==00) {
    digitalWrite(Light, LOW);
}

vervangen in:

  //
  // kijk of de tijd in gewenste interval is
  //
  uint16_t maxTijd = 2230;
  uint16_t minTijd = 0800;
  //
  // bereken huidige tijd als gewoon getal. Maakt het eenvoudiger om te testen
  //
  uint16_t huidigeTijd = hour * 100 + minute;
  
  if (huidigeTijd >= minTijd && huidigeTijd <= maxTijd) {
    digitalWrite(Light, HIGH);
  } else {
    digitalWrite(Light, LOW);
  }

Als nu de spanning er tussentijds afgehaald wordt maar de tijd is nog steeds in het gevraagde interval dan gaat het licht gelijk weer aan.

Dankjewel Nico!
Dit kan ik inderdaad toepassen om de verlichting aan te laten gaan gedurende de dag.
Maar hoe moet ik dat doen als ik het tussen 23.00 en 02.00 wil laten regenen, dan gaat dit niet werken toch?

  uint16_t minRegenTijd = 0200;
  uint16_t maxRegenTijd = 2300;
  uint16_t huidigeTijd = hour * 100 + minute;
  //
  // als de tijd in het interval lig, dan niet regenen. anders wel.
  //
  if (huidigeTijd >= minRegenTijd && huidigeTijd <= maxRegenTijd) {
    digitalWrite(Light, LOW);
  } else {
    digitalWrite(Light, HIGH);
  }

Ahh dan draai je het gewoon om natuurlijk.
Dankjewel!

Nu nog een LCD schermpje er aan hangen zodat je niet steeds je laptop/pc er aan hoeft te hangen om te zien of alles goed werkt en op tijd loopt. En nog een paar drukknopjes zodat je ook met de hand e.e.a. aan en uit kunt schakelen.

Dat was inderdaad ook mijn idee cartoonist, maar ik kan nergens echt een goede tutorial of code daarvoor vinden.
Een schermpje erop aansluiten is niet zo moeilijk, maar dat met die knoppen/een soort menu maken, dat valt niet mee.
Ik heb zelf al eens wat geprobeerd te maken, maar ik heb eigenlijk geen idee hoe ik het moet doen.
Mocht iemand een interessant linkje hebben naar een youtube filmpje of iets dergelijks waar het duidelijk uitgelegd word, dan hou ik me aanbevolen.

opschrijven / tekenen wat je wilt..... is meestal de beste oplossing..... menu voorbeelden zat,.... beter zoeken?

Een gelikt gebruiker menu. Wat intuitief werkt en door iedereen bediend kan worden. Dat is een van de moeilijkste onderdelen van een project.

Een gelikte behuizing maken is wellicht makkelijker.

Ik ben weer eens verder gegaan met het regensysteem.
Enkel klopt het nog niet.

Als ik van 23.00 tot 2.00 het wil laten regenen, dan gaat dat niet werken met de genoemde codes.

  uint16_t minRegenTijd = 0200;
  uint16_t maxRegenTijd = 2300;
  uint16_t huidigeTijd = hour * 100 + minute;
  //
  // als de tijd in het interval lig, dan niet regenen. anders wel.
  //
  if (huidigeTijd >= minRegenTijd && huidigeTijd <= maxRegenTijd) {
    digitalWrite(Light, LOW);
  } else {
    digitalWrite(Light, HIGH);
  }

Hoe krijg ik het wel werkend?

Ik heb een half oog op dat stukje code gericht.
Maar de oorzaak van het probleem lijkt me bij het lezen van je verhaal dat je een overflow meemaakt.
Je gaat van 23:00 naar 0:00 en das lastig want dan zou je achteruit gaan.
Daarom kun je beter alleen vooruit kijken.
Dus dan ga je van 23:00 tot 23:59:59.
Daarna ga je van 0:00 tot 2:00.
Om te weten waar je mee bezig was, dien je dan een vlaggetje te zetten dat je de nul voorbij moet, en die te wissen als je de nul gepasseerd bent.
Zo kun je dus zien dat je hier rekening mee moet houden.

Hey Mas3, ik heb inmiddels een stukje code waarmee het lijkt te werken.

  if ((huidigeTijd >= maxTijd && huidigeTijd > minTijd) || (huidigeTijd < maxTijd && huidigeTijd < minTijd)){
  
    digitalWrite...

Zo zou het moeten werken toch?

Dat kun je zelf uitproberen.

maxTijd en minTijd zijn constanten.
Die kun je dus ook uitschrijven zodat het minder abstract word en je eenvoudiger kunt zien wat daar staat.
Neem nu voor huidigeTijd 2 voorbeelden die allebei binnen jouw gewenste bereik liggen.
Een keer van voor middernacht, en een keer van na middernacht.

Dus ga ik het nu even voor je invullen met waardes in een 'vervangingscode':

als (
       (23:30 groter of gelijk aan  2:00
         en  23:30 groter dan 23:00)

of
      (23:30 kleiner dan 2.00 
        en 23.30 kleiner dan 23:00)
      )
{
doe iets;
  }

Ik hoop dat ik dat goed heb ingevuld.
En jij kunt nu kijken of dat gaat doen wat je wil.

Je kunt dus ook een andere waarde kiezen (in plaats van die 23:30) die in jouw gewenste bereik zit, en een waarde die er buiten valt.
Zo kun je ook voor die momenten kijken of dat doet wat je had bedacht.

Het werkt zoals het zou moeten.

Op die manier uitschrijven is wel een goede, dat kan wel eens verhelderend werken, dankjewel!

Dat stukje code helder krijgen was best wel lastig.
Op een gegeven moment zie/begrijp ik wat er gebeurd, en dan is het niet zo lastig meer.
Dan lukt het me om de code met een tijd door te lopen in mijn hoofd om te zien wat er gebeurd op dat tijdstip volgens de code.

Leren begrijpen neemt tijd.