I'm making a plant watering project. I started pretty simple, each plant gets watered for a set amount of time, then two days later the program resets the Nano and it starts over. The problem is that sometimes it leaves relays open, causing double or triple activations of the relays.
Below is a simplified version of my code. Every once in a while the first relay led will blink 3 times instead of once and moving on to the next. The puzzling part is that it only happens maybe 1 out of 10 times. Any suggestions?
int motorPower = 2;
int valve1 = 3;
int valve2 = 4;
int valve3 = 5;
int valve4 = 6;
const long interval1 = 1000;
const long interval2 = interval1+1000;
const long interval3 = interval2+1000;
const long interval4 = interval3+1000;
const long interval5 = interval4+1000;
const long interval6 = interval5+1000;
const long interval7 = interval6+1000;
const long interval8 = interval7+1000;
const long interval9 = 172800000;
boolean valveCheck = false;
boolean motorOn = false;
boolean motorOff = false;
boolean openV1 = false;
boolean closeV1 = false;
boolean openV2 = false;
boolean closeV2 = false;
boolean openV3 = false;
boolean closeV3 = false;
boolean openV4 = false;
boolean closeV4 = false;
void(* resetFunc) (void) = 0;
void setup() {
pinMode(2, OUTPUT);
digitalWrite(motorPower, HIGH);
pinMode(3, OUTPUT);
digitalWrite(valve1, HIGH);
pinMode(4, OUTPUT);
digitalWrite(valve2, HIGH);
pinMode(5, OUTPUT);
digitalWrite(valve3, HIGH);
pinMode(6, OUTPUT);
digitalWrite(valve4, HIGH);
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long currentMillis = millis();
if (!valveCheck && currentMillis > 500){
digitalWrite(motorPower, HIGH);
digitalWrite(valve1, HIGH);
digitalWrite(valve2, HIGH);
digitalWrite(valve3, HIGH);
digitalWrite(valve4, HIGH);
valveCheck = true;
}
//Here is where the inadvertent loop/repeat starts after a 1 second pause
//valve 1
if (currentMillis >= interval1 && !openV1 && !closeV1) {
openV1 = true;
digitalWrite(motorPower, LOW);
digitalWrite(valve1, LOW);
}
if (currentMillis >= interval2 && openV1 && !closeV1) {
openV1 = false;
closeV1 = true;
digitalWrite(valve1, HIGH);
}
//Here is where the inadvertent loop/repeat ends
//valve 2
if (currentMillis >= interval3 && !openV2 && !closeV2) {
openV2 = true;
digitalWrite(valve2, LOW);
}
if (currentMillis >= interval4 && openV2 && !closeV2) {
openV2 = false;
closeV2 = true;
digitalWrite(valve2, HIGH);
}
//valve 3
if (currentMillis >= interval5 && !openV3 && !closeV3) {
openV3 = true;
digitalWrite(valve3, LOW);
}
if (currentMillis >= interval6 && openV3 && !closeV3) {
openV3 = false;
closeV3 = true;
digitalWrite(valve3, HIGH);
}
//valve 4
if (currentMillis >= interval7 && !openV4 && !closeV4) {
openV4 = true;
digitalWrite(valve4, LOW);
}
if (currentMillis >= interval8 && openV4 && !closeV4) {
openV4 = false;
closeV4 = true;
digitalWrite(valve4, HIGH);
digitalWrite(motorPower, HIGH);
}
//reset
if (currentMillis >= interval9) {
resetFunc();
}
}```
Later I will be adding other peripherals to the setup that may need to run async, so I'm using millis() for timing instead of delay(). This will potentially be running for months at a time, and millis() will overflow back to zero in 50 days. If I reset the controller every two days (the timing I need to rewater the plants), I don't need to worry about accounting for the 50 day issue.
I agree that the way I am tackling this is non-ideal. Eventually it will be hooked up to a Pi, so the timing will be controlled there, and it will be easier to schedule the tasks.
Back to the root question, why would it run the valve 1 actuation code anywhere between 1 and 3 times? The reset isn't until much later, and it doesn't make sense to me that it seems to happen randomly. Also, after it passes valve 1, the rest of the code works fine.
The code is odd but should not behave unpredictably. Forcing a system restart to reset the millis() counter is not normal practice.
More likely the unwanted repetition is due to the switching of the loads causing a brown out.
Schematic:
12V 3A supply to distribution block
12V and grd to relay board from distribution block
5V and grd from relay board to Nano
D2-D6 signals from Nano to relay board for relays 2-6 control
12V from distribution block to relays. When activated via signals they power the valves and pump (motor in code)
Grd from distribution block to each valve
It is worth noting that this issue was occurring when it was only the Nano hooked up to the relays with no other equipment hooked up. Being a new member, I am limited in the number of links I can post.
Yes, 5V from the relay board to the Nano 5V pin. The relay board supplies steady 5V from one of it's pins, as well as an appropriate ground. 6v6gt had mentioned that it looks like the diodes are built into the relay board. All values are DC.
Correct, if coded like that, you will get the rollover problem after 49 days or whatever. But like this if (millis() - previousMillis >= interval) it will be fine.