I have code that i built initially for my Arduino Uno to control 8 outlets through an Elegoo 8 Channel DC 5V Relay Module. The timer schedule worked fine for these 8 relays, however when i scaled up to 16 relays, adding a second module to the arduino I started having issues with the schedule. The outlets would remain active when they should be disabled, and other similar issues indicating that is a bug in time tracking. This was confusing to me since the same code handled the 8 relays without issue. I have dedicated power to the arduino and the relay. Also when i test the function of each relay (controlled by arduino) individually all get energized and disabled as intended.
I have posed the code below and I would appreciate any feedback.
Thank you
/*
This sketch turns each of the 16 relays on and then off, based on a daily 'on' time, a duration and cycle. Once the cycle time completes the sequence repeats
Uses arrays and for statements
HIGH TURNS RELAY OFF
*/
long Out1 = 6;
long Out2 = 8;
long Out3 = A4;
long Out4 = 7;
long Out5 = 9;
long Out6 = A3;
long Out7 = A0;
long Out8 = 4;
long Out9 = 2;
long Out10 = A1;
long Out11 = 5;
long Out12 = 3;
long Out13 = A2;
long Out14 = 10;
long Out15 = A5;
long Out16 = 11;
long pinArray[] = {Out1, Out2, Out3, Out4, Out5, Out6, Out7, Out8, Out9, Out10, Out11, Out12, Out13, Out14, Out15, Out16}; // define the pins that will connect to the relays
long relayStateArray[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // track the state of a relay (on or off). Start with the first one on.
//IintTimeMat{} = {Hr,mm,ss}
long InitTimeMat[] = {7,57,00};
long InitTime = InitTimeMat[0]*3600+InitTimeMat[1]*60+InitTimeMat[2]; //time of date when arduino is reset
//long InitTime = 0; //time of date when arduino is reset
long Cycles = 0; //number of cycles passed since arduino reset
//long CycleLen = 60; // length of a 'day' in seconds
long CycleLen = 86400; // length of a 'day' in seconds
float CurrentSecCalc = 0; // variable to track the current "time" -- milliseconds since last time the Arduino was reset
float CurrentSec = 0; // variable to track the current "time" -- milliseconds since last time the Arduino was reset
long previousMillis[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // variable to track the last time a relay state was changed
//StartTime#[] = {Hr,mm,ss}
long StartTime1[] = {5,0,5};
long STS1 = StartTime1[0]*3600+StartTime1[1]*60+StartTime1[2];
long StartTime2[] = {5,0,10};
long STS2 = StartTime2[0]*3600+StartTime2[1]*60+StartTime2[2];
long StartTime3[] = {5,0,15};
long STS3 = StartTime3[0]*3600+StartTime3[1]*60+StartTime3[2];
long StartTime4[] = {0,0,0};
long STS4 = StartTime4[0]*3600+StartTime4[1]*60+StartTime4[2];
long StartTime5[] = {0,0,0};
long STS5 = StartTime5[0]*3600+StartTime5[1]*60+StartTime5[2];
long StartTime6[] = {0,0,0};
long STS6 = StartTime6[0]*3600+StartTime6[1]*60+StartTime6[2];
long StartTime7[] = {0,0,0};
long STS7 = StartTime7[0]*3600+StartTime7[1]*60+StartTime7[2];
long StartTime8[] = {5,0,20};
long STS8 = StartTime8[0]*3600+StartTime8[1]*60+StartTime8[2];
long StartTime9[] = {5,0,5};
long STS9 = StartTime9[0]*3600+StartTime9[1]*60+StartTime9[2];
long StartTime10[] = {0,0,0};
long STS10 = StartTime10[0]*3600+StartTime10[1]*60+StartTime10[2];
long StartTime11[] = {0,0,0};
long STS11 = StartTime11[0]*3600+StartTime11[1]*60+StartTime11[2];
long StartTime12[] = {5,0,10};
long STS12 = StartTime12[0]*3600+StartTime12[1]*60+StartTime12[2];
long StartTime13[] = {5,0,15};
long STS13 = StartTime13[0]*3600+StartTime13[1]*60+StartTime13[2];
long StartTime14[] = {0,0,0};
long STS14 = StartTime14[0]*3600+StartTime14[1]*60+StartTime14[2];
long StartTime15[] = {0,0,0};
long STS15 = StartTime15[0]*3600+StartTime15[1]*60+StartTime15[2];
long StartTime16[] = {0,0,0};
long STS16 = StartTime16[0]*3600+StartTime16[1]*60+StartTime16[2];
//long StartTime[] = {5,20,00,0,0,0,0,0}; // array for Start time for each outlet in seconds
long StartTime[] = {STS1, STS2, STS3, STS4, STS5, STS6, STS7, STS8, STS9, STS10, STS11, STS12, STS13, STS14, STS15, STS16}; // array for Start time for each outlet in seconds
//OnTime#[] = {Hr,mm,ss}
long OnTime1[] = {18,0,0};
long OTS1 = OnTime1[0]*3600+OnTime1[1]*60+OnTime1[2];
long OnTime2[] = {18,0,10};
long OTS2 = OnTime2[0]*3600+OnTime2[1]*60+OnTime2[2];
long OnTime3[] = {18,0,20};
long OTS3 = OnTime3[0]*3600+OnTime3[1]*60+OnTime3[2];
long OnTime4[] = {0,0,0};
long OTS4 = OnTime4[0]*3600+OnTime4[1]*60+OnTime4[2];
long OnTime5[] = {0,0,0};
long OTS5 = OnTime5[0]*3600+OnTime5[1]*60+OnTime5[2];
long OnTime6[] = {0,0,0};
long OTS6 = OnTime6[0]*3600+OnTime6[1]*60+OnTime6[2];
long OnTime7[] = {0,0,0};
long OTS7 = OnTime7[0]*3600+OnTime7[1]*60+OnTime7[2];
long OnTime8[] = {18,0,30};
long OTS8 = OnTime8[0]*3600+OnTime8[1]*60+OnTime8[2];
long OnTime9[] = {18,0,0};
long OTS9 = OnTime9[0]*3600+OnTime9[1]*60+OnTime9[2];
long OnTime10[] = {0,0,0};
long OTS10 = OnTime10[0]*3600+OnTime10[1]*60+OnTime10[2];
long OnTime11[] = {0,0,0};
long OTS11 = OnTime11[0]*3600+OnTime11[1]*60+OnTime11[2];
long OnTime12[] = {18,0,10};
long OTS12 = OnTime12[0]*3600+OnTime12[1]*60+OnTime12[2];
long OnTime13[] = {18,0,20};
long OTS13 = OnTime13[0]*3600+OnTime13[1]*60+OnTime13[2];
long OnTime14[] = {0,0,0};
long OTS14 = OnTime14[0]*3600+OnTime14[1]*60+OnTime14[2];
long OnTime15[] = {0,0,0};
long OTS15 = OnTime15[0]*3600+OnTime15[1]*60+OnTime15[2];
long OnTime16[] = {0,0,0};
long OTS16 = OnTime16[0]*3600+OnTime16[1]*60+OnTime16[2];
//long OnTime[] = {30,35,00,0,0,0,0,0}; // array for duration each outlet will remain on in seconds
long OnTime[] = {OTS1, OTS2, OTS3, OTS4, OTS5, OTS6, OTS7, OTS8, OTS9, OTS10, OTS11, OTS12, OTS13, OTS14, OTS15, OTS16}; // array for duration each outlet will remain on in seconds
long i = 0; // used for the "for" statements (loops that cycle through all 8 relays).
void setup() {
Serial.begin(9600);
for (i = 0; i < 16; i++) { // set the pinMode to OUTPUT for the 8 pins that connect to the relays
pinMode(pinArray[i], OUTPUT);
}
}
void loop() {
CurrentSec = millis() / 1000;
if ((InitTime + CurrentSec) / CycleLen - Cycles >= 1)
{
++Cycles;
}
CurrentSecCalc = CurrentSec - Cycles * CycleLen + InitTime; // set this variable to the current Arduino time
for (i = 0; i < 16; i++) {
if ((relayStateArray[i] == LOW) && ((CurrentSecCalc >= StartTime[i] + OnTime[i]) or (CurrentSecCalc < StartTime[i]))) //if a rmax relay is on and reached the end of schedule
{ relayStateArray[i] = HIGH; // turn it off...
previousMillis[i] = CurrentSecCalc; // record the time of this change in state to the relay...
}
//when the first statement fials the relay either is still scheduled to stay on or is currently off
else if ((relayStateArray[i] == HIGH) && (CurrentSecCalc >= StartTime[i]) && (CurrentSecCalc <= + OnTime[i] + StartTime[i])) //If a relay is off and it is time to turn on...
{ relayStateArray[i] = LOW; // turn it on...
}//if conditions fail both statements the relay is off as scheduled
digitalWrite(pinArray[i], relayStateArray[i]); // the above just changes the value in the state array. This turns the relay on or off based on that value.
}
Serial.print(CurrentSecCalc/60);
Serial.print('\n');
/*Serial.print(Cycles);
Serial.print('\n');*/
}