树莓派Python脚本多断电循环记录数据防损坏及SQLite启动问题
树莓派电压/电流数据记录方案优化及SQLite自启问题解决
一、避免断电导致文件损坏的可靠方案
1. 优化文本文件写入逻辑
- 每次写入用
with语句自动管理文件句柄,确保写入后立即关闭并刷新缓冲区,同时启用行缓冲减少内存缓存数据:import time def get_voltage(): # 替换为实际传感器读取逻辑 return 5.1 def get_current(): # 替换为实际传感器读取逻辑 return 0.2 while True: voltage = get_voltage() current = get_current() data_line = f"{time.strftime('%Y-%m-%d %H:%M:%S')}, {voltage}, {current}\n" # buffering=1启用行缓冲,确保数据即时写入磁盘 with open("voltage_current.log", "a", buffering=1) as f: f.write(data_line) time.sleep(1) - 批次写入独立文件时,通过扫描目录获取最新序号避免覆盖旧数据:
开机时自动扫描现有文件,从最大序号+1开始写入,完全不会覆盖历史数据。import os import time def get_next_file_num(): num = 1 while os.path.exists(f"VoltageData{num}.txt"): num += 1 return num current_file_num = get_next_file_num() count = 0 while True: voltage = get_voltage() current = get_current() data_line = f"{time.strftime('%Y-%m-%d %H:%M:%S')}, {voltage}, {current}\n" with open(f"VoltageData{current_file_num}.txt", "a") as f: f.write(data_line) count += 1 if count >= 1000: count = 0 current_file_num += 1 time.sleep(1)
2. SQLite数据库方案优化(解决自启失败问题)
SQLite是嵌入式数据库,不需要额外的开机服务,它直接操作本地文件,不存在依赖服务未启动的情况。自启失败大概率是systemd服务配置问题,按以下步骤排查修复:
- 检查并修正systemd服务文件(例:
/etc/systemd/system/data-record.service):[Unit] Description=Voltage/Current Data Recorder After=multi-user.target # 若依赖硬件服务(如I2C传感器),可添加对应依赖项,比如: # After=sys-devices-platform-soc-3f804000.i2c-i2c-1.device [Service] Type=simple User=pi # 确保Python路径和脚本路径正确,可用which python3确认路径 ExecStart=/usr/bin/python3 /home/pi/data_recorder.py # 设置工作目录为脚本所在路径,避免文件路径错误 WorkingDirectory=/home/pi # 异常退出后自动重启 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target - 重新加载并启用服务:
sudo systemctl daemon-reload sudo systemctl enable data-record.service sudo systemctl start data-record.service - 查看服务状态排查错误:
sudo systemctl status data-record.service # 实时查看日志 journalctl -u data-record.service -f - 脚本中使用数据库绝对路径,避免工作目录导致的路径问题:
import sqlite3 import time db_path = "/home/pi/sensor_data.db" conn = sqlite3.connect(db_path) cursor = conn.cursor() # 确保表存在,仅第一次运行时创建 cursor.execute('''CREATE TABLE IF NOT EXISTS sensor_data (timestamp TEXT, voltage REAL, current REAL)''') conn.commit() while True: voltage = get_voltage() current = get_current() timestamp = time.strftime('%Y-%m-%d %H:%M:%S') cursor.execute("INSERT INTO sensor_data VALUES (?, ?, ?)", (timestamp, voltage, current)) # 每次插入后立即提交,确保数据写入磁盘 conn.commit() time.sleep(1)
二、额外可靠性建议
- 启用树莓派文件系统只读模式:彻底避免断电导致的文件系统损坏,可将数据文件挂载到RAM磁盘,定期同步到SD卡;或使用支持断电保护的外部存储(如USB SSD)。
- 数据库写入后必须执行
conn.commit(),避免未提交的内存数据丢失。
内容的提问来源于stack exchange,提问作者wrhsc1310
相关产品推荐
相关产品推荐

