Arduino 秒表程序几乎慢了 4 倍

问题描述 投票:0回答:1

我的程序应该在串行监视器上作为计时器提供输出,就像数字时钟一样。它做得很好,只是非常慢,在程序中经过一秒钟大约需要 4 秒。

该程序使用 10 毫秒的变量,每次增加 1,这应该意味着它每秒增加 100 次。每次达到 10 时,它都会将下一个设置得更高,下一个为 100 毫秒。这会持续经过秒、10秒(这会持续到6而不是10)、分钟、10分钟和100分钟。我是一名新程序员,如果内容混乱且难以阅读,敬请原谅。

void setup()
{
    // put your setup code here, to run once:
    Serial.begin(9600);
    Serial.println();
    Serial.println("Timer will start in 5 seconds");
    delay(5000);
}

void loop()
{
    // put your main code here, to run repeatedly:
    static int tenMilliSeconds = 0;
    static int hundredMilliSeconds = 0;
    if (tenMilliSeconds == 10)
    {
        tenMilliSeconds = 0;
        hundredMilliSeconds++;
    }
    static int seconds = 0;
    if (hundredMilliSeconds == 10)
    {
        hundredMilliSeconds = 0;
        seconds++;
    }
    static int tenSeconds = 0;
    if (seconds == 10)
    {
        seconds = 0;
        tenSeconds++;
    }
    static int minutes = 0;
    if (tenSeconds == 6)
    {
        tenSeconds = 0;
        minutes++;
    }
    static int tenMinutes = 0;
    if (minutes == 10)
    {
        minutes = 0;
        tenMinutes++;
    }
    static int hundredMinutes = 0;
    if (tenMinutes == 10)
    {
        tenMinutes = 0;
        hundredMinutes++;
    }
    if (hundredMinutes == 10)
    {
        Serial.println("The limit has been reached.");
        while (hundredMinutes == 10)
        {
            delay(100000);
        }
    }
    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);

    tenMilliSeconds++;
    delay(10);
}

我知道它是否有点偏离,因为它不能同时运行代码,但令我惊讶的是,在这种情况下它几乎慢了 4 倍,因为网上说典型的 Arduino 微控制器执行一个基本命令需要 60 纳秒!这还不够大,不足以造成凹痕。是否只是串行打印时间减慢了我的速度,而计时器本身运行良好?或者我的代码中的某个地方搞砸了。谢谢你。

编辑:这是串行监视器输出:

0 : 0 : 8 :: 4 : 0 :: 4 : 5
0 : 0 : 8 :: 4 : 0 :: 4 : 6
0 : 0 : 8 :: 4 : 0 :: 4 : 7
0 : 0 : 8 :: 4 : 0 :: 4 : 8
0 : 0 : 8 :: 4 : 0 :: 4 : 9
0 : 0 : 8 :: 4 : 0 :: 5 : 0

正如预期,但需要太长时间。

arduino arduino-uno arduino-ide serial-monitor
1个回答
0
投票

使用

Serial.begin(9600)
,您已将 Arduino 上的串行端口配置为以每秒 9600 位的速度传输,无奇偶校验位和一个停止位(请参阅 Serial.begin())。在每秒 9600 位的情况下,传输一位(1 或 0)需要 104 微秒。您使用 Serial.print() 发送的每个字节都将使用 10 位进行编码:1 个起始位、您要发送的字节的 8 位和 1 个停止位。如果每比特 104 微秒,则每个字节有 10 * 104 = 1040 微秒,或 1.04 毫秒。

每行长 29 个字节:27 个字符加上 2 个字节用于回车符和换行符。 29 字节 * 1.04 毫秒/字节为您提供大约 30 毫秒的时间来传输每行。

传输数据需要 30 毫秒,加上您用

delay()
添加的额外 10 毫秒延迟,每个循环至少有 40 毫秒。我说“至少”,因为所有这些指示do都需要时间。您有简单的递增、比较和赋值指令,这些指令非常快,但在 Serial.print(...)
 中,您还需要更耗时的整数到字符串转换以及将数据放入串行端口缓冲区等。

因此,由于循环时间为 40 毫秒 + 无论运行所有这些指令需要多长时间,这就解释了为什么输出比您预期的要慢 4 倍。

注意:

Serial.print()

是异步的,将在将下一个字节放入缓冲区后立即返回,这比我上面计算的 30 毫秒传输快
很多。然而,由于这些循环非常短,缓冲区很快就会填满,此时 Serial.print()
 
will 会等待,直到缓冲区中有足够的可用空间来容纳要发送的数据(这将需要相同数量的数据)传输该量数据所需的时间)。

您应该注意到,如果您以(高得多)的速率传输数据,一切都会更接近您的预期。然而,最终这种方法永远不会非常精确。如果您使用

micros()

millis()
 来测量已经过去了多少时间,并用它来计算您需要等待多长时间,您会得到更好的结果。

© www.soinside.com 2019 - 2024. All rights reserved.