Bob Hammell
Published © Apache-2.0

River Monitoring with an IoT Flow Meter

Send flow rate measurements to the cloud and monitor them in real-time with Soracom Harvest and AWS IoT.

IntermediateFull instructions provided8 hours17,394

Things used in this project

Hardware components

Raspberry Pi 3 Model B+
Raspberry Pi 3 Model B+
×1
SORACOM Air Global IoT SIM
SORACOM Air Global IoT SIM
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×3
Huawei 3G USB dongle (MS2131i)
×1
Adafruit Liquid Flow Meter
×1
USB 2.0 A Male to A Female Extension Cable
×1
External Battery Pack (9000 mAh)
Any brand. Must have micro USB output.
×1
4-40 x 1/2" screw
×4
1/4" x 1/2" hex bolt w/ hex nut
×4
1/4" - 1/8" Heat Shrink Tubing (8ft)
×1
1/8" - 1/16" Heat Shrink Tubing
×6
Nylon Zip Ties
×3
Waterproof Silicone Caulk
×1
1" PVC Pipe (5 ft)
×2
1" PVC Tee Fitting
×3
1" 2 Hole Rigid Conduit Strap
×2

Software apps and online services

Raspbian
Raspberry Pi Raspbian
SORACOM Funnel
SORACOM Funnel
SORACOM Harvest
SORACOM Harvest
SORACOM Inventory - Remote management for connected devices
SORACOM Inventory - Remote management for connected devices
AWS IoT
Amazon Web Services AWS IoT

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)
Heat Gun (generic)
Screwdriver (generic)
Hand Saw (generic)

Story

Read more

Custom parts and enclosures

Electronics Housing Box

3D printed box used to hold the project electronics (Rapsberry Pi, battery, cellular dongle). Includes bracket holes for attaching it to a 1" PVC pipe.

Flow Meter Bracket

3D printed bracket that holds a YF-S201 flow meter and connects it to a 1" PVC pipe.

Flow Meter Funnel

3D printed funnel that fits on the opening of the YF-S201 flow meter.

Schematics

Flow Meter Pin Connections

Schematic showing the pin connections between the YF-S201 flow meter and a Raspberry Pi 3

Code

flowmeter.py

Python
Python script that repeatedly collects flow meter measurements and pushes it to Soracom Harvest
import json
import time
from datetime import datetime
import RPi.GPIO as GPIO
import requests
  
class FlowMeter():
    ''' Class representing the flow meter sensor which handles input pulses
        and calculates current flow rate (L/min) measurement
    '''
    
    def __init__(self):
        self.flow_rate = 0.0
        self.last_time = datetime.now()
  
    def pulseCallback(self, p):
        ''' Callback that is executed with each pulse 
            received from the sensor 
        '''
       
        # Calculate the time difference since last pulse recieved
        current_time = datetime.now()
        diff = (current_time - self.last_time).total_seconds()
       
        # Calculate current flow rate
        hertz = 1. / diff
        self.flow_rate = hertz / 7.5
       
        # Reset time of last pulse
        self.last_time = current_time
    
    def getFlowRate(self):
        ''' Return the current flow rate measurement. 
            If a pulse has not been received in more than one second, 
            assume that flow has stopped and set flow rate to 0.0
        '''
       
        if (datetime.now() - self.last_time).total_seconds() > 1:
            self.flow_rate = 0.0
        
        return self.flow_rate
  
def main():
    ''' Main function for repeatedly collecting flow rate measurements
        and sending them to the SORACOM API
    '''
   
    # Configure GPIO pins
    INPUT_PIN = 7
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(INPUT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
   
    # Init FlowMeter instance and pulse callback
    flow_meter = FlowMeter()
    GPIO.add_event_detect(INPUT_PIN,
                          GPIO.RISING,
                          callback=flow_meter.pulseCallback,
                          bouncetime=20)
   
    # Begin infinite loop
    while True:
  
        # Get current timestamp and flow meter reading
        timestamp = str(datetime.now())
        flow_rate = flow_meter.getFlowRate()
        print('Timestamp: %s' % timestamp)
        print('Flow rate: %f' % flow_rate)

        # Build payload
        payload = {
            'timestamp': timestamp,
            'flow_rate': flow_rate
        }
          
        # Publish to Soracom API
        headers = {'Content-Type': 'application/json'}
        try:
            print('Publishing to SORACOM API...')
            r = requests.post('http://unified.soracom.io',
                               data=json.dumps(payload),
                               headers=headers,
                               timeout=5)
        except:
            print('Error: Connection timeout.')
       
        # Delay
        time.sleep(5)
  
if __name__ == '__main__':
   main()

Credits

Bob Hammell

Bob Hammell

8 projects • 25 followers
Developer interested in Python, Arduino, & Matlab. Background in Image Processing and Remote Sensing.

Comments