利用CircuitPython内置传感器实现CPU温度监控与本地日志记录

news2026/5/15 19:04:52
1. 项目概述从芯片温度到数据洞察在嵌入式项目里给设备“把脉”是基本功。CPU温度这个看似简单的数据点其实是窥探硬件运行状态的绝佳窗口。它不仅能告诉你芯片是不是在“发烧”更能间接反映环境变化、负载情况甚至是散热设计的有效性。以前做这类监控往往得外挂一个温度传感器再折腾ADC采样和校准流程繁琐。直到我发现很多现代微控制器比如Adafruit常用的SAMD21系列其CPU内部就集成了温度传感器并且CircuitPython已经把它做成了一个开箱即用的属性。这个项目的核心就是绕开复杂的硬件电路直接利用microcontroller.cpu.temperature这个“内置仪表”把读取到的温度数据以文本日志的形式实时记录到开发板自带的闪存文件系统中。整个过程你只需要几行Python代码无需焊接无需额外的元器件真正体现了CircuitPython“快速原型”的理念。它非常适合用于长期部署的设备健康监测、环境温度趋势分析需注意CPU温度与环境温度的差异和滞后性或是作为学习嵌入式数据采集与文件IO的入门实践。2. 核心思路与方案选型解析2.1 为什么选择CircuitPython与内置传感器这个方案的核心优势在于“极简”。传统MCU开发无论是用Arduino C还是裸机C读取内部温度传感器都需要直接操作芯片的寄存器涉及复杂的模数转换、校准系数计算对新手极不友好。CircuitPython的microcontroller模块将这些底层细节全部封装提供了一个直接的.temperature属性返回的就是摄氏度浮点数极大地降低了技术门槛。选择文件系统记录而非无线传输或外接SD卡是基于场景的权衡。对于很多低功耗、离线或原型验证阶段的项目首先需要的是可靠、简单的数据落地方案。开发板内置的闪存通常有几MB虽然空间有限但记录温度这类小数据绰绰有余。直接写入文件系统数据立即可通过USB在电脑上查看流程闭环调试方便。这个方案奠定了数据流的基础感知CPU温度 - 处理可选单位转换 - 存储本地文件。2.2 权限管理一个关键的设计挑战这里遇到一个嵌入式系统里经典的矛盾开发便利性与运行时安全性的冲突。CircuitPython设备连接电脑后其内部存储会作为一个U盘USB Mass Storage挂载方便我们直接拖拽修改code.py等文件。但如果在程序运行code.py时也允许Python代码向同一个文件系统写入数据就会产生访问冲突可能导致数据损坏。因此CircuitPython默认将文件系统设置为“只读”模式供代码访问以保证USB侧可写。我们的日志程序需要写文件就必须改变这个默认行为。这就是boot.py和storage模块出场的原因。boot.py在系统启动、USB连接建立之前执行在这里我们可以用storage.remount(“/”, False)将根目录重新挂载为可写。但这样一来USB侧就失去了写入权限你无法再通过电脑直接编辑代码了。为了解决这个两难问题原教程给出了一个巧妙的硬件交互方案通过一个物理开关或跳线来动态决定启动时的挂载模式。具体来说在boot.py中检测某个GPIO引脚如D0的电平。如果该引脚被接地拉低则启动为“代码可写”模式用于数据记录如果该引脚悬空或拉高则保持默认的“USB可写”模式方便代码更新。这种设计将控制权交给了硬件状态非常符合嵌入式开发“硬软结合”的思维。3. 硬件准备与软件环境搭建3.1 硬件选型与连接本项目对硬件要求极低。核心是一块支持CircuitPython且CPU内置温度传感器的开发板。Adafruit Gemma M0、Trinket M0、Feather M0系列以及功能更丰富的Circuit Playground Express、Metro M4等只要是基于SAMD21Cortex-M0或SAMD51Cortex-M4F等系列芯片的板子通常都支持。购买前最好查阅官方文档确认microcontroller.cpu.temperature属性可用。对于实现“选择性挂载”功能你需要准备一个物理开关或一根跳线。以Gemma M0为例找一根杜邦线或直接用金属镊子/导线。将开发板的D0引脚或你代码中定义的其他引脚与GND地引脚短接。 这个短接动作就是在告诉boot.py“这次启动请允许我的代码写入文件系统”。当你需要更新代码时断开这个短接即可。注意Circuit Playground Express板载了一个滑动开关其电路已经连接到了D7引脚。因此对于CPX你无需额外飞线直接使用这个开关即可在代码中将检测的引脚改为board.D7。3.2 CircuitPython固件更新与库确认确保你的开发板运行的是CircuitPython 2.0.0或更高版本因为storage模块和microcontroller.cpu.temperature属性是从该版本引入的。更新固件是第一步访问CircuitPython官网找到你的板型对应的最新.uf2固件文件。将板子通过USB连接电脑并快速双击复位按钮使其进入BOOTLOADER模式此时电脑会出现一个名为CPLAYBOOT、FEATHERBOOT等的U盘。将下载的.uf2文件拖入该U盘。盘符会自动弹出稍等片刻板子重启后就会出现一个新的名为CIRCUITPY的U盘这表明CircuitPython固件已刷写成功。固件本身已包含microcontroller、storage、board、digitalio等核心模块无需额外安装库文件这为我们省去了很多依赖管理的麻烦。4. 核心代码实现与分步详解4.1 创建动态挂载控制的boot.py这个文件是系统启动的钥匙它只执行一次。我们将实现通过硬件引脚状态决定文件系统权限的逻辑。# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries # SPDX-License-Identifier: MIT import board import digitalio import storage # 1. 初始化硬件开关引脚 # 这里以D0为例如果你用CPX的滑动开关请改为 board.D7 switch_pin board.D0 switch digitalio.DigitalInOut(switch_pin) # 2. 配置引脚为输入模式并启用内部上拉电阻 switch.direction digitalio.Direction.INPUT switch.pull digitalio.Pull.UP # 默认内部上拉到高电平 # 3. 根据引脚电平决定挂载模式 # switch.value 在引脚被拉低接地时为 False悬空/拉高时为 True # 我们需要在引脚接地False时让代码可写readonlyFalse storage.remount(/, readonlyswitch.value)代码解读与实操要点digitalio.Pull.UP启用内部上拉电阻至关重要。它确保在引脚悬空时其电平能被稳定地拉至高电平逻辑1或True避免因静电干扰产生误判。只有当用导线明确将引脚与GND连接时电平才会被拉低至False。storage.remount(“/“, readonlyswitch.value)这是权限切换的核心。readonly参数为True时代码只能读不能写但USB可写方便我们更新程序。为False时代码可读写USB则变为只读。我们将引脚电平switch.value直接赋值给它实现了硬件控制逻辑。重要警告写完boot.py并保存后你必须先弹出EjectCIRCUITPYU盘再物理按下板子上的复位按钮boot.py才会在新的一次完整上电启动流程中执行。仅在REPL中按CtrlD软复位是无效的。4.2 主程序code.py温度记录与状态指示这是项目的主循环负责持续读取温度并写入文件同时通过LED提供状态反馈。# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries # SPDX-License-Identifier: MIT import time import board import digitalio import microcontroller # 1. 初始化状态指示灯LED # 大部分板子的板载LED连接在D13引脚 led digitalio.DigitalInOut(board.D13) led.switch_to_output() try: # 2. 以追加模式打开日志文件 with open(/temperature_log.txt, a) as log_file: while True: # 3. 读取CPU温度单位摄氏度 temp_c microcontroller.cpu.temperature # 可选转换为华氏度 # temp_f (temp_c * 9 / 5) 32 # log_file.write(‘{:.2f}\n’.format(temp_f)) # 4. 格式化并写入数据 # 使用 {0:f} 确保写入的是浮点数格式避免科学计数法 log_file.write(‘{0:f}\n’.format(temp_c)) # 立即刷新缓冲区确保数据写入物理存储避免断电丢失 log_file.flush() # 5. 翻转LED状态指示一次写入完成 led.value not led.value # 6. 设置采样间隔单位秒 time.sleep(1) except OSError as e: # 7. 异常处理处理文件写入失败的情况 blink_delay 0.5 # 默认错误闪烁频率1Hz (亮0.5s, 灭0.5s) # 错误码 28: 设备空间不足 if e.args[0] 28: blink_delay 0.25 # 空间不足时快速闪烁2Hz # 在实际项目中这里可以尝试删除旧文件或停止记录 # 错误码 30: 文件系统为只读可能boot.py未正确设置或D0未接地 # elif e.args[0] 30: # blink_delay 1.0 # 只读错误慢闪0.5Hz # # 可以添加更明确的错误指示如特定颜色RGB灯 # 进入错误指示循环 while True: led.value not led.value time.sleep(blink_delay)代码深度解析与避坑指南文件打开模式使用“a“(append) 模式而非“w“(write)。“w“模式每次打开都会清空文件原有内容只适合单次运行。而“a“模式会在文件末尾追加数据非常适合长期日志记录即使设备断电重启新的数据也会接在旧数据之后。flush()的重要性在嵌入式系统中为了延长Flash寿命和提升性能写入操作经常先缓存在内存中。log_file.flush()方法强制将缓冲区数据立即写入物理存储。如果不调用flush()在突然断电的情况下最近几秒的数据可能会丢失。对于关键数据记录这是一个必要的安全措施。错误处理的艺术try-except块是生产级代码的必备。我们主要捕获OSError。除了教程提到的错误码28空间不足错误码30同样关键它表示“只读文件系统错误”。如果你的程序一运行就进入错误闪烁且闪烁频率是默认的1Hz而非快速的2Hz很大概率就是错误码30即boot.py的挂载模式没有切换成功代码没有写入权限。此时应检查boot.py文件是否存在且语法正确。是否已通过“弹出U盘 - 物理复位”的流程重启。硬件上D0引脚是否已可靠接地。采样率与功耗权衡time.sleep(1)表示每秒记录一次。对于温度这种变化相对缓慢的量这个频率通常足够。如果你想降低功耗可以增大休眠间隔比如time.sleep(10)每10秒一次。但要注意过于频繁的写操作如sleep(0.1)会加速Flash磨损且温度读数本身也有一定的响应时间过高频率无意义。5. 系统部署、数据获取与可视化5.1 完整工作流部署硬件连接用导线将板子的D0或你指定的引脚与GND短接。文件部署在电脑上打开CIRCUITPY盘。首先创建或编辑boot.py写入4.1节的代码。然后创建code.py写入4.2节的代码。启动记录安全弹出CIRCUITPYU盘然后按下板子上的物理复位按钮。此时板载LED应开始以1秒为周期稳定闪烁表明程序正在正常运行并记录数据。停止与数据读取当需要停止记录并读取数据时首先断开D0与GND的短接线然后再次物理复位板子。这次启动由于boot.py检测到D0为高电平文件系统会以“USB可写”模式挂载。此时将板子连接电脑打开CIRCUITPY盘就能直接看到并打开temperature_log.txt文件里面是按行存储的温度值。5.2 数据处理与简单可视化获取到的temperature_log.txt是纯文本文件每一行一个温度值摄氏度。你可以用任何文本编辑器或脚本语言处理。使用Python进行简单分析import matplotlib.pyplot as plt # 读取数据 with open(‘temperature_log.txt‘, ‘r‘) as f: # 过滤空行并转换为浮点数列表 data [float(line.strip()) for line in f if line.strip()] # 基本统计 print(f“数据点数: {len(data)}“) print(f“平均温度: {sum(data)/len(data):.2f} °C“) print(f“最高温度: {max(data):.2f} °C“) print(f“最低温度: {min(data):.2f} °C“) # 绘制趋势图 plt.figure(figsize(10, 5)) plt.plot(data) plt.title(‘CPU Temperature Log‘) plt.xlabel(‘Sample Number‘) plt.ylabel(‘Temperature (°C)‘) plt.grid(True) plt.tight_layout() plt.show()这段脚本能帮你快速计算温度的平均值、极值并绘制出温度随时间采样序列变化的曲线图非常直观。5.3 项目扩展思路基础功能实现后你可以从多个维度扩展这个项目多传感器融合结合板载或外接的光照、湿度传感器如I2C接口的BME280在日志中同时记录多条数据线用逗号分隔形成CSV格式。时间戳记录CircuitPython的time模块可以获取自上次启动以来的相对时间time.monotonic()。虽然不能提供真实世界时间但可以记录采样间隔。如果需要绝对时间可以考虑外接一个便宜的RTC实时时钟模块。条件触发记录修改循环逻辑仅在温度超过某个阈值如temp_c 60时才进行记录和LED报警实现简单的过热保护监测。低功耗优化对于电池供电场景可以将主循环中的time.sleep()替换为microcontroller.cpu.sleep()等更深度的休眠指令并在休眠期间完全关闭外设仅依靠内部定时器唤醒大幅降低待机功耗。数据导出自动化编写一个电脑端的Python脚本当设备以“USB可写”模式连接时自动将temperature_log.txt文件复制到电脑指定位置并清空板子上的旧文件实现半自动化的数据收集。这个项目麻雀虽小五脏俱全涵盖了嵌入式开发中传感器数据采集、文件I/O操作、硬件交互、异常处理等多个核心环节。通过动手实践你能深刻理解软硬件协同的工作原理为后续更复杂的物联网应用打下坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2615787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…