树莓派while循环持续采集值的Python REST API实现方法
树莓派Zero光学传感器1秒采集+FastAPI接口实现
核心思路
完全规避反复启动Python解释器的开销,单进程常驻后台运行:
- 独立守护线程跑1秒间隔的传感器采集循环,进程启动后仅初始化一次传感器硬件
- FastAPI服务同进程运行,接口直接返回内存中缓存的最新采集值,无额外IO开销
- 全程单进程单worker,适配树莓派Zero有限的内存与CPU性能
第一步:安装依赖
在树莓派Zero的Python环境中执行安装命令:
pip install fastapi uvicorn # 如果是GPIO直连光学传感器,按需安装对应硬件库 # pip install gpiozero RPi.GPIO
第二步:完整实现代码
新建main.py文件,把传感器读取部分替换成你自己的硬件读取逻辑即可:
import time import threading from datetime import datetime from fastapi import FastAPI # 全局缓存:存储最新读数和对应采集时间 latest_reading = { "value": None, "timestamp": None } # 轻量线程锁,避免读写值冲突,开销可忽略 reading_lock = threading.Lock() app = FastAPI() def sensor_collect_loop(): """后台采集线程:固定1秒间隔读取传感器,更新全局缓存""" # 放传感器初始化代码,进程启动时仅执行一次 # 示例:sensor = OpticalSensor(input_pin=18) while True: try: # 替换成你实际的传感器读取逻辑 current_value = 0 # 改为current_value = sensor.read()这类实际调用 current_ts = datetime.now().isoformat() # 加锁更新缓存值 with reading_lock: latest_reading["value"] = current_value latest_reading["timestamp"] = current_ts except Exception as e: # 采集异常打印日志即可,不要终止循环 print(f"采集出错: {str(e)}") # 采集完成后等待1秒,满足1次/秒的采集频率 time.sleep(1) # FastAPI启动时自动拉起采集守护线程 @app.on_event("startup") async def startup_collector(): collector_thread = threading.Thread(target=sensor_collect_loop, daemon=True) collector_thread.start() # 对外REST API端点:返回最新采集值 @app.get("/latest-reading") def get_latest(): with reading_lock: return { "code": 200, "data": latest_reading }
第三步:启动与部署
- 测试启动:在代码所在目录执行如下命令
启动后访问uvicorn main:app --host 0.0.0.0 --port 8000 --workers 1http://树莓派局域网IP:8000/latest-reading即可拿到最新传感器数值,接口响应延迟普遍在10ms以内,完全满足性能要求。 - 开机自启:直接用systemd写常驻服务实现开机自动运行即可,不要用cron定时拉取脚本,避免重复启动进程产生不必要的开销。
注意:启动参数必须带
--workers 1,树莓派Zero内存仅512M,多worker模式会触发内存溢出导致进程崩溃。
性能说明
这套方案完全避开了之前每次启动Python产生的5秒以上开销:
- Python解释器开机仅启动一次,传感器硬件仅做一次初始化
- 采集循环稳定保持1秒间隔,实际时间误差在10ms以内
- 接口直接读取内存缓存值,不需要临时触发硬件读取,无等待延迟
- 常驻运行时CPU占用低于5%,内存占用不到30M,Zero可以长期稳定运行
内容的提问来源于stack exchange,提问作者S. Gissel
相关产品推荐
相关产品推荐

