Relay override - which method would be recommended

…to protect my plants from flooding?
Which methodology would you recommend me to activate a relay only a few minutes to protect the plants, even if the sensor values have not yet reached the threshold for automatic shutdown.
Do I solve this with a callback, a software timer, interrupt or the time?

  if ((water.toInt() >= pump_threshold) && (distance <= tank_threshold)) 
        {
        Serial.println("Too dry, we should water it.");
        digitalWrite(relayPin, HIGH); // relay start
        digitalWrite(internalLED, HIGH);
        lcd->clear();
        lcd->setCursor(0 /*columns*/,0 /*rows*/);
        lcd->noBlink();
        lcd->print("Trocken: "); lcd->print(water); lcd->print("/"); lcd->print(pump_threshold); lcd->print("%");
        lcd->setCursor(4, 1);
        lcd->blink();
        lcd->print("WATERING");
        Blynk.virtualWrite(V7, "...WATERING...");
        }

Suggestion:
if (digitalWrite(relayPin, HIGH)) > 1 Minute activated) {
digitalWrite(relayPin, LOW); // stop relay before plants need to learn swimming
}

Can anybody translate my suggestion? My Photon dont understand me atm.

I use a timer.

I use a Particle.function() to turn the relay on, trigger the timer to shut it off after 30 seconds. This still doesn’t guarantee it really shuts it off. :slight_smile: That trust I put on the base firmware and hardware.

Note: I setup the timer as a one shot. Set it to run, it will fire off only once.

REF: Software Timers

// Define a Relay object
RelayShield ghRelays;

// Timer to automatically turn Relay 1 off when
// it is turned on
Timer ghTimer(30000, turnRelay1Off, true);

// Automatically turn relay #1 off after the
// specified time interval.
void turnRelay1Off() {
  ghRelays.off(1);
}

// Handler for a remote command from the
// Particle Cloud.  Return 1 upon success or
// 0 for no effect.
int remoteCmd(String command) {
    if (command == "r1on") {
      ghRelays.on(1);
      ghTimer.start();
    }
}

void setup () {
  // Register Particle functions
  // Allow us to send remote commands
  Particle.function("cmd", remoteCmd);
}
1 Like

Depending on the actual risk you got a whole lot of options but for mission critical tasks I’d have multiple levels of self-check logic in my code but would also add HW fallback like an extern HW watchdog and/or a HW timed off switch and a proper HW state check of the relay.

3 Likes

Thx for your feedback: do I think to easy? My onTimeout() will not fire in my case.
in the definitions on top:

Timer relayTimer(10000, onTimeout, readData); // after 10 sec should relay go off, move forward with reading fresh sensor values

in executeRelay():

  if ((water.toInt() >= pump_threshold) && (distance <= tank_threshold)) 
  {
    Serial.println("Too dry, we should water it.");
    digitalWrite(relayPin, HIGH); // relay start
    digitalWrite(internalLED, HIGH);
    lcd->print("WATERING");
    Blynk.virtualWrite(V7, "...WATERING...");
        // Timer to automatically turn Relay off after 10 Sek 
    relayTimer.start(); // starts timer if stopped or resets it if started.
    if (relayTimer.isActive()) {
      Blynk.virtualWrite(V7, "...WATERING - Timer activated...");
    }
// Automatically turn relay #1 off after the specified time interval.
  void onTimeout() {
            Blynk.virtualWrite(V7, "Timer set Relay off");
            digitalWrite(relayPin, LOW); 
            digitalWrite(internalLED, LOW);
  }

Is this third parameter in the Timer instantiation a boolean and set to true?
I also suspect that you’ll enter the conditional block multiple times always restarting the timer, never allowing it to timeout unless the condition actually equates to false.

Yes, the interval of the loop was set to 2 seconds, so the timer with 10 seconds had no chance to execute. Thx!
I will try it with the current time plus 10 seconds and then with a Goto that jump mark on onTimeout().

I also wouldn’t do any heavy lifting in the timer. Try setting a flag and action on that in the loop.

With my code the photon gots “panik - stack overflow”:

// declation:
    Timer relayTimer(30000, relayTurnOff, true);
    bool activeTimer = false;

// go Watering
        if ((water.toInt() >= pump_threshold) && (distance <= tank_threshold) && (activeTimer == false)) 
        {
 
        digitalWrite(relayPin, HIGH); // relay start
        digitalWrite(internalLED, HIGH);
        Blynk.virtualWrite(V7, "...WATERING...");
        
        relayTimer.start();
        if (relayTimer.isActive()) {
            activeTimer = true;
        }

void relayTurnOff()
   {
    digitalWrite(relayPin, LOW);
    digitalWrite(internalLED, LOW);
    activeTimer = false;
    Blynk.virtualWrite(V7, "...Timer turns off the Relay..."); 
   } 

It works how expected but only because my Photon flashes red and restart :wink:
Other ideas to disable a relay after 30 seconds?
https://go.particle.io/shared_apps/5957da17a33884bf98000216

As I said in our PM discussion a few hours ago: “Get rid of the Blynk call”, to start with :wink:

And I would also have that activeTimee = true; unconditionally just for the odd chance that relayTimer.isActive() won’t be set true fast enough.

2 Likes

Ok - Thank you for your feedback - me today with the software timer extensively busy and it also finished with timers for my requirements.