Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Water Flow Sensor - Looking for Advice

    Scheduled Pinned Locked Moved Discussion
    6 Posts 5 Posters 156 Views 7 Watching
    Loading More Posts
    • 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.
    • J Offline
      JSGora
      last edited by

      TL;DR: Looking for help getting a water flow rate sensor working on my Gpy/Expansion Board 3.1, new to MicroPython and struggling. My desired output would be in L/min.

      What I've done so far:

      I have a Gpy with expansion board V3.1. I've successfully connected to LTE over hologram and wifi to PyBytes. I have a novice understanding of Arduino but MicroPython is new to me.

      Here is an Arduino example of what I am trying to do:

      // reading liquid flow rate using Seeeduino and Water Flow Sensor from Seeedstudio.com
      // Code adapted by Charles Gantt from PC Fan RPM code written by Crenn @thebestcasescenario.com
      // http:/themakersworkbench.com http://thebestcasescenario.com http://seeedstudio.com
      
      volatile int NbTopsFan; //measuring the rising edges of the signal
      int Calc;                               
      int hallsensor = 2;    //The pin location of the sensor
      
      void rpm ()     //This is the function that the interupt calls 
      { 
       NbTopsFan++;  //This function measures the rising and falling edge of the hall effect sensors signal
      
      
      } 
      // The setup() method runs once, when the sketch starts
      void setup() //
      { 
       pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
       Serial.begin(9600); //This is the setup function where the serial port is initialised,
      
      
       attachInterrupt(0, rpm, RISING); //and the interrupt is attached
      } 
      // the loop() method runs over and over again,
      // as long as the Arduino has power
      void loop ()    
      {
       NbTopsFan = 0;      //Set NbTops to 0 ready for calculations
       sei();            //Enables interrupts
       delay (1000);      //Wait 1 second
       cli();            //Disable interrupts
       Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
      
      
       Serial.print (Calc, DEC); //Prints the number calculated above
       Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line
      }
      

      I have the following sensor: https://www.digiten.shop/collections/counter/products/digiten-g1-2-water-flow-hall-sensor-switch-flow-meter-1-30l-min

      I currently have it plugged in to 3.3V and GND with Data going into P16.

      According to the spec sheet on the website:

      Frequency: F=7.5 * Q (L / Min) error: ± 2% current can not exceed 10mA, 450 output pulses/liters, F=Constant * units of flow (L / min) * time (seconds)
      Flow range:1-30L/min
      Maximum current:15 mA(DC 5V)
      Working voltage range:DC 5-24 V
      Load capacity:≤10 mA(DC 5V)
      Output Waveform:Square Wave,output pulse signal.
      Sensor:Hall effect

      I have tried several bits of code to try and read data off the sensor, but I am having trouble getting anything to work or be useable.

      This code looks great but my lack of understanding things still has kept me from being able to actually run it and print back any values.

      class RPM:
          
          def __init__(self, pin):
              self._pin = Pin(pin,mode=Pin.IN)
              self._intvl = 0
              self._pin.callback(Pin.IRQ_RISING,handler=self._callback,arg=self)
              self._timer = Timer.Chrono()
              self._timer.start()
      
          def _callback(self,obj):
              self._intvl = self._timer.read_ms()
              self._timer.reset()   
      
          def rpm(self):
              return 60000 / self._intvl 
      

      I was able to modify this tutorial: https://core-electronics.com.au/tutorials/pycom/hc-sr04-ultrasonic-sensor-with-pycom-tutorial.html to receive back some data but it only reads values at a very low speed and then stops reporting at higher 'speed'. I'm not sure if this is a limitation of the 3.3V or that I am headed down the wrong path with the code:

      import utime
      import pycom
      import machine
      from machine import Pin
      
      echo = Pin('P16', mode=Pin.IN, pull=Pin.PULL_DOWN)
      
      # Ultrasonic distance measurment
      def distance_measure():
      
          # wait for the rising edge of the echo then start timer
          while echo() == 0:
              pass
          start = utime.ticks_ms()
      
          # wait for end of echo pulse then stop timer
          while echo() == 1:
              pass
          finish = utime.ticks_ms()
      
          # pause for 20ms to prevent overlapping echos
          utime.sleep_ms(500)
      
          # calculate distance by using time difference between start and stop
          # speed of sound 340m/s or .034cm/us. Time * .034cm/us = Distance sound travelled there and back
          # divide by two for distance to object detected.
          distance = ((utime.ticks_diff(start, finish)) * 60)/7.5
      
          return distance
      
      while True:
          print(distance_measure())
      

      Returns:

      -1360.0
      -1528.0
      -1008.0
      -576.0
      -104.0
      -8.0
      -8.0
      -24.0
      -96.0
      

      I tried several versions of code reading DHT sensors with Time / Interrupts, but I had no success getting anything to report back from the flow sensor.

      If I read the pin as analog I can get a value of 4095 (3.3V) at rest and the higher the pressure on the sensor it goes to 0, however I get a mixture of 'false zeros' between readings.

      import machine
      import utime
      
      
      while True:
          adc = machine.ADC()             # create an ADC object
          apin = adc.channel(pin='P16', attn = machine.ADC.ATTN_11DB)   # create an analog pin on P16
          val = apin()                    # read an analog value
      
          print(val)
          utime.sleep_ms(50)
      
      

      Will return:

      335
      102
      0
      0
      0
      112
      0
      108
      245
      0
      

      If I read it using pulses_get I cam able to get occasional sets of data, but not consistently.

      # get the raw data from a DHT11/DHT22/AM2302 sensor
      from machine import Pin
      from pycom import pulses_get
      from time import sleep_ms
      
      pin = Pin("P16", mode=Pin.OPEN_DRAIN)
      pin(0)
      sleep_ms(20)
      pin(1)
      data = pulses_get(pin, 100)
      
      print(data)
      
      

      will return:

      [(0, 18010), (1, 4217), (0, 17331), (1, 4174), (0, 17341), (1, 4187), (0, 16935), (1, 3256), (0, 16397), (1, 3296), (0, 16500), (1, 3384), (0, 16175), (1, 2554), (0, 15749), (1, 2675), (0, 15883), (1, 2785), (0, 15641), (1, 2039), (0, 15258), (1, 2168), (0, 15405), (1, 2332), (0, 15202), (1, 1634), (0, 14856), (1, 1770), (0, 15051), (1, 1934), (0, 14836), (1, 1291), (0, 14534), (1, 1453), (0, 14738), (1, 1638), (0, 14551), (1, 1023), (0, 14274), (1, 1198), (0, 14467), (1, 1361), (0, 14305), (1, 764), (0, 14030), (1, 945), (0, 14212), (1, 1114), (0, 14069), (1, 541), (0, 13798), (1, 705), (0, 13980), (1, 883), (0, 13818), (1, 329), (0, 13577), (1, 489), (0, 13768), (1, 671), (0, 13623), (1, 128), (0, 13385), (1, 299), (0, 13566), (1, 476), (0, 26622), (1, 129), (0, 13418), (1, 303), (0, 6703), (1, 173), (0, 6043), (1, 51)]
      

      I am guessing the solution has to do with RMT or something but I'm out of ideas. If anyone is able to give me guidance in the right direction I would be greatly appreciated! - Thanks

      1 Reply Last reply Reply Quote 0
      • J Offline
        JSGora
        last edited by

        With a little help from someone at work I was able to get the RPM code running and print values however I am only reading zeros.

        I tried running the referenced Arduino code on an UNO with the sensor to ensure it was working correctly and everything works perfectly.

        In the end I really just need to port over what is happening in the Arduino code over to MicroPython to run on the Gpy. I feel like that is what I should capture with the follow code, but that is not the case.

        import machine
        from time import sleep
        from machine import Timer
        from machine import Pin
        
        
        class RPM:
        
            def __init__(self, pin):
                self._pin = Pin(pin,mode=Pin.IN)
                self._intvl = 0
                self._pin.callback(Pin.IRQ_RISING,handler=self._callback,arg=self)
                self._timer = Timer.Chrono()
                self._timer.start()
        
            def _callback(self,obj):
                self._intvl = self._timer.read_ms()
                self._timer.reset()
        
            def rpm(self):
                return self._intvl
        
        while True:
            data = RPM('P16')
            print(data.rpm())
            sleep(1)
        
        
        S 1 Reply Last reply Reply Quote 0
        • D Offline
          d.alvrzx
          last edited by d.alvrzx

          Hello,

          As per the device's datasheet, the minimum working voltage for your sensor is 4.5 VDC, so I don't think it would work with it connected to 3.3 VDC. Probably why you're getting zeroes, because there's nothing on the output of the sensor. Also note that in the Arduino example, the sensor is connected to 5V, which the Arduino can produce - GPy can't.

          Also, you have to be careful when connecting the signal of the sensor into the GPy, because the sensor will output a square wave between 0 and Vss, where Vss is the supply voltage for the sensor (5V for example). The GPy's pins can only receive an input of up to 3.3 VDC, so you will need a voltage divider prior to your input pin to bring the voltage down. If not, you would most likely damage the pin.

          Regarding the example code with the RPM class, it looks like it should work...

          Best,

          Dan

          1 Reply Last reply Reply Quote 1
          • J Offline
            John Anderson
            last edited by

            I am using the industry's most comprehensive range of corrosion-free a paddle wheel flow meter which are cost effective, excellent compatibility with liquids, foam, vapor and can offer low current consumption for battery powered applications. If you are interested you can visit this website: https://iconprocon.com/product-category/flow-meters/

            1 Reply Last reply Reply Quote 0
            • S Offline
              Smart Farming @JSGora
              last edited by Smart Farming

              Dear @JSGora, did you find some solution for the flow water sensor? some code, some tip, some info? we are working whit lopy4 technology and we have the same problem. thank's

              1 Reply Last reply Reply Quote 0
              • C Offline
                cromagnon
                last edited by

                I've had success using Atlas Scientific's embedded flow processor for water meter pulse totalizing:
                https://atlas-scientific.com/embedded-solutions/ezo-embedded-flow-meter-totalizer/

                I connect it to a FiPy via I2C then forward the readings to my server over MQTT. Seems like a good option since the flow processor will keep totalizing if your LoPy restarts.

                1 Reply Last reply Reply Quote 1

                Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                With your input, this post could be even better 💗

                Register Login
                • 1 / 1
                • First post
                  Last post

                Pycom on Twitter

                Pycom