I found and edited some code that records water flow data off of a flowmeter. I have managed to edit the script to run for only 5 mins and write to a file (I tried a .csv file but I am realizing this may not be entirely possible). However, when the script runs, the data file created just lists one “row” of recorded data. The while loop runs every 5 seconds for about 5 mins and provides a timestamp and a flow-rate reading, I’m trying to get the script to continuously record data. Here is the code:
import json
import time
from datetime import datetime, timedelta
import RPi.GPIO as GPIO
import csv
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)
end_time = datetime.now() + timedelta(minutes=5)
while True:
timestamp = str(datetime.now())
flow_rate = flow_meter.getFlowRate()
time.sleep(5)
print('Timestamp: %s' % timestamp)
print('Flow rate: %f' % flow_rate)
header = ['Time','Flow Rate']
data = [timestamp, flow_rate]
with open('flowrate.csv', 'w', encoding='UTF8', newline='') as f:
writer = csv.writer(f)
writer.writerow(header)
writer.writerow(data)
if datetime.now() > end_time:
break
if __name__ == '__main__':
main()
I’ve included my “data writing” strings near the bottom in the while loop.
Advertisement
Answer
Opening the file with mode 'w'
overwrites the whole file every time. So, just write the header at the beginning, and “append” later on:
def main()
with open('flowrate.csv', 'w', encoding='UTF8', newline='') as f:
writer = csv.writer(f)
writer.writerow(header)
later, in the loop
with open('flowrate.csv', 'a', encoding='UTF8', newline='') as f:
writer = csv.writer(f)
writer.writerow(data)
This is only practical if you’re really only writing a row every now and then. If you’re writing more often, then you should just keep the file open and reuse the writer
instance.