Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. having trouble with water flow sensor + relay + moisture

having trouble with water flow sensor + relay + moisture

Scheduled Pinned Locked Moved Troubleshooting
4 Posts 3 Posters 874 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tsunami
    wrote on last edited by tsunami
    #1

    Hi, I've build my own node with mqtt to send waterflow sensor and DHT22 and moisture data to Domoticz and have one Relay to control. but both relay and waterflow sketches has receive function and when I write both of them in one function, relay doesn't show up in domoticz devices or hardware(child node);
    here is my code:

    #include <DHT.h>
    #include <SPI.h>
    #define DHT_DATA_PIN 6
    #define SENSOR_TEMP_OFFSET 0
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    static const uint64_t UPDATE_INTERVAL = 5000;
    
    #define MY_RADIO_NRF24
    #define MY_RF24_PA_LEVEL RF24_PA_MAX
    #define MY_REPEATER_FEATURE
    #define MY_NODE_ID 1
    
    #include <MySensors.h>  
    
    
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    
    #define CHILD_ID_MOISTURE 2
    #define CHILD_ID_HUM 3
    #define CHILD_ID_TEMP 4
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    
    MyMessage msgMoisture(CHILD_ID_MOISTURE, V_HUM);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    
    static int sensorValue;
    int soilPin = A0;
    int soilPower = 5;
    
    
    #define DIGITAL_INPUT_SENSOR 3                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
    
    #define PULSE_FACTOR 450000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
    
    #define SLEEP_MODE false                        // flowvalue can only be reported when sleep mode is false.
    
    #define MAX_FLOW 30                             // Max flow (l/min) value to report. This filters outliers.
    
    #define CHILD_ID_WATER 1
    
    uint32_t SEND_FREQUENCY =
        5000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
        
    
    MyMessage flowMsg(CHILD_ID_WATER,V_FLOW);
    MyMessage volumeMsg(CHILD_ID_WATER,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID_WATER,V_VAR1);
    
    double ppl = ((double)PULSE_FACTOR)/1000;        // Pulses per liter
    
    volatile uint32_t pulseCount = 0;
    volatile uint32_t lastBlink = 0;
    volatile double flow = 0;
    bool pcReceived = false;
    uint32_t oldPulseCount = 0;
    uint32_t newBlink = 0;
    double oldflow = 0;
    double volume =0;
    double oldvolume =0;
    uint32_t lastSend =0;
    uint32_t lastPulse =0;
    
    void before()
    {
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        // Then set relay pins in output mode
        pinMode(pin, OUTPUT);
        // Set relay to last known state (using eeprom storage)
        digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
      }
    }
    
    void presentation()
    {
     sendSketchInfo("Smart Irrigation System", "1.0");
      present(CHILD_ID_MOISTURE, S_MOISTURE);
      present(CHILD_ID_WATER, S_WATER);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
    
      metric = getControllerConfig().isMetric;
      
      for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
      present(sensor, S_BINARY);
      }
    
    }
    
    void setup()
    {
      pinMode(soilPower, OUTPUT);//Set D6 as an OUTPUT
      // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
      pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
    
      pulseCount = oldPulseCount = 0;
    
      // Fetch last known pulse count value from gw
      request(CHILD_ID_WATER, V_VAR1);
    
      lastSend = lastPulse = millis();
    
      attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING);
    
       dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      }
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
      sleep(dht.getMinimumSamplingPeriod());
    }
    
    void loop()
    {
    
       // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
    
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
    
        #ifdef MY_DEBUG
        Serial.print("H: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(UPDATE_INTERVAL); 
     //......................................................
      uint32_t currentTime = millis();
    
      // Only send values at a maximum frequency or woken up from sleep
      if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) {
        lastSend=currentTime;
    
        if (!pcReceived) {
          //Last Pulsecount not yet received from controller, request it again
          request(CHILD_ID_WATER, V_VAR1);
          return;
        }
    
        if (!SLEEP_MODE && flow != oldflow) {
          oldflow = flow;
    
          Serial.print("l/min:");
          Serial.println(flow);
    
          // Check that we dont get unresonable large flow value.
          // could hapen when long wraps or false interrupt triggered
          if (flow<((uint32_t)MAX_FLOW)) {
            send(flowMsg.set(flow, 2));                   // Send flow value to gw
          }
        }
    
        // No Pulse count received in 2min
        if(currentTime - lastPulse > 120000) {
          flow = 0;
        }
    
        // Pulse count has changed
        if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
          oldPulseCount = pulseCount;
    
          Serial.print("pulsecount:");
          Serial.println(pulseCount);
    
          send(lastCounterMsg.set(pulseCount));                  // Send  pulsecount value to gw in VAR1
    
          double volume = ((double)pulseCount/((double)PULSE_FACTOR));
          if ((volume != oldvolume)||(!SLEEP_MODE)) {
            oldvolume = volume;
    
            Serial.print("volume:");
            Serial.println(volume, 3);
    
            send(volumeMsg.set(volume, 3));               // Send volume value to gw
          }
        }
      }
      if (SLEEP_MODE) {
        sleep(SEND_FREQUENCY);
      }
        soilmoisture();
    }
    
    void soilmoisture()
    {
      digitalWrite(soilPower, HIGH);
    delay(10);//wait 10 milliseconds
    sensorValue = analogRead(soilPin);
    digitalWrite(soilPower, LOW);
    sensorValue = map(sensorValue, 0, 680, 0, 100);
      send(msgMoisture.set(sensorValue));
        sleep(SEND_FREQUENCY);
    }
    
    void receive(const MyMessage &message)
    {
      if (message.type==V_VAR1) {
        uint32_t gwPulseCount=message.getULong();
        pulseCount += gwPulseCount;
        flow=oldflow=0;
        Serial.print("Received last pulse count from gw:");
        Serial.println(pulseCount);
        pcReceived = true;
      }
    
      if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
    }
    }
    
    
    void onPulse()
    {
      if (!SLEEP_MODE) {
        uint32_t newBlink = micros();
        uint32_t interval = newBlink-lastBlink;
    
        if (interval!=0) {
          lastPulse = millis();
          if (interval<500000L) {
            // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
            return;
          }
          flow = (60000000.0 /interval) / ppl;
        }
        lastBlink = newBlink;
      }
      pulseCount++;
    }
    
    

    anyone can help me?
    and any suggestion to clean up my code?
    thanks in advanced.

    mfalkviddM 1 Reply Last reply
    0
    • T tsunami

      Hi, I've build my own node with mqtt to send waterflow sensor and DHT22 and moisture data to Domoticz and have one Relay to control. but both relay and waterflow sketches has receive function and when I write both of them in one function, relay doesn't show up in domoticz devices or hardware(child node);
      here is my code:

      #include <DHT.h>
      #include <SPI.h>
      #define DHT_DATA_PIN 6
      #define SENSOR_TEMP_OFFSET 0
      static const uint8_t FORCE_UPDATE_N_READS = 10;
      static const uint64_t UPDATE_INTERVAL = 5000;
      
      #define MY_RADIO_NRF24
      #define MY_RF24_PA_LEVEL RF24_PA_MAX
      #define MY_REPEATER_FEATURE
      #define MY_NODE_ID 1
      
      #include <MySensors.h>  
      
      
      #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      #define NUMBER_OF_RELAYS 1 // Total number of attached relays
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      
      
      #define CHILD_ID_MOISTURE 2
      #define CHILD_ID_HUM 3
      #define CHILD_ID_TEMP 4
      
      float lastTemp;
      float lastHum;
      uint8_t nNoUpdatesTemp;
      uint8_t nNoUpdatesHum;
      bool metric = true;
      
      MyMessage msgMoisture(CHILD_ID_MOISTURE, V_HUM);
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      DHT dht;
      
      static int sensorValue;
      int soilPin = A0;
      int soilPower = 5;
      
      
      #define DIGITAL_INPUT_SENSOR 3                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
      
      #define PULSE_FACTOR 450000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
      
      #define SLEEP_MODE false                        // flowvalue can only be reported when sleep mode is false.
      
      #define MAX_FLOW 30                             // Max flow (l/min) value to report. This filters outliers.
      
      #define CHILD_ID_WATER 1
      
      uint32_t SEND_FREQUENCY =
          5000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
          
      
      MyMessage flowMsg(CHILD_ID_WATER,V_FLOW);
      MyMessage volumeMsg(CHILD_ID_WATER,V_VOLUME);
      MyMessage lastCounterMsg(CHILD_ID_WATER,V_VAR1);
      
      double ppl = ((double)PULSE_FACTOR)/1000;        // Pulses per liter
      
      volatile uint32_t pulseCount = 0;
      volatile uint32_t lastBlink = 0;
      volatile double flow = 0;
      bool pcReceived = false;
      uint32_t oldPulseCount = 0;
      uint32_t newBlink = 0;
      double oldflow = 0;
      double volume =0;
      double oldvolume =0;
      uint32_t lastSend =0;
      uint32_t lastPulse =0;
      
      void before()
      {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
          // Then set relay pins in output mode
          pinMode(pin, OUTPUT);
          // Set relay to last known state (using eeprom storage)
          digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
        }
      }
      
      void presentation()
      {
       sendSketchInfo("Smart Irrigation System", "1.0");
        present(CHILD_ID_MOISTURE, S_MOISTURE);
        present(CHILD_ID_WATER, S_WATER);
        present(CHILD_ID_HUM, S_HUM);
        present(CHILD_ID_TEMP, S_TEMP);
      
        metric = getControllerConfig().isMetric;
        
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
        present(sensor, S_BINARY);
        }
      
      }
      
      void setup()
      {
        pinMode(soilPower, OUTPUT);//Set D6 as an OUTPUT
        // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
        pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
      
        pulseCount = oldPulseCount = 0;
      
        // Fetch last known pulse count value from gw
        request(CHILD_ID_WATER, V_VAR1);
      
        lastSend = lastPulse = millis();
      
        attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING);
      
         dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
        if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
          Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
        }
        // Sleep for the time of the minimum sampling period to give the sensor time to power up
        // (otherwise, timeout errors might occure for the first reading)
        sleep(dht.getMinimumSamplingPeriod());
      }
      
      void loop()
      {
      
         // Force reading sensor, so it works also after sleep()
        dht.readSensor(true);
      
        // Get temperature from DHT library
        float temperature = dht.getTemperature();
        if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT!");
        } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
          lastTemp = temperature;
          if (!metric) {
            temperature = dht.toFahrenheit(temperature);
          }
          // Reset no updates counter
          nNoUpdatesTemp = 0;
          temperature += SENSOR_TEMP_OFFSET;
          send(msgTemp.set(temperature, 1));
      
          #ifdef MY_DEBUG
          Serial.print("T: ");
          Serial.println(temperature);
          #endif
        } else {
          // Increase no update counter if the temperature stayed the same
          nNoUpdatesTemp++;
        }
      
        // Get humidity from DHT library
        float humidity = dht.getHumidity();
        if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
        } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
          lastHum = humidity;
          // Reset no updates counter
          nNoUpdatesHum = 0;
          send(msgHum.set(humidity, 1));
      
          #ifdef MY_DEBUG
          Serial.print("H: ");
          Serial.println(humidity);
          #endif
        } else {
          // Increase no update counter if the humidity stayed the same
          nNoUpdatesHum++;
        }
      
        // Sleep for a while to save energy
        sleep(UPDATE_INTERVAL); 
       //......................................................
        uint32_t currentTime = millis();
      
        // Only send values at a maximum frequency or woken up from sleep
        if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) {
          lastSend=currentTime;
      
          if (!pcReceived) {
            //Last Pulsecount not yet received from controller, request it again
            request(CHILD_ID_WATER, V_VAR1);
            return;
          }
      
          if (!SLEEP_MODE && flow != oldflow) {
            oldflow = flow;
      
            Serial.print("l/min:");
            Serial.println(flow);
      
            // Check that we dont get unresonable large flow value.
            // could hapen when long wraps or false interrupt triggered
            if (flow<((uint32_t)MAX_FLOW)) {
              send(flowMsg.set(flow, 2));                   // Send flow value to gw
            }
          }
      
          // No Pulse count received in 2min
          if(currentTime - lastPulse > 120000) {
            flow = 0;
          }
      
          // Pulse count has changed
          if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
            oldPulseCount = pulseCount;
      
            Serial.print("pulsecount:");
            Serial.println(pulseCount);
      
            send(lastCounterMsg.set(pulseCount));                  // Send  pulsecount value to gw in VAR1
      
            double volume = ((double)pulseCount/((double)PULSE_FACTOR));
            if ((volume != oldvolume)||(!SLEEP_MODE)) {
              oldvolume = volume;
      
              Serial.print("volume:");
              Serial.println(volume, 3);
      
              send(volumeMsg.set(volume, 3));               // Send volume value to gw
            }
          }
        }
        if (SLEEP_MODE) {
          sleep(SEND_FREQUENCY);
        }
          soilmoisture();
      }
      
      void soilmoisture()
      {
        digitalWrite(soilPower, HIGH);
      delay(10);//wait 10 milliseconds
      sensorValue = analogRead(soilPin);
      digitalWrite(soilPower, LOW);
      sensorValue = map(sensorValue, 0, 680, 0, 100);
        send(msgMoisture.set(sensorValue));
          sleep(SEND_FREQUENCY);
      }
      
      void receive(const MyMessage &message)
      {
        if (message.type==V_VAR1) {
          uint32_t gwPulseCount=message.getULong();
          pulseCount += gwPulseCount;
          flow=oldflow=0;
          Serial.print("Received last pulse count from gw:");
          Serial.println(pulseCount);
          pcReceived = true;
        }
      
        if (message.type==V_STATUS) {
          // Change relay state
          digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
          // Store state in eeprom
          saveState(message.sensor, message.getBool());
      }
      }
      
      
      void onPulse()
      {
        if (!SLEEP_MODE) {
          uint32_t newBlink = micros();
          uint32_t interval = newBlink-lastBlink;
      
          if (interval!=0) {
            lastPulse = millis();
            if (interval<500000L) {
              // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
              return;
            }
            flow = (60000000.0 /interval) / ppl;
          }
          lastBlink = newBlink;
        }
        pulseCount++;
      }
      
      

      anyone can help me?
      and any suggestion to clean up my code?
      thanks in advanced.

      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #2

      @tsunami if you look at the debug output, you will probably see that the presentation presents the relay and the water sensor with the same child id.

      You'll need to use a higher number for one of the IDs.

      T 1 Reply Last reply
      0
      • mfalkviddM mfalkvidd

        @tsunami if you look at the debug output, you will probably see that the presentation presents the relay and the water sensor with the same child id.

        You'll need to use a higher number for one of the IDs.

        T Offline
        T Offline
        tsunami
        wrote on last edited by
        #3

        @mfalkvidd I've changed CHILD_ID for nodes but nothing changed and moisture data show up in DHT22's humidity!

        1 Reply Last reply
        0
        • gohanG Offline
          gohanG Offline
          gohan
          Mod
          wrote on last edited by
          #4

          @tsunami said in having trouble with water flow sensor + relay + moisture:

          #define CHILD_ID_MOISTURE 2
          #define CHILD_ID_HUM 3
          #define CHILD_ID_TEMP 4

          try
          #define CHILD_ID_MOISTURE 12
          #define CHILD_ID_HUM 13
          #define CHILD_ID_TEMP 14

          Also delete node from controller if you still see the ID mixed up

          1 Reply Last reply
          2
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          18

          Online

          11.7k

          Users

          11.2k

          Topics

          113.1k

          Posts


          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • MySensors
          • OpenHardware.io
          • Categories
          • Recent
          • Tags
          • Popular