Announcement

Collapse
No announcement yet.

Utilizing input for flow meter

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Utilizing input for flow meter

    I think I am in a pickle.

    Awaiting arrival of my parts but I am trying to see if I can make this work.

    Background
    - I am currently setting up an irrigation system which includes a 200L rain barrel which collects both rain water and ground water through my house sump pump. I then have a sump pump and float located in the rain barrel which when reaching its predetermined level, pumps water over to a 1250L storage tank. My idea is to monitor roughly the tank level by utilizing 2 flow meters and storing the amount as a homeseer device. The specifics on flow meter are here: https://www.bc-robotics.com/shop/liquid-flow-meter/

    One flow meter will be on the 1250L tank input and will calculate flow rate vs time running to determine # of litres put into the tank. The second flow meter will be on the tank output that runs to an irrigation system, a free hose for watering can, etc. This will use the same idea of flow rate vs time to determine liters out. The overflow discharge will not have a meter but when the tank is full at 1200L no more will be added to it no matter how much is pumped in.

    My pickle is that I will have a 12V valve, moisture and soil temp sensors hooked up to an Uno with an ethernet sheild. This has a 90 foot run from the switch to the Uno and I would like to have it all run off of the one Uno to prevent having to run a second line at 90 feet.

    Am I able to use the normal board setup and set the flow meters as inputs, count the pulses over a given period of time reliably? The transfer pump probably operates for about 3 minutes when its moving water over to the main tank. Have an event to clear a count varialbe, start a timer when that flow meter starts, count all pulses for that period, then calculate it back to liters. Does that sound plausible? Thanks guys.

    #2
    Originally posted by KoryDoubleYou View Post
    I think I am in a pickle.

    Awaiting arrival of my parts but I am trying to see if I can make this work.

    Background
    - I am currently setting up an irrigation system which includes a 200L rain barrel which collects both rain water and ground water through my house sump pump. I then have a sump pump and float located in the rain barrel which when reaching its predetermined level, pumps water over to a 1250L storage tank. My idea is to monitor roughly the tank level by utilizing 2 flow meters and storing the amount as a homeseer device. The specifics on flow meter are here: https://www.bc-robotics.com/shop/liquid-flow-meter/

    One flow meter will be on the 1250L tank input and will calculate flow rate vs time running to determine # of litres put into the tank. The second flow meter will be on the tank output that runs to an irrigation system, a free hose for watering can, etc. This will use the same idea of flow rate vs time to determine liters out. The overflow discharge will not have a meter but when the tank is full at 1200L no more will be added to it no matter how much is pumped in.

    My pickle is that I will have a 12V valve, moisture and soil temp sensors hooked up to an Uno with an ethernet sheild. This has a 90 foot run from the switch to the Uno and I would like to have it all run off of the one Uno to prevent having to run a second line at 90 feet.

    Am I able to use the normal board setup and set the flow meters as inputs, count the pulses over a given period of time reliably? The transfer pump probably operates for about 3 minutes when its moving water over to the main tank. Have an event to clear a count varialbe, start a timer when that flow meter starts, count all pulses for that period, then calculate it back to liters. Does that sound plausible? Thanks guys.
    The pulses are likely going to come too quick to rely on Homeseer detecting each one (and counting them). I would have the arduino count the pulses and transmit the count total to Homeseer (and do the math there). You'd have to use the API sketch for that I believe. If you want flow rate you'd also have to have the Arduino calculate that, because it has to be done rather quickly.

    Comment


      #3
      Nuts. That's what I was worried about. Looking back on it now I really over thought that. All I would need to do is count pulses during operation of the pump and multiply by 2.25mm as indicated on the spec sheet. Still doesn't help me to get it as accurate as it could be like you said.

      Is there an option to migrate the other sensors and valve to the api board? Moisture and temp would be output only but I would need to be able to operate the valve open and close from homeseer.

      Comment


        #4
        Hi Kory,
        I'm using a same for Power consumption: I have a energy meter that send a pulse every 1W.

        As AllanMar wrote, you need a board in API mode and appropiate sketch.

        Here the mine for power counter:

        Code:
        //For serial set to 0 and for Ethernet set to 1
        #define ISIP 0
        
        //Do NOT modify these
        #if ISIP == 1
        #include <EEPROM.h>
        #include <SPI.h>       
        #include <Ethernet.h>
        #include <EthernetUdp.h> 
        #endif
        /************************************************************
         *Arduino to Homeseer 3 Plugin API written by Enigma Theatre.*
         * V1.0.0.81                                                 *
         *                                                           *
         *******Change the values below only*************************
         */
        
        // Pin pulse
        const int getpulsepin = 2;
        
        // variable
        int power = 0;
        unsigned long startime = 0;
        unsigned long duration = 0;
        int state = 0;
        int pinval = 0;
        unsigned long tempoPrecedente = 0;
        
        //Address of the board.
        const byte BoardAdd = 3;
        
        #if ISIP == 1
        // Enter a MAC address and IP address for your board below.
        byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x03};
        
        // The IP address will be dependent on your local network.
        IPAddress ip(192,100,100,100);     //IP entered in HS config.
        const unsigned int localPort = 8902;      //port entered in HS config.
        IPAddress HomeseerIP(192,100,100,25); //Homeseer IP address
        IPAddress ServerIP(EEPROM.read(2),EEPROM.read(3),EEPROM.read(4),EEPROM.read(5));
        byte EEpromVersion = EEPROM.read(250);
        #endif
        
        
        //************Do not change anything in Here*****************
        int FromHS[10];                                          // *
        boolean IsConnected = false;                             // *
        #if ISIP == 1                                            // *
        char packetBuffer[UDP_TX_PACKET_MAX_SIZE];               // *
        EthernetUDP Udp;                                         // *
        const unsigned int ServerPort = 8888;                    // *
        #endif                                                   // *
        void(* resetFunc) (void) = 0;                            // *
        //***********************************************************
        
        
        void setup() {
          HSSetup();
          //************************
          //Add YOUR SETUP HERE;
        
        pinMode(getpulsepin, INPUT); // pin del sensore
        digitalWrite (getpulsepin, HIGH);//abilito resistenza pull up
          
          //************************
        
        
        
        
        }
        
        
        
        
        void loop() {
        #if ISIP == 1
          IsUDP();
        #endif
        
            //************************
            //Add YOUR CODE HERE;
            //************************
        
             pinval = digitalRead(getpulsepin);   // legge il pin del sensore
         
            if ((state == 1) & (pinval == 0)) { // punto di transizione
            duration = millis() - startime;       // calcola la duration della pulsazione
            startime = millis();            // setta il nuovo tempo di partenza 
            power = 3600.0/duration*1000;  // calcola consumo ***HERE YOU NEED TO CHANGE AS YOU WANT COUNT
            SendToHS(1,power);
            int duration2 = duration; // /1000;
            SendToHS(2,duration3);
                }
          }
            state = pinval;         // imposta lo state uguale alla lettura del pin
        
            
            /* To Send Data to Homeseer use SendToHS(Device,Value)
             Eg.. SendToHS(1,200); where 1 is the API device in homeseer and 200 is the value to send
             To Recieve data from Homeseer look up the FromHS array that is updated when the device value changes.
             Eg.. FromHS[5] would be the data from API Output device 5
             All code that is located just below this block will execute regardless of connection status!
             You can include SendToHS() calls, however when there isn't an active connection, it will just return and continue.
             If you only want code to execute when HomeSeer is connected, put it inside the if statement below.
             */
        
        /*Execute regardless of connection status*/
        
        
         if (IsConnected == true) {
           /*Execute ONLY when HomeSeer is connected*/
        
          }
        }
        
        const char* Version = "API1.0.0.81";
        
        byte Byte1,Byte2,Byte3;
        int Byte4,Byte5;
        
        
        void HSSetup() {
        
        #if ISIP == 1
            if (EEpromVersion!=22) {
            ServerIP=HomeseerIP;
            EEPROM.write(2,ServerIP[0]);
            EEPROM.write(3,ServerIP[1]);
            EEPROM.write(4,ServerIP[2]);
            EEPROM.write(5,ServerIP[3]);
            EEPROM.write(250,22); //Store the version where the eeprom data layout was last changed
            EEpromVersion=22;
          }
        Ethernet.begin(mac,ip);
          Udp.begin(localPort);
          Udp.setTimeout(0);
          delay(1000);
        SendConnect();
        #else
          Serial.begin(115200);
          Serial.flush();
          Serial.setTimeout(0);
          delay(1000);
          Serial.print("Connect ");
          Serial.println(BoardAdd);
        #endif
        
          IsConnected = false;
        
        }
        
        void SendConnect()
        {
        #if ISIP == 0
          Serial.print("Connect ");
          Serial.println(BoardAdd);
        #else
            Udp.beginPacket(ServerIP,ServerPort);  //First send a connect packet to the dynamic IP stored in eeprom
            Udp.print("Connect ");
            Udp.print(BoardAdd);
            Udp.endPacket();
            if (ServerIP!=HomeseerIP) {
              Udp.beginPacket(HomeseerIP,ServerPort);  //Then if the stored value doesn't match the pre-specified one, send a connect packet there also
              Udp.print("Connect ");
              Udp.print(BoardAdd);
              Udp.endPacket();
            }
         
        #endif
        }
        
        
        #if ISIP == 1
        void IsUDP(){
          int packetSize = Udp.parsePacket();
          if(packetSize)
          {
            IPAddress remote = Udp.remoteIP();
            Byte1 =Udp.parseInt();
            Udp.read(); 
            Byte2 =Udp.read(); 
            Byte3 =Udp.parseInt();
            Byte4 =Udp.parseInt();
            Byte5 =Udp.parseInt();
            DataEvent();
          }
        }
        
        #else
        void serialEvent() {
          while (Serial.available() > 0) {
            delay(17);
        
        
            Byte1 = Serial.parseInt();
            Serial.read();  
            Byte2 = Serial.read(); 
            Byte3 = Serial.parseInt();
            Byte4 = Serial.parseInt();
            Byte5 = Serial.parseInt();
            DataEvent();
          }
        }
        #endif
        
        
        /*
        
        Used Data Input Cases
        D Disconnect
        r reset
        K Keepalive
        O PinMode Output Set
        d Input debounce time set
        C Connect request
        c Connection established - report current status
        */
        void DataEvent() {
        
        
        
          if (Byte1 == BoardAdd) {
            switch (Byte2) {
        
            case 'c':
              IsConnected = true;
        #if ISIP == 1
              if (Udp.remoteIP() != ServerIP) {
                ServerIP=Udp.remoteIP();
                EEPROM.write(2,ServerIP[0]);
                EEPROM.write(3,ServerIP[1]);
                EEPROM.write(4,ServerIP[2]);
                EEPROM.write(5,ServerIP[3]);
              }     
        #endif
        
              break;
        
            case 'C':   
        #if ISIP == 1
              Udp.beginPacket(Udp.remoteIP(), ServerPort);
              Udp.print("Version ");
              Udp.print(BoardAdd);
              Udp.print(" ");
              Udp.print(Version);
              Udp.println(" HS3");
              Udp.endPacket();
        
              Udp.beginPacket(Udp.remoteIP(), ServerPort);
              delay(100);
              Udp.print("Connected ");
              Udp.println(BoardAdd);
              Udp.endPacket();
        #else
              Serial.print("Version ");
              Serial.print(BoardAdd);
              Serial.print(" ");
              Serial.print(Version);
              Serial.println(" HS3"); 
              delay(100);
              Serial.print("Connected ");
              Serial.println(BoardAdd);
        #endif
              delay(100);
              IsConnected = false;
              break;
        
            case 'K':
              delay(200);
        #if ISIP == 1
              Udp.beginPacket(Udp.remoteIP(), ServerPort);
              Udp.print("Alive ");
              Udp.println(BoardAdd);
              Udp.endPacket();
              if (Udp.remoteIP() != ServerIP) {
                ServerIP=Udp.remoteIP();
                EEPROM.write(2,ServerIP[0]);
                EEPROM.write(3,ServerIP[1]);
                EEPROM.write(4,ServerIP[2]);
                EEPROM.write(5,ServerIP[3]);
              }     
        #else     
              Serial.print("Alive ");
              Serial.println(BoardAdd);
        #endif
              break; 
              
              case 'r':
              delay(200);
              resetFunc();  //call reset
              break; 
        
            case 'O':
              FromHS[Byte3] = Byte4;
              break; 
        
            case 'D':
              IsConnected = false;
              break;   
            }
          }
        }
        
        void SendToHS(byte Device, long Data){
        if (IsConnected == true) {
        #if ISIP == 1
          Udp.beginPacket(Udp.remoteIP(), ServerPort);
          Udp.print(BoardAdd);
          Udp.print(" API ");
          Udp.print(Device);
          Udp.print(" ");
          Udp.print(Data);
          Udp.endPacket();
        #else
          Serial.print(BoardAdd);
          Serial.print(" API ");
          Serial.print(Device);
          Serial.print(" ");
          Serial.println(Data);
        #endif
        }
        }
        
        void SendToHS(byte Device, int Data){
        if (IsConnected == true) {
        #if ISIP == 1
          Udp.beginPacket(Udp.remoteIP(), ServerPort);
          Udp.print(BoardAdd);
          Udp.print(" API ");
          Udp.print(Device);
          Udp.print(" ");
          Udp.print(Data);
          Udp.endPacket();
        #else
          Serial.print(BoardAdd);
          Serial.print(" API ");
          Serial.print(Device);
          Serial.print(" ");
          Serial.println(Data);
        #endif
        }
        }
        
        void SendToHS(byte Device, float Data){
        if (IsConnected == true) {
        #if ISIP == 1
          Udp.beginPacket(Udp.remoteIP(), ServerPort);
          Udp.print(BoardAdd);
          Udp.print(" API ");
          Udp.print(Device);
          Udp.print(" ");
          Udp.print(Data);
          Udp.endPacket();
        #else
          Serial.print(BoardAdd);
          Serial.print(" API ");
          Serial.print(Device);
          Serial.print(" ");
          Serial.println(Data);
        #endif
        }
        }
        This is only the startup, but is possible to change and count only when the valve is ON, or you can count the pulse when the valve is ON and then divide by "valve ON time"...

        Sure, Allan is much more expert than me

        Comment


          #5
          Originally posted by KoryDoubleYou View Post
          Nuts. That's what I was worried about. Looking back on it now I really over thought that. All I would need to do is count pulses during operation of the pump and multiply by 2.25mm as indicated on the spec sheet. Still doesn't help me to get it as accurate as it could be like you said.

          Is there an option to migrate the other sensors and valve to the api board? Moisture and temp would be output only but I would need to be able to operate the valve open and close from homeseer.
          What kind of flow rates are you expecting? That flowmeter mentions 30L/min max, many sump pumps can produce alot more than that (depends on height though). At 30L/min that would be 225 pulses/second, so you'll have to make sure the code runs fast enough.

          Theres no limitation that would prevent you from doing all this in one arduino though.

          Comment


            #6
            Thanks khriss I will use that as a guide! Should get me started.

            Allan you being up a good point. It may push more than that. I will do a manual test and see where it's at. It should be rather consistent so I could always use the flow meter as an indicator that it's pumping and base time on a known constant for flow. Moves 70 litres a minute and ran for 2.1 minutes etc. Do a flow test a couple times a year to check it out.

            The flow out should be fine it will be a gravity fed tank that moves just enough to keep the drip working.

            Now to work through actuating the valve from an Api script. Shouldn't be hard, have an open close valve device in homeseer and send the open value to the Api when necessary?

            Comment


              #7
              If you already have a valves devices (that control your valves), you could create 2 input in API board.
              Then create an event like this:
              If valve device go ON --> then switch ON valve API device.
              If valve device go OFF --> then switch OFF valve API device.
              Ok, now the "virtual" valve API devices are matched.

              On your API skecth, now You can start a timer when API valve device go ON, count the pulse from flowmeter, stop timer when API valve device go OFF and calculate the time and all you want.
              Then you pass the results to HS via API.
              The best is to control valves directly with API board pin.

              Comment


                #8
                Awesome,

                It's starting to come together.

                My next question is does FromHS[x] return an integer or a LOW/HIGH response?

                My idea is to create an event that will turn the valve on and off when its required, a timer on HS side will coordinate with irrigation needs. Send the On command to the uno through FromHS[x] and allow the arduino to operate the valve.

                int ValveStatus = 0;

                ValveStatus = FromHS[3]; / HS Event turns it on.

                if statement to see if ValveStatus is ON, digitalwrite valve to high and this will continue until HS turns the valve off which will then turn ValveStatus low, digitalwrite low to the valve which will close it.

                Do I have the right idea?

                Is there any way to failsafe this so that I don't unload 1200L of water onto the wife's plants in the event of a lost communication with HS. She will not be too impressed at all. ha.

                Thanks.

                Comment

                Working...
                X