Low voltage disconnect

I have a solar panel charging a battery and several loads attached to it. I would like to disconnect the load after the voltage drops to and remains below a low value for a period of 3 minutes. If the voltage rises above the low value during the 3 minutes , the timer would be reset.
The load would not connect again until the battery remained above a high value for 4 minutes.

This is the code for 1 relay . I am planning to have a total of 5 relays all with different voltage limits. I'm not sure if this is the correct way to accomplish what I want .

/*-----( Declare Constants )-----*/
//set pins
const int voltageIn = A0;
const int relay1 = 2;

//set voltage range of relay
const int Off_VoltageRelay1 = 24.3;
const int On_VoltageRelay1 = 28.0;

/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 16 chars 2 line display or 0x3F

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

/*-----( Declare Variables )-----*/
int val1 = 0;

void setup()
  pinMode(relay1, OUTPUT);

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight

  // ------- Quick 3 blinks of backlight  -------------
  for (int i = 0; i < 3; i++)
  lcd.backlight(); // finish with backlight on

  //-------- Write characters on the display ------------------
  // NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.setCursor(0, 0);
  lcd.print("Battery Voltage");
  lcd.setCursor(0, 1);
  lcd.print("Load Controller");

}/*--(end setup )---*/

void loop()
    // read the input on analog pin 0:
    int inputVoltage = analogRead(voltageIn);
    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 40V):
    float voltage = inputVoltage * (40 / 1023.0);

    //if voltage is below Lo limit turn relay OFF
    //if voltage is above Hi limit turn relay ON
    if (voltage < Off_VoltageRelay1)
      delay (60000);
    if (voltage < Off_VoltageRelay1)
      delay (60000);
    if (voltage < Off_VoltageRelay1)
      delay (60000);
    if (voltage < Off_VoltageRelay1)
      digitalWrite (relay1, LOW);

    if (voltage > On_VoltageRelay1)
      delay (60000);
    if (voltage > On_VoltageRelay1)
      delay (60000);
    if (voltage > On_VoltageRelay1)
      delay (60000);
    if (voltage > On_VoltageRelay1)
      delay (60000);
    if (voltage > On_VoltageRelay1)
      digitalWrite (relay1, HIGH);

and remains below a low value

Your code does not read the voltage during those 3 minutes. You can't be sure that it remains below during that time.

In Examples/Digital, you will Find BlinkWithoutDelay. Take a look at it. It will help you in your endeavour.


I will take a look at the example. I would like to read the voltage during the 3 minutes to be sure it doesn't go above the value.

Decided to rewrite the program using smoothing. Looks like it will work so far.

You need to model states - your criterion for disconnect is stateful, it depends on the history, not just the
current values.

There are three notional states, I'll call them 'normal', 'temporary-overload', 'tripped'

Whenever you read a current below the limit, and the state is not 'tripped', state should become 'normal'

Whenever state is 'normal' and you read a current over the limit, state goes to 'temporary-overload' and you record the time of this transistion.

Whenener the state is 'temporary-overload' and the time since that recorded transition is 3 minutes or more,
change to 'tripped' and kill the switch.