Help with Switch/Case/Break statement



  • Hi,

    I'm working on building a pump to empty my De-humidifier for me automatically. I have the components connected, but I cannot get the Switch/Case statement to work/compile for me. I'm not sure where i'm going wrong. The compiler complains about a duplicate case, but i'm not sure why. I know it's in the LOW_WATER statement. This is the first time i've used this form of statement; i'm probably missing something small. Any help is appreciated.

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Automated Sump-Pump for De-Humidifier
     * 
     * PURPOSE:
     * To automatically when water is at a pre-set level, have small
     * sump pump engage and empty water until it hits the desired
     * level. Uses the NewPING Library with Ultrasonic Sensor HC-SR04
     * */
    
     // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 22 //or comment out for automatic
    // #define MY_REPEATER_FEATURE  // Enabled repeater feature for this node
    #include <SPI.h>
    #include <MySensors.h>
    #include <NewPing.h>
    
    unsigned long REPORT_TIME = 60000; // Sleep time between sensor readings
    #define RELAY_PIN 3 // To control the sump pump, define relay pin here.
    #define RELAY_ON HIGH
    #define RELAY_OFF LOW
    #define TRIGGER_PIN 4 //HC-SR04 Trgger Pin (Transmit)
    #define ECHO_PIN 5 //HC-SR04 Echo Pin (Receive)
    #define MAX_DISTANCE 50 //Maximum Distance for Sensor scan (tank depth) no more than 297fu
    #define RADIUS 15 //Radius of cylindrical bucket. Used for Flow calculations
    unsigned long SEND_FLOW = 0; // Trigger to send flow values to HA controller
    unsigned long WATER_VOLUME = 0;
    unsigned int Depth = 5;
    unsigned int HIGH_WATER = 5; // Distance from face of sensor to top of water at high point (when pump will engage)
    unsigned int LOW_WATER = 30; // Distance from face of sensor to top of water at low level (where pump will disengage)
    
    #define CHILD_ID_RELAY 0 //To allow manual control of the sump pump from HA controller
    #define CHILD_ID_DEPTH 1 // Used to show water depth.
    #define CHILD_ID_FLOW 2 // Sensor to send flow/water volume info
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum depth
    
    // MySensors Message Initialization
    
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    MyMessage msgDepth(CHILD_ID_DEPTH, V_DISTANCE);
    MyMessage msgPrefix(CHILD_ID_DEPTH, V_UNIT_PREFIX); //Adds SI unit (CM) for depth measurement.
    MyMessage msgFlow(CHILD_ID_FLOW, V_VOLUME); // Water flow info. In METRES!
    
    unsigned long previousDepth = 0; // For tracking report time
    
    void setup()
    {
      pinMode(RELAY_PIN, OUTPUT);
      digitalWrite(RELAY_PIN, LOW);
      send(msgPrefix.set("CM"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("DeHumidifierSumpPump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_RELAY, S_LIGHT);
      present(CHILD_ID_DEPTH, S_DISTANCE);
      present(CHILD_ID_FLOW, S_WATER);
      send(msgPrefix.set("CM"));
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    Depth = sonar.ping_cm();
    switch (Depth) {
      
      case '= LOW_WATER':
      digitalWrite(RELAY_PIN. RELAY_OFF);
      send(msgRelay.set (0));
      SEND_FLOW = 1;
      break;
      
      case '= HIGH_WATER':
      digitalWrite(RELAY_PIN, RELAY_ON);
      send(msgRelay.set(1));
      break;
    
      case '!= Depth':
      send(msgDepth.set(Depth));
      previousDepth = Depth;
      break;
    }
    if (RELAY_PIN == RELAY_OFF && Depth == LOW_WATER && SEND_FLOW == 1) {
       WATER_VOLUME = (((sq(RADIUS)) * 3.14) * (LOW_WATER - Depth) / 1000);
       send(msgFlow.set(WATER_VOLUME));
       SEND_FLOW = 0;
    }
     
    
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(RELAY_PIN, RELAY_ON);
         send(msgRelay.set(1));
         // Store state in eeprom
    //     saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

  • Mod

    It could be that my c programming skills are inadequate, but I have not seen case statements like that earlier. This is how they usually look:

    switch (Depth) {
      
      case LOW_WATER:
      digitalWrite(RELAY_PIN. RELAY_OFF);
      send(msgRelay.set (0));
      SEND_FLOW = 1;
      break;
      
      case HIGH_WATER:
      digitalWrite(RELAY_PIN, RELAY_ON);
      send(msgRelay.set(1));
      break;
    
      default:
      send(msgDepth.set(Depth));
      previousDepth = Depth;
      break;
    }
    

    What is the intention with the last case (!= Depth)? You are checking if the Depth variable is not equal to itself? When would that happen?


  • Admin

    You are using switch wrong here..

    1. you compare Depth (int) with a character (' '). (first two case is starting with an '=' so this is probably what triggers it).
    2. you can not use = / != in case statements.
    3. If a case is executed all others are ignored.
    4. switch / case is normally used with constants (for the case statements)

    I would suggest to rewrite it to use if sentences instead, as switches is not well suited for the purpose that you have.

    (Strings is denoted with double quotes ", while single quotes ' denotes a single character)

    for more info on switch / case, you could read this as a starter



  • @mfalkvidd

    I'm trying to set it up so that if the depth changes, it will report the new one back to the HA controller.

    @tbowmo

    I was working with the IF/Else statemetns at first, but my Arduino kept running the code and clogging my serial console and sending reports to my HA controller. I was going to use a sleep command to make it only check once every X seconds/minutes, but I wanted to be able to add a manual empty switch for emergency use. Since the If/Else was clogging the console, thought Switch/Case would work better.

    I'll keep looking into this. Thanks for the help.


  • Admin

    You have two states, right? High and low.

    High starts pump, and low stops it.

    Then make your code only transmit on state changes. And the depth indicator should only transmit when it's different from the one that got transmitted the last time. (on my phone so can't write that much code here)



  • @tbowmo

    Yes, high stats it low stops it.

    I have been working with the IF statements but I am still having an issue. I'm getting some weird behaviour with the code. When it first starts up and the ultrasonic sensor is more than ~5cm from an object, it works ok and the relay stays off. If I put something close in front of the sensor, the relay turns on but it keeps spamming the message to the gateway (even when it should not). Also, if you move that object away from the front of the ultrasonic sensor, the relay stays on.

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Automated Sump-Pump for De-Humidifier
     * 
     * PURPOSE:
     * To automatically when water is at a pre-set level, have small
     * sump pump engage and empty water until it hits the desired
     * level. Uses the NewPING Library with Ultrasonic Sensor HC-SR04
     * */
    
     // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 22 //or comment out for automatic
    // #define MY_REPEATER_FEATURE  // Enabled repeater feature for this node
    #include <SPI.h>
    #include <MySensors.h>
    #include <NewPing.h>
    
    #define RELAY_PIN 3 // To control the sump pump, define relay pin here.
    // #define RELAY_ON HIGH
    // #define RELAY_OFF LOW
    #define TRIGGER_PIN 4 //HC-SR04 Trgger Pin (Transmit)
    #define ECHO_PIN 5 //HC-SR04 Echo Pin (Receive)
    #define MAX_DISTANCE 100 //Maximum Distance for Sensor scan (tank depth) no more than 297f
    #define LOW_WATER 30 // Distance from face of sensor to top of water at low level (where pump will disengage)
    #define HIGH_WATER 5 // Distance from face of sensor to top of water at high point (when pump will engage)
    #define RADIUS 15 //Radius of cylindrical bucket. Used for Flow calculations
    unsigned long SEND_FLOW = 0; // Trigger to send flow values to HA controller
    unsigned long WATER_VOLUME = 0; // Just a place holder....
    unsigned long previousMillis = 0; //Tracks time list last depth report. 
    unsigned long reportMillis = 10000; //How often to do depth report
    long unsigned int Depth = 5;
    long unsigned int oldDepth = 0; //used to track transmission of water level on change only. 
    
    #define CHILD_ID_RELAY 0 //To allow manual control of the sump pump from HA controller
    #define CHILD_ID_DEPTH 1 // Used to show water depth.
    #define CHILD_ID_FLOW 2 // Sensor to send flow/water volume info
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum depth
    
    // MySensors Message Initialization
    
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    MyMessage msgDepth(CHILD_ID_DEPTH, V_DISTANCE);
    MyMessage msgPrefix(CHILD_ID_DEPTH, V_UNIT_PREFIX); //Adds SI unit (CM) for depth measurement.
    MyMessage msgVolume(CHILD_ID_FLOW, V_VOLUME); // Water flow info. In METRES!
    
    unsigned long previousReport = 0; // For tracking report time
    
    void setup()
    {
      pinMode(RELAY_PIN, OUTPUT);
      digitalWrite(RELAY_PIN, LOW);
      send(msgPrefix.set("CM"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("DeHumidifierSumpPump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_RELAY, S_LIGHT);
      present(CHILD_ID_DEPTH, S_DISTANCE);
      present(CHILD_ID_FLOW, S_WATER);
      send(msgPrefix.set("CM"));
    }
    
    void loop()
    {
      unsigned long currentMillis = millis();
      Depth = sonar.ping_cm();
      if  (Depth == HIGH_WATER){
      digitalWrite(RELAY_PIN, HIGH);
      send(msgRelay.set(1));
      SEND_FLOW = 1;
      }
      
      if ( (Depth == LOW_WATER) && SEND_FLOW == 1) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (LOW_WATER - Depth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
        SEND_FLOW = 0;
      }
    
      if ( (currentMillis - previousMillis) >= reportMillis) {
        send(msgDepth.set(Depth));
        send(msgPrefix.set("CM"));
        previousMillis = currentMillis;
    }
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(RELAY_PIN, HIGH);
         send(msgRelay.set(1));
         // Store state in eeprom
    //     saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

  • Contest Winner

    @drock1985 said:
    Try this , so add && SEND_FLOW == 0

    if  (Depth == HIGH_WATER && SEND_FLOW == 0) {
      digitalWrite(RELAY_PIN, HIGH);
      send(msgRelay.set(1));
      SEND_FLOW = 1;
     }
    


  • I think i've got it; but for some reason my sensor is a lot more sensitive when using my sketch versus the example one that came with the library. I can go to a reliable resolution of up to 2-5CM using the example sketch; and only ~10 (the cutoff limit I was using in the sketch) when all combined.

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Automated Sump-Pump for De-Humidifier
     * 
     * PURPOSE:
     * To automatically when water is at a pre-set level, have small
     * sump pump engage and empty water until it hits the desired
     * level. Uses the NewPING Library with Ultrasonic Sensor HC-SR04
     * */
    
     // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 22 //or comment out for automatic
    // #define MY_REPEATER_FEATURE  // Enabled repeater feature for this node
    #include <SPI.h>
    #include <MySensors.h>
    #include <NewPing.h>
    
    #define RELAY_PIN 3 // To control the sump pump, define relay pin here.
    // #define RELAY_ON HIGH
    // #define RELAY_OFF LOW
    #define TRIGGER_PIN 4 //HC-SR04 Trgger Pin (Transmit)
    #define ECHO_PIN 5 //HC-SR04 Echo Pin (Receive)
    #define MAX_DISTANCE 100 //Maximum Distance for Sensor scan (tank depth) no more than 297f
    int LOW_WATER = 2; // Distance from face of sensor to top of water at low level (where pump will disengage)
    int HIGH_WATER = 30; // Distance from face of sensor to top of water at high point (when pump will engage)
    int RADIUS = 15; //Radius of cylindrical bucket. Used for Flow calculations
    int bucketDepth = 30;
    int waterDepth = 5;
    unsigned long SEND_FLOW = 0; // Trigger to send flow values to HA controller
    unsigned long WATER_VOLUME = 0; // Just a place holder....
    unsigned long previousMillis = 0; //Tracks time list last depth report. 
    unsigned long reportMillis = 10000; //How often to do depth report
    long unsigned int Distance = 5;
    long unsigned int oldDepth = 0; //used to track transmission of water level on change only. 
    
    #define CHILD_ID_RELAY 0 //To allow manual control of the sump pump from HA controller
    #define CHILD_ID_DEPTH 1 // Used to show water depth.
    #define CHILD_ID_FLOW 2 // Sensor to send flow/water volume info
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum depth
    
    // MySensors Message Initialization
    
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    MyMessage msgDepth(CHILD_ID_DEPTH, V_DISTANCE);
    MyMessage msgPrefix(CHILD_ID_DEPTH, V_UNIT_PREFIX); //Adds SI unit (CM) for depth measurement.
    MyMessage msgVolume(CHILD_ID_FLOW, V_VOLUME); // Water flow info. In METRES!
    
    unsigned long previousReport = 0; // For tracking report time
    
    void setup()
    {
      pinMode(RELAY_PIN, OUTPUT);
      digitalWrite(RELAY_PIN, LOW);
      send(msgPrefix.set("CM"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("DeHumidifierSumpPump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_RELAY, S_LIGHT);
      present(CHILD_ID_DEPTH, S_DISTANCE);
      present(CHILD_ID_FLOW, S_WATER);
      send(msgPrefix.set("CM"));
    }
    
    void loop()
    {
      unsigned long currentMillis = millis();
      Distance = sonar.ping_cm();
      waterDepth = (bucketDepth - Distance);
      if  (waterDepth == HIGH_WATER && SEND_FLOW == 0){
      digitalWrite(RELAY_PIN, HIGH);
      send(msgRelay.set(1));
      SEND_FLOW = 1;
      }
      
      else if ( (waterDepth <= LOW_WATER) && SEND_FLOW == 1) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (bucketDepth - waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
        SEND_FLOW = 0;
      }
    
      else if ( (currentMillis - previousMillis) >= reportMillis) {
        send(msgDepth.set(Distance));
        send(msgPrefix.set("CM"));
        previousMillis = currentMillis;
      }
     else if ((RELAY_PIN == HIGH) && (waterDepth == LOW_WATER)) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (bucketDepth - waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
     }
    }
    
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if ((message.type==V_LIGHT) && (waterDepth != LOW_WATER)) {
         // Change relay state
         digitalWrite(RELAY_PIN, HIGH);
         send(msgRelay.set(1));
         // Store state in eeprom
    //     saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    


  • Ok, did a bit more digging. I think I finally got this.

    Mixed up in my mind how I wanted to measure the water level. Think I have the logic finally figured out in my illogical head.

    Thanks for all the help guys; good to network brains every once in while 🙂

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Automated Sump-Pump for De-Humidifier
     * 
     * PURPOSE:
     * To automatically when water is at a pre-set level, have small
     * sump pump engage and empty water until it hits the desired
     * level. Uses the NewPING Library with Ultrasonic Sensor HC-SR04
     * */
    
     // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 22 //or comment out for automatic
    // #define MY_REPEATER_FEATURE  // Enabled repeater feature for this node
    #include <SPI.h>
    #include <MySensors.h>
    #include <NewPing.h>
    
    #define RELAY_PIN 3 // To control the sump pump, define relay pin here.
    #define TRIGGER_PIN 4 //HC-SR04 Trgger Pin (Transmit)
    #define ECHO_PIN 5 //HC-SR04 Echo Pin (Receive)
    #define MAX_DISTANCE 100 //Maximum Distance for Sensor scan (tank depth) no more than 297f
    int LOW_WATER = 2; // 
    int HIGH_WATER = 20; // 
    int RADIUS = 15; //Radius of cylindrical bucket. Used for Flow calculations
    int bucketDepth = 30;
    int waterDepth = 5;
    unsigned long SEND_FLOW = 0; // Trigger to send flow values to HA controller
    unsigned long WATER_VOLUME = 0; // Just a place holder....
    unsigned long previousMillis = 0; //Tracks time list last depth report. 
    unsigned long reportMillis = 10000; //How often to do depth report
    long unsigned int Distance = 5;
    long unsigned int oldDepth = 0; //used to track transmission of water level on change only. 
    
    #define CHILD_ID_RELAY 0 //To allow manual control of the sump pump from HA controller
    #define CHILD_ID_DEPTH 1 // Used to show water depth.
    #define CHILD_ID_FLOW 2 // Sensor to send flow/water volume info
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum depth
    
    // MySensors Message Initialization
    
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    MyMessage msgDepth(CHILD_ID_DEPTH, V_DISTANCE);
    MyMessage msgPrefix(CHILD_ID_DEPTH, V_UNIT_PREFIX); //Adds SI unit (CM) for depth measurement.
    MyMessage msgVolume(CHILD_ID_FLOW, V_VOLUME); // Water flow info. In METRES!
    
    unsigned long previousReport = 0; // For tracking report time
    
    void setup()
    {
      pinMode(RELAY_PIN, OUTPUT);
      digitalWrite(RELAY_PIN, LOW);
      send(msgPrefix.set("CM"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("DeHumidifierSumpPump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_RELAY, S_LIGHT);
      present(CHILD_ID_DEPTH, S_DISTANCE);
      present(CHILD_ID_FLOW, S_WATER);
      send(msgPrefix.set("CM"));
    }
    
    void loop()
    {
      unsigned long currentMillis = millis();
      Distance = sonar.ping_cm();
      waterDepth = (bucketDepth - Distance);
      if  (waterDepth >= HIGH_WATER && SEND_FLOW == 0){
      digitalWrite(RELAY_PIN, HIGH);
      send(msgRelay.set(1));
      SEND_FLOW = 1;
      }
      
      else if ( (waterDepth <= LOW_WATER) && SEND_FLOW == 1) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (bucketDepth - waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
        SEND_FLOW = 0;
      }
    
      else if ( (currentMillis - previousMillis) >= reportMillis) {
        send(msgDepth.set(Distance));
        send(msgPrefix.set("CM"));
        previousMillis = currentMillis;
      }
     else if ((RELAY_PIN == HIGH) && (waterDepth <= LOW_WATER)) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        Distance = sonar.ping_cm();
        waterDepth = (bucketDepth - Distance);
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (bucketDepth - waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
     }
     wait(100);
    }
    
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if ((message.type==V_LIGHT) && (waterDepth != LOW_WATER)) {
         // Change relay state
         digitalWrite(RELAY_PIN, HIGH);
         send(msgRelay.set(1));
         // Store state in eeprom
    //     saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

  • Admin

    @drock1985

    I see a couple of issues with the code in your loop() function

    First off, you need to use digitalRead(RELAY_PIN) == HIGH to get the state of the relay pin, instead of RELAY_PIN == HIGH.

    Another thing, the last else if() will never be called, since you set RELAY_PIN low, earlier in your code when water level is below LOW_WATER, so it will always be low when you reach the last if clause.

    Also, I would suggest you report water volume every time I report distance, as they are related. (right now you only report when the water is below LOW_WATER level)

    Below routine will check water levels, and control relay based on that, and always report back depth / volume, regardless of pump is active or not. (then you can also check how fast it increase / decrease)

    I would suggest that you set the wait() time to a larger value than 100 (right now, it's set to check every 100mS, which is a bit too frequent in my opinion..)

    void loop()
    {
      unsigned long currentMillis = millis();
      Distance = sonar.ping_cm();
      waterDepth = (bucketDepth - Distance);
      if  (waterDepth >= HIGH_WATER && SEND_FLOW == 0){
        digitalWrite(RELAY_PIN, HIGH);
        send(msgRelay.set(1));
        SEND_FLOW = 1;
      }
      else if ( (waterDepth <= LOW_WATER) && SEND_FLOW == 1) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        SEND_FLOW = 0;
      }
    
      if ( (currentMillis - previousMillis) >= reportMillis) {
        send(msgDepth.set(Distance));
        send(msgPrefix.set("CM"));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (bucketDepth - waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
        previousMillis = currentMillis;
      }
    
     wait(100);
    }
    


  • @tbowmo

    Thanks for the help. I see now where I was going wrong. I have everything working as expected. The only thing I needed to do was add some special commands to the message statement. For some reason, the relay would not turn off when the water low level was reached; used this below as a counter for now.

    Thanks again.

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     * 
     * DESCRIPTION
     * Automated Sump-Pump for De-Humidifier
     * 
     * PURPOSE:
     * To automatically when water is at a pre-set level, have small
     * sump pump engage and empty water until it hits the desired
     * level. Uses the NewPING Library with Ultrasonic Sensor HC-SR04
     * */
    
     // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 22 //or comment out for automatic
    // #define MY_REPEATER_FEATURE  // Enabled repeater feature for this node
    #include <SPI.h>
    #include <MySensors.h>
    #include <NewPing.h>
    
    #define RELAY_PIN 3 // To control the sump pump, define relay pin here.
    #define TRIGGER_PIN 4 //HC-SR04 Trgger Pin (Transmit)
    #define ECHO_PIN 5 //HC-SR04 Echo Pin (Receive)
    #define MAX_DISTANCE 100 //Maximum Distance for Sensor scan (tank depth) no more than 297f
    int LOW_WATER = 2; // 
    int HIGH_WATER = 20; // 
    int RADIUS = 15; //Radius of cylindrical bucket. Used for Flow calculations
    int bucketDepth = 30;
    int waterDepth = 5;
    unsigned long SEND_VOLUME = 0; // Trigger to send flow values to HA controller
    unsigned long WATER_VOLUME = 0; // Just a place holder....
    unsigned long previousMillis = 0; //Tracks time list last depth report. 
    unsigned long reportMillis = 10000; //How often to do depth report
    unsigned long manualWait = 20000; //Time for manual pump on action. 20 seconds default (to avoid pump dryout)
    long unsigned int Distance = 5;
    long unsigned int oldDepth = 0; //used to track transmission of water level on change only. 
    
    #define CHILD_ID_RELAY 0 //To allow manual control of the sump pump from HA controller
    #define CHILD_ID_DEPTH 1 // Used to show water depth.
    #define CHILD_ID_VOLUME 2 // Sensor to send Water Volume info
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum depth
    
    // MySensors Message Initialization
    
    MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);
    MyMessage msgDepth(CHILD_ID_DEPTH, V_DISTANCE);
    MyMessage msgPrefix(CHILD_ID_DEPTH, V_UNIT_PREFIX); //Adds SI unit (CM) for depth measurement.
    MyMessage msgVolume(CHILD_ID_VOLUME, V_VOLUME); // Water volume info. In Metres cubed
    
    unsigned long previousReport = 0; // For tracking report time
    
    void setup()
    {
      pinMode(RELAY_PIN, OUTPUT);
      digitalWrite(RELAY_PIN, LOW);
      send(msgPrefix.set("CM"));
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("DeHumidifierSumpPump", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_RELAY, S_LIGHT);
      present(CHILD_ID_DEPTH, S_DISTANCE);
      present(CHILD_ID_VOLUME, S_WATER);
      send(msgPrefix.set("CM"));
    }
    
    void loop()
    {
      unsigned long currentMillis = millis();
      Distance = sonar.ping_cm();
      waterDepth = (bucketDepth - Distance);
      
      if  (waterDepth >= HIGH_WATER && SEND_VOLUME == 0){
        digitalWrite(RELAY_PIN, HIGH);
        send(msgRelay.set(1));
        SEND_VOLUME = 1;
      }
      else if ( (waterDepth <= LOW_WATER) && SEND_VOLUME == 1 ) {
        digitalWrite(RELAY_PIN, LOW);
        send(msgRelay.set (0));
        SEND_VOLUME = 0;
      }
    
      if ( (currentMillis - previousMillis) >= reportMillis) {
        send(msgDepth.set(Distance));
        send(msgPrefix.set("CM"));
        WATER_VOLUME = ((((sq(RADIUS)) * 3.14) * (waterDepth)) / 1000);
        send(msgVolume.set(WATER_VOLUME));
        previousMillis = currentMillis;
      }
    
     wait(reportMillis);
    }
    
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if ((message.type==V_LIGHT) && (waterDepth >= LOW_WATER)) {
         // Change pump state for 20 seconds. 
         digitalWrite(RELAY_PIN, HIGH);
         send(msgRelay.set(1));
         wait(manualWait);
         digitalWrite(RELAY_PIN, LOW);
         send(msgRelay.set(0));
       } 
    }
    

 

445
Online

7.9k
Users

8.8k
Topics

93.8k
Posts