I’m trying to connect a Water Flow Meter on my GrovePi to read it on the Raspberry Pi. This is the wiki of the G 1/2" Water Flow Meter. It has a rotating wheel that pulses a hall effect sensor. By reading the pulses generated in a given time, it’s easy to compute the actual water flow that runs to the meter. The meter has a given flow pulse that is different for different meters (the same meter exists in 1/8", 1/4", 3/4", 1" and 5/4" diameter, but the flow pulse is different for each meter). On the 1/2" meter, the flow pulse is 7.5. This means that on a frequency of 75 Hz, the water flow is 10 l/min. The water flow is defined by this formula:
Q = pulse_frequency * 60 / 7.5. Since it's very hard to measury exactly 1 second, it's better to measure both the number of pulses during the measuring time. The formula then becomes:
Q = pulses_measured * 60 / measuring_time / 7.5.
This for the theory. Now the practical thing: how to connect the meter to the GrovePi and writing the python-script.
The meter has 3 wires: black (GND), red (Vcc +5V) and yellow (signal output, low on pulse, high on no pulse). Since this is a digital meter, I try to connect it to one of the Digital Ports of the GrovePi (D5 in my case). The black wire goes to the GND (pin 4 of the D5-connector), the red to Vcc (pin 3 of the D5-connector) and the yellow to the either pin 2 of the D5-connector (normaly the white wire) or pin 1 of the D5-connector (normaly the yellow wire). To prevent the drifting of the voltage on the signal wire, a pull-up resistor of 10k is placed between the red and the yellow wire of the meter.
This is my python script:
# testflowmeter10.py
# Use Raspberry Pi and GrovePi to test input from Water Flow Meter
# Johan Vandewalle
# Version 0.10
# coding: latin-1
#!/usr/bin/python
# Import modules
import smbus
import time # Library to allow delay times
import datetime # Library to allow time and date recording
from array import array # Library to allow working with arrays
import os # Library to allow command line tasks
import unicodedata # Library to use unicode characters above value 127
import math # library with mathematical functions
import RPi.GPIO as GPIO # library with GPIO read- and write functions
import grovepi # library with the GrovePi functions
import struct
# for RPI version 1, use "bus = smbus.SMBus(0)"
rev = GPIO.RPI_REVISION
if rev == 2:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
# Define global variables
global WATER_FLOW_PIN
global LOGTIME
global PULSE_OUTPUT_FLOW_METER
global FLOW_SPEED
global VALUE
global FLOWTIME
global STARTTIME
# Set starting values variables
# This is the address of the Atmega328 on the GrovePi
address = 0x04
# Set starting values for global variables
WATER_FLOW_PIN = 5 FLOWTIME = 0.0
STARTTIME = 0.0
now = time.time() # Set now to current time in seconds since Epoch
date = datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d_%H:%M:%S")
# Set date to current time in YYYY-mm-dd_hh:mm:ss format
STARTTIME = now # Set WORKTIME at current time in seconds since Epoch
FLOWTIME = now
PULSE_OUTPUT_FLOW_METER = 7.5 # This sets the output frequency conversion rate (depending on the Water Flow Meter characteristics)
FLOW_SPEED = 0.0 # Set FLOW_SPEED start value at 0.0
LOGTIME = ["2014-04-21_19:00:00","2014-04-21_19:00:00","2014-04-21_19:00:00","2014-04-21_19:00:00","2014-04-21_19:00:00","2014-04-21_19:00:00","2014-04-21_19:00:00"]
VALUE = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Set array VALUE[0 to 6] with 7 readings, start value at 0.0
# Definition of functions
# Main function
def main():
global COUNT
initialise() # Call function initialise() to initalize port setting
while True: # Start infinitive loop
COUNT = 0 # Set start value at 0
read_flow_meter() # Call function read_flow_meter
time.sleep(5) # Pause 5 secs
def initialise():
pinMode(WATER_FLOW_PIN,"INPUT")
def read_flow_meter(): # Function to read Water Flow Meter
global LOGTIME
global VALUE
global COUNT
now = time.time() # Set now to current time in seconds since Epoch
STARTTIME = now # Set worktime at current time in seconds since Epoch
FLOWTIME = now # Set flowtime at currect time in seconds since Epoch
VALUE[6] = 0.0 # Set start value at 0.0
falling = 0 # Set start value at 0
rising = 0 # Set start value at 0
lus_teller = 0 # Set start value at 0
last_value = 'low' # Set start value at 'low'
pulse_value = 0
duration = 0.0
print( 'Reading Water Flow Meter for 1 second. Please wait ...' )
while duration < 1.0:
try:
pulse_value = digitalRead( WATER_FLOW_PIN ) # Read value from Water Flow Meter
print( 'lus_teller = ' + str( lus_teller ) + ', pulse_value = ' + str( pulse_value ) )
# if lus_teller == 0 and pulse_value == 1:
# last_value = 'high'
if pulse_value == 0:
if last_value == 'high':
falling = falling + 1 # Add 1 to variable low_tick to count the number of changes from high to low (falling pulses)
last_value = 'low'
if pulse_value == 1:
if last_value == 'low':
rising = rising + 1 # Add 1 to variable high_tick to count the number of changes from low to high (rising pulses)
last_value = 'high'
print( 'falling pulses = ' + str( falling ) + ', rising pulses = ' + str( rising ) + ', last_value = ' + last_value )
now = time.time() # Set now to current time in seconds since Epoch
print( 'now = ' + str( now ) )
date = datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d_%H:%M:%S")
# Set date to current time in YYYY-mm-dd_hh:mm:ss format
print( 'date = ' + date )
FLOWTIME = now # Set FLOWTIME at currect time in seconds since Epoch
duration = FLOWTIME - STARTTIME # Calculate duration of measuring in seconds (float)
print( 'duration = ' + str( duration ) )
except TypeError:
print( "Unable to read the Water Flow meter value" )
lus_teller = lus_teller + 1 # Add 1 to lus_teller to count the number of loops
LOGTIME[6] = date # Set LOGTIME[6] at current time in YYYY-mm-dd_hh:mm:ss format
VALUE[6] = round( ( ( ( 60.0 / duration ) * falling ) / PULSE_OUTPUT_FLOW_METER ), 2 )
# Calculate flow speed in l/min, rounded at 2 decimals (60.0 seconds / duration (measuring time in seconds) * number of rising pulses
print( 'last_value = ' + last_value )
print( 'falling pulses = ' + str( falling ) )
print( 'rising pulses = ' + str( rising ) )
print( 'lus_teller = ' + str( lus_teller ) + ' (number of times through loop).' )
print( 'now = ' + str( now ) + ' time in seconds from Epoch at last measuring. ' )
print( 'date = ' + date + ' (stringvalue of time at last measuring).' )
print( 'duration = ' + str( duration ) + ' (time elapsed between start en ending measuring).' )
print( 'LOGTIME[6] = ' + LOGTIME[6] + ' (saved time).' )
print( 'VALUE[6] = ' + str( VALUE[6] ) + ' (saved value in l/min rounded at 2 decimals).' )
print( CODE[6] + " (" + DESCRIPTION[6] + "). Flow meter readings during 1 second. Number of falling pulses = " + str( falling ) + ". Flow speed = " + str( VALUE[6] ) + " l/min. Logtime: " + LOGTIME[6] )
falling = 0 # Reset start value at 0
rising = 0 # Reset start value at 0
lus_teller = 0 # Reset start value at 0
duration = 0.0 # Reset start value at 0.0
main() # Call function main
The output isn’t what it should be. If I connect the yellow wire to pin 1 of the D5-connector, the value read with digitalRead(5) is always 1 (it makes no difference wheather water is flowing or not).
If I connect the yellow wire to pin 2 of the D5-connector, the value read with digitalRead(5)is always 255 (it makes no difference wheather water is flowing or not).
What am I doing wrong: is it an error in the script or isn’t this meter suited for connecting to one of the Digital ports? If so, to which port can I connect it?