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

MicroPython环境下ESP32如何获取开机/程序启动后的运行时长

MicroPython ESP32运行时长统计方案

核心实现(无需额外依赖,优先使用)

不需要依赖datetime模块,也不用受Thonny同步主机时间的干扰,直接使用MicroPython内置utime模块的硬件滴答接口即可实现精准的开机运行时长统计,计数基准为芯片上电复位时刻,完全独立于RTC时间,不受Thonny同步时间操作影响。

注意不要使用utime.time()、utime.localtime()这类返回绝对RTC时间的接口,Thonny连接设备时会默认将电脑时间同步到ESP32的RTC域,这就是观察到时间元组来自电脑的原因。

在程序最起始位置加入以下代码,即可获取精度1毫秒的运行时长:

import utime

# 程序启动第一时间记录初始滴答值,作为0秒基准
_start_ms = utime.ticks_ms()

def get_uptime_seconds() -> float:
    """返回程序启动到当前的运行时长,单位:秒"""
    return utime.ticks_diff(utime.ticks_ms(), _start_ms) / 1000

关键说明:必须使用utime.ticks_diff()计算时间差,禁止直接对两个ticks值做算术减法。ticks_ms()为32位循环计数,约每49天溢出一次,ticks_diff()是官方内置的溢出安全差值计算接口,可保证任意时间点返回的时间差准确无误。

后续业务需求适配

针对屏幕显示、串口输出、日志存储需求,可直接用以下代码实现,不会阻塞ESPWebServer主逻辑:

时长格式转换

将秒数转换为通用的时:分:秒格式,适配屏幕显示和日志输出:

def format_uptime(total_sec: float) -> str:
    hours = int(total_sec // 3600)
    minutes = int((total_sec % 3600) // 60)
    seconds = int(total_sec % 60)
    return f"{hours:02d}:{minutes:02d}:{seconds:02d}"

串口/屏幕输出

直接调用函数取值即可:

# 串口输出
print(f"设备运行时长:{format_uptime(get_uptime_seconds())}")
# TFT屏幕显示直接把format_uptime的返回值传给屏幕文本绘制接口即可

每分钟写入本地日志

在主循环中加入非阻塞判断,避免用长延时影响Web服务运行:

last_log_min = -1

# 放入主循环
current_uptime = get_uptime_seconds()
current_min = int(current_uptime // 60)
if current_min != last_log_min:
    # 追加写入日志文件
    with open("uptime_record.txt", "a", encoding="utf-8") as f:
        f.write(f"{format_uptime(current_uptime)}\n")
    last_log_min = current_min
# 执行原有WebServer逻辑,加短延时避免占用过高
utime.sleep_ms(10)

本地可用的轻量udatetime模块

如果需要兼容datetime类的调用接口,可将以下代码保存为udatetime.py上传到ESP32本地文件系统,直接import即可使用,无需固件内置datetime支持,文件体积不到1KB:

# udatetime.py
import utime

_start_tick = utime.ticks_ms()

class datetime:
    @staticmethod
    def now() -> tuple:
        """返回当前RTC时间元组 (年,月,日,时,分,秒)"""
        year, month, day, hour, minute, second, *_ = utime.localtime()
        return (year, month, day, hour, minute, second)
    
    @staticmethod
    def uptime() -> float:
        """返回程序启动后的运行时长,单位:秒"""
        return utime.ticks_diff(utime.ticks_ms(), _start_tick) / 1000

调用示例:

import udatetime
print(udatetime.datetime.uptime())

其他问题说明

  • 遇到的help函数异常是所用2022-02-12 dirty版本固件的已知bug,仅help('modules')可用不影响业务逻辑运行,如需正常使用help可升级到v1.19及以上正式版MicroPython固件。
  • 板载电池电压读取无需移植官方Arduino封装,T-Display的电池分压接在GPIO34引脚,可直接通过ADC读取换算:
    from machine import ADC
    bat_adc = ADC(34)
    bat_adc.atten(ADC.ATTN_11DB)
    def get_bat_voltage() -> float:
        return bat_adc.read_uv() / 1000000 * 2  # 分压比为1/2,乘以2得到实际电压
    
    锂电池正常电压区间为3.0V(欠压)~4.2V(满电),可根据实际测试的电压对应电量设置关机阈值。

内容的提问来源于stack exchange,提问作者James V. Fields

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:25:04