0

This works but I would like to have a timed failsafe...

If the FLOAT_PIN goes LOW for more than 3 seconds, it will turn SOLENOID_PIN to LOW.

I can't figure out how to incorporate it into my loop. I tried delay() and started playing with millis() but all I keep finding is LED blinking samples...

I'm not very good with C++ - still learning.

const int FLOAT_PIN = 8; // Pin connected to FLOAT switch
const int SOLENOID_PIN = A0; // SOLENOID pin - active-high

void setup() {
  Serial.begin(9600);
  // Since the other end of the FLOAT switch is connected to ground, we need
  // to pull-up the FLOAT switch pin internally.
  pinMode(FLOAT_PIN, INPUT_PULLUP);
  pinMode(SOLENOID_PIN, OUTPUT);
}

void loop() {
  int floatswitch = digitalRead(FLOAT_PIN); // Read the state of the float switch

  if (floatswitch == HIGH) {
    // If the pin reads high, water is OFF.
    Serial.println("Switch closed");
    digitalWrite(SOLENOID_PIN, HIGH); // Turn the SOLENOID on
  } else {
    digitalWrite(SOLENOID_PIN, LOW); // Turn the SOLENOID off
  }
}
  • use a flag floatFlag.... if floatSwitch == high and floatFlag == false (floatFlag = true; tim = currentTime;) ...... if floatSwitch == low (floatFlag == false) ....... if floatFlag == true and currentTime == tim +3 seconds (turn on valve) – jsotola Dec 31 '17 at 3:09
  • Also asked at: forum.arduino.cc/index.php?topic=519688 If you're going to do that then please be considerate enough to add links to the other places you cross posted. This will let us avoid wasting time due to duplicate effort and also help others who have the same questions and find your post to discover all the relevant information. – per1234 Dec 31 '17 at 3:42
2

This is one of those cases when thinking in terms of a finite state machine makes the programming quite straightforward. Here I would use three states:

  • In the OFF state, the switch is LOW and the solenoid is off
  • in the ON state, the switch is HIGH and the solenoid is on
  • in the DELAYING state, the switch is LOW, but the program is keeping the switch HIGH for three seconds.

The possible transitions are:

  • OFFON when the switch goes HIGH
  • ONDELAYING when the switch goes LOW
  • DELAYINGOFF after three second in this state
  • DELAYINGON when the switch goes HIGH.

The last transition is meant to ensure that LOW states of the switch that last less than three seconds do not turn the solenoid off.

And here is a tentative implementation. Keep your constants and your setup(), and replace your loop() with this:

const uint32_t DELAY_TIME = 3000;  // time to deay the -> off transition

void loop() {
    static enum {OFF, ON, DELAYING} state;
    static uint32_t start_delay;
    int floatswitch = digitalRead(FLOAT_PIN);

    switch (state) {
        case OFF:
            if (floatswitch == HIGH) {
                Serial.println("Switch closed");
                digitalWrite(SOLENOID_PIN, HIGH); // Turn the SOLENOID on
                state = ON;
            }
            break;
        case ON:
            if (floatswitch == LOW) {
                start_delay = millis();
                state = DELAYING;
            }
            break;
        case DELAYING:
            if (floatswitch == HIGH) {
                state = ON;
            }
            else if (millis() - start_delay >= DELAY_TIME) {
                digitalWrite(SOLENOID_PIN, LOW); // Turn the SOLENOID off
                state = OFF;
            }
            break;
    }
}
  • think its backwards. Worked but backwards, it's preventing it from turning off for 3 seconds, rather then turning off if its on for more then 3 seconds. – Mike S Jan 1 '18 at 21:35
  • no matter what I do it works one way but not the other... not sure what i did wrong. – Mike S Jan 1 '18 at 21:45
  • @MikeS: I can't understand your comment “it's preventing it from turning off for 3 seconds, rather then turning off if its on for more then 3 seconds”. I wrote this answer to match your question as written. If this is not the behavior you expect, please, edit your question with a more explicit description of your expectations. – Edgar Bonet Jan 1 '18 at 23:14
  • your example works, but not as intended. Float goes low, turn on solenoid, Float goes high, turns off solenoid but delays 3 seconds once Float is high. The logic about is right, not sure if your states are written correctly. Can it be written outside the loop that Solenoid can only be high for X seconds (no matter the output of the FLOAT?) – Mike S Jan 2 '18 at 2:02
  • @MikeS: This works exactly as intended – as I intended it to work based on my understanding of your question. I assume you didn't read my last comment, so let me repeat: please, update your question and add an explicit and clear description of the behaviour you expect. – Edgar Bonet Jan 2 '18 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.