having trouble with water flow sensor + relay + moisture



  • 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.


  • Mod

    @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.



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


  • Mod

    @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


 

427
Online

7.9k
Users

8.8k
Topics

94.3k
Posts