You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Python流量计采数仅写单条CSV,如何让每次循环新增数据行

树莓派流量计CSV连续采集修复方案

问题根因

你遇到的CSV文件仅保留一行记录的核心原因是:每次循环都使用w(覆盖写入)模式打开CSV文件,每次写入操作都会清空文件原有内容,最终仅会保留最后一次循环的写入结果。同时每次循环重复写入表头也不符合CSV文件的格式规范。

核心修改点

  • 将CSV文件初始化、表头写入逻辑移至while循环外部,避免重复覆盖文件、重复写入表头
  • 调整time.sleep(5)的位置,避免采集的时间戳与实际写入时间存在5秒偏差
  • 新增GPIO清理逻辑,避免脚本退出后引脚状态触发异常警告

修改后完整代码

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)
    # 提前打开CSV文件,写入表头
    header = ['Time','Flow Rate']
    with open('flowrate.csv', 'w', encoding='UTF8', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(header)
        while True:
            timestamp = str(datetime.now())
            flow_rate = flow_meter.getFlowRate()
            print('Timestamp: %s' % timestamp)
            print('Flow rate: %f' % flow_rate)
            # 写入当前采集数据
            writer.writerow([timestamp, flow_rate])
            if datetime.now() > end_time:
                break 
            # 等待5秒进行下一次采集
            time.sleep(5)
    # 脚本退出前清理GPIO状态
    GPIO.cleanup()

if __name__ == '__main__':
   main()

可选高可靠性写入方案

如果担心脚本中途异常断电、进程被杀导致已采集数据丢失,可以改用每次循环追加写入的模式,无需保持文件长期打开,修改步骤如下:

  1. 导入os模块判断文件是否存在:在代码开头新增import os
  2. 把循环内的写入逻辑替换为如下代码即可:
header = ['Time','Flow Rate']
data = [timestamp, flow_rate]
# 判断文件是否存在,不存在则先写入表头
file_exists = os.path.exists('flowrate.csv')
with open('flowrate.csv', 'a', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)
    if not file_exists:
        writer.writerow(header)
    writer.writerow(data)

该方案每次写入后都会自动落盘保存,5秒一次的采集频率下性能损耗可以忽略。

内容的提问来源于stack exchange,提问作者Jackson A Swan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:36:01