My first sketch is finally at what I think is a usable stage. I know there is probably much better ways to do things, but I didnt want to user code I didnt understand, which limited me. I'll refine it as I learn, but are there any glaring mistakes that will bite me? Basically it opens a chicken coop door and slowly brightens the coop lights at sunrise. It slowly dims the lights 14 hours later and shuts the coop door at sunset.
I exported a table of sunset sunrise times at -5 from UDT, so I wouldnt have to deal with daylight saving time. I am a little unclear on the progmem syntax, but I copied that part, and it appears to work correctly.
#include "RTClib.h"
RTC_DS3231 rtc;
int brightness = 40;
int day = 31;
int month = 12;
int minutes;
int dayofyear = 0;
int dimmer = 3;
int relay1 = 4;
int relay2 = 8;
// Sunrise minutes from midnight. Daylight savings time ignored.
static const long sunriseAr[] PROGMEM = {
446,447,447,447,447,447,447,447,447,446,446,446,446,446,445,445,444,444,444,443,443,442,
442,441,440,440,439,438,437,437,436,435,434,433,432,431,430,429,428,427,426,425,424,423,
422,420,419,418,417,416,414,413,412,410,409,408,406,405,404,402,401,399,398,396,395,393,
392,391,389,388,386,384,383,381,380,378,377,375,374,372,371,369,368,366,365,363,361,360,
358,357,355,354,352,351,349,348,346,345,343,342,340,339,337,336,334,333,332,330,329,328,
326,325,323,322,321,320,318,317,316,315,313,312,311,310,309,308,307,306,305,304,303,302,
301,300,299,298,297,296,296,295,294,293,293,292,291,291,290,290,289,289,288,288,288,287,
287,287,286,286,286,286,286,286,286,285,285,285,286,286,286,286,286,286,286,287,287,287,
288,288,288,289,289,290,290,291,291,292,292,293,293,294,295,295,296,296,297,298,299,299,
300,301,302,302,303,304,305,306,306,307,308,309,310,311,311,312,313,314,315,316,317,318,
318,319,320,321,322,323,324,325,326,326,327,328,329,330,331,332,333,333,334,335,336,337,
338,339,340,340,341,342,343,344,345,346,346,347,348,349,350,351,352,353,353,354,355,356,
357,358,359,360,360,361,362,363,364,365,366,367,368,369,369,370,371,372,373,374,375,376,
377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,
399,401,402,403,404,405,406,407,408,409,410,411,413,414,415,416,417,418,419,420,421,422,
423,424,425,426,427,428,429,430,431,432,433,433,434,435,436,437,437,438,439,440,440,441,
441,442,443,443,444,444,444,445,445,445,446,446,446,446};
// Sunset minutes from midnight. Daylight savings time ignored.
static const long sunsetAr[] PROGMEM = {
1020,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,
1037,1038,1039,1040,1041,1043,1044,1045,1046,1047,1048,1049,1051,1052,1053,1054,1055,1056,
1057,1058,1060,1061,1062,1063,1064,1065,1066,1067,1068,1070,1071,1072,1073,1074,1075,1076,
1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,
1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1110,1111,
1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1125,1126,1127,1128,
1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1141,1142,1143,1144,1145,
1146,1147,1148,1149,1150,1151,1152,1153,1153,1154,1155,1156,1157,1158,1159,1159,1160,1161,
1162,1163,1163,1164,1165,1166,1166,1167,1168,1168,1169,1170,1170,1171,1171,1172,1172,1173,
1173,1174,1174,1175,1175,1175,1176,1176,1176,1176,1177,1177,1177,1177,1177,1177,1177,1177,
1177,1177,1177,1177,1177,1176,1176,1176,1176,1175,1175,1175,1174,1174,1173,1173,1172,1172,
1171,1170,1170,1169,1168,1168,1167,1166,1165,1164,1164,1163,1162,1161,1160,1159,1158,1157,
1156,1155,1153,1152,1151,1150,1149,1148,1146,1145,1144,1143,1141,1140,1139,1137,1136,1134,
1133,1132,1130,1129,1127,1126,1124,1123,1121,1120,1118,1117,1115,1114,1112,1111,1109,1108,
1106,1105,1103,1102,1100,1098,1097,1095,1094,1092,1090,1089,1087,1086,1084,1083,1081,1079,
1078,1076,1075,1073,1072,1070,1069,1067,1066,1064,1062,1061,1060,1058,1057,1055,1054,1052,
1051,1049,1048,1047,1045,1044,1043,1041,1040,1039,1038,1036,1035,1034,1033,1032,1030,1029,
1028,1027,1026,1025,1024,1023,1022,1021,1021,1020,1019,1018,1017,1017,1016,1015,1015,1014,
1013,1013,1012,1012,1012,1011,1011,1010,1010,1010,1010,1009,1009,1009,1009,1009,1009,1009,
1009,1009,1009,1009,1010,1010,1010,1010,1011,1011,1012,1012,1012,1013,1013,1014,1015,1015,
1016,1017,1017,1018,1019,1019};
void setup () {
Serial.begin(57600);
#ifndef ESP8266
while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
if (! rtc.begin()) {
Serial.flush();
abort();
}
rtc.adjust(DateTime(2020, 1, 1, 7, 25, 30)); // spoof time for testing
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(dimmer, OUTPUT);
digitalWrite (relay1, LOW);
digitalWrite (relay2, LOW);
analogWrite(dimmer,0);
DateTime now = rtc.now();
while(day > 1 || month > 1){
DateTime dayb4 (now - TimeSpan(dayofyear,0,0,0));
month = dayb4.month();
day = dayb4.day();
dayofyear++;
}dayofyear--; // Subtract 1 day due to tables staring at 0
}
void loop() {
DateTime now = rtc.now();
// increments 1 day forward at midmight. Delays 90 minutes during inactive period.
if (now.hour() == 0){
dayofyear++;
delay(90*60*1000UL);
}
// Get the sunrise sunset times from the tables
long rise = pgm_read_word_near(sunriseAr + (dayofyear));
long set = pgm_read_word_near(sunsetAr + (dayofyear));
int lightoff = rise + 840; // Minutes after midnight that lights begin to dim.
Serial.print(dayofyear, DEC);
Serial.println(rise, DEC);
Serial.println(set, DEC);
Serial.println(lightoff, DEC);
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
minutes = now.hour() * 60 + now.minute(); // minutes after midnight
if(minutes >= rise && minutes < set)
{
digitalWrite (relay1, HIGH);
digitalWrite (relay2, HIGH);
if(minutes == rise){
brightness = 40;
while(brightness<200)
{
analogWrite(dimmer,brightness);
delay(500);
brightness++;
}
rtc.adjust(DateTime(2020, 1, 1, 16, 59, 30)); // spoof time for testing
}
}
if(minutes > lightoff)
{
while(brightness>40)
{
analogWrite(dimmer,brightness);
delay(500);
brightness--;
// Closes door if sunset occurs while lights are dimming.
DateTime now = rtc.now();
minutes = now.hour() * 60 + now.minute(); // minutes after midnight
if(minutes >= set)
{
digitalWrite (relay1, LOW);
digitalWrite (relay2, LOW);
}
}
analogWrite(dimmer,0);
}
if(minutes >= set)
{
digitalWrite (relay1, LOW);
digitalWrite (relay2, LOW);
}
delay(1000);
}