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

Arduino计时器程序运行速度仅为预期1/4,求问题排查方案

问题诊断与修复方案

核心问题分析

你的计时器运行速度慢4倍的主要原因有两个:

1. 串口打印的耗时远超预期

你在每次循环中执行了大量Serial.print/Serial.println调用,而串口波特率设置为9600。按9600波特计算,每发送1字节数据大约需要1.04毫秒。以你提供的输出示例为例,每一行输出包含约26个字符(含换行符),发送这一行的时间就需要26 × 1.04 ≈ 27毫秒。再加上你设置的delay(10),单次循环的总耗时约为37毫秒,远大于你预期的10毫秒。这直接导致每秒仅能执行约27次循环,而非计划中的100次,最终造成计时速度严重偏慢。

2. 基于delay()的计时方式不可靠

使用delay(10)来模拟10毫秒间隔的思路本身存在缺陷,因为delay()是阻塞式函数,且循环中其他代码(如串口打印、变量进位逻辑)的执行时间会额外增加循环总耗时,导致实际间隔远大于预期的10毫秒。Arduino的标准实践是使用millis()实现非阻塞式计时,避免依赖固定延迟。

修复后的代码示例

以下是优化后的代码,采用millis()进行精确计时,同时减少不必要的串口输出频率(比如每100毫秒打印一次,而非每10毫秒),既保证计时精度,又降低串口开销:

void setup() {
  Serial.begin(9600);
  Serial.println();
  Serial.println("Timer will start in 5 seconds");
  delay(5000);
}

// 计时变量
unsigned long previousMillis = 0;
const long interval = 10; // 10毫秒间隔

int tenMilliSeconds = 0;
int hundredMilliSeconds = 0;
int seconds = 0;
int tenSeconds = 0;
int minutes = 0;
int tenMinutes = 0;
int hundredMinutes = 0;

void loop() {
  unsigned long currentMillis = millis();

  // 仅当达到10毫秒间隔时更新计时变量
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    
    tenMilliSeconds++;
    if (tenMilliSeconds == 10) {
      tenMilliSeconds = 0;
      hundredMilliSeconds++;
    }
    if (hundredMilliSeconds == 10) {
      hundredMilliSeconds = 0;
      seconds++;
    }
    if (seconds == 10) {
      seconds = 0;
      tenSeconds++;
    }
    if (tenSeconds == 6) {
      tenSeconds = 0;
      minutes++;
    }
    if (minutes == 10) {
      minutes = 0;
      tenMinutes++;
    }
    if (tenMinutes == 10) {
      tenMinutes = 0;
      hundredMinutes++;
    }
    if (hundredMinutes == 10) {
      Serial.println("The limit has been reached.");
      while (true) { // 停止计时
        delay(1000);
      }
    }

    // 每100毫秒打印一次(即每10次间隔打印),减少串口开销
    if (hundredMilliSeconds % 10 == 0 && tenMilliSeconds == 0) {
      Serial.print(hundredMinutes);
      Serial.print(" : ");
      Serial.print(tenMinutes);
      Serial.print(" : ");
      Serial.print(minutes);
      Serial.print(" :: ");
      Serial.print(tenSeconds);
      Serial.print(" : ");
      Serial.print(seconds);
      Serial.print(" :: ");
      Serial.print(hundredMilliSeconds);
      Serial.print(" : ");
      Serial.println(tenMilliSeconds);
    }
  }
}

额外优化建议

  • 如果需要更高的串口输出频率,可以将波特率提高到115200,这能大幅降低串口发送时间。
  • 避免在计时循环中执行任何阻塞操作(如delay()),所有耗时操作都应采用非阻塞方式处理。

内容的提问来源于stack exchange,提问作者Morten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:20:54