This is a singular exception to show you how it works:
This is the english speaking forum.
You have to do the work of translating from english to chinese and from chinese to english for all future postings
函数 delay() 被阻塞
这意味着只要执行延迟,在延迟完成之前就不能做其他事情。
所以你的代码需要一个基本的重新设计才能非阻塞地工作
您希望某些操作每 3 秒只发生一次
所以你的代码需要检查 3 秒是否已经过去。
这是基于一个叫做millis()的函数完成的
作为一个易于跟踪数字的全天示例
delay() 正在阻塞。只要延迟是“延迟”,就不能执行任何其他代码。
现在有一种非阻塞计时技术。
非阻塞计时的基本原理与使用delay() **根本不同**
**您必须先了解差异**,然后再查看代码。
否则你可能会尝试在millis()代码中“看到”一个“延迟模拟事物”**它真的不是**
试图在millis() 中看到“延迟模拟的东西”使得很难理解millis()
了解了基于millis()的非阻塞计时的基本原理,就容易理解了。
想象一下烤一个磨砂披萨
封面上写着准备将烤箱加热到 200°C
然后把披萨放进去。
烘烤时间10分钟
您估计加热需要 3 分钟
你看看你的手表是 13:02(时间快照)
你开始看报纸,不时看看你的手表
手表显示 13:02。 13:02 - 13:02 = 0 分钟过去了
手表显示 13:03。 13:03 - 13:02 = 1 分钟过去了
手表显示 13:04。 13:04 - 13:02 = 2 分钟还没到
watch 显示 13:05 我什么时候开始 13:02 的? OK 13:05 - 13:02 = 3 分钟时间将披萨放入烤箱
新基时间 13:05(时间快照)
看 13:06 还没到时间
看 13:07 还没到时间
看 13:08 还没到时间(13:08 - 13:05 = 3 分钟不到 10 分钟
看 13:09 还没到时间
看 13:10 还没到时间
看 13:11 还没到时间
看 13:12 还没到时间
看 13:13 还没到时间
看 13:14 还没到时间(13:14 - 13:05 = 9 分钟不到 10 分钟
看 13:15 我什么时候开始的 13:05 OK 13:15 - 13:05 = 10 分钟吃披萨的时间(yum yum)
你做了一个反复比较已经过去了多少时间
这就是非阻塞时序的作用
在查看“已经过去了多少时间”的代码中完成
当前时间 - 开始时间 >= 烘焙时间
烘烤时间为10分钟
13:06 - 13:05 = 1 分钟 >= bakeTime 是假的
13:07 - 13:05 = 2 分钟 >= bakeTime 为假
...
13:14 - 13:05 = 9 分钟 >= bakeTime 是假的
13:15 - 13:05 = 10 分钟 >= bakeTime 是计时动作的正确时间!!
所以你的 loop() 正在做
空循环()
// 做各种事情,比如看报纸
if (currentTime - previousTime >= period) {
以前的时间 = 当前时间; // 首先要做的是更新时间的快照
// 定时动作的时间
}
它必须完全以这种方式编码,因为通过这种方式它可以管理从 Max 回零的翻转
函数millis() 自动
baldengineer.com 也有关于使用函数millis() 计时的非常好的教程。
有一段明确指出了函数 delay() 和 millis() 之间的区别:
millis() 函数是 Arduino 库中最强大的函数之一。此函数返回自上次重置以来当前草图已运行的毫秒数。一开始,你可能会想,这不是每一个都有用的!但请考虑一下您在白天如何报时。实际上,您可以查看自午夜以来已经过去了多少分钟。这就是millis()背后的想法!
与使用 delay() 时“等待一段时间”不同,您可以使用 millis() 来询问“已经过去了多少时间”?
https://www.baldengineer.com/millis-tutorial.html
The function delay() is blocking
This means as long as a delay is executed no other thing can be done until the delay has finished.
So your code needs a fundamental re-design to work non-blocking
You want to have that some actions only take place once every 3 seconds
So your code needs to check if 3 seconds have passed by.
This is done based on a function called millis()
as an allday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()
You have to understand the difference first and then look into the code.
otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.
imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes
You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch shows 13:02. 13:02 - 13:02 = 0 minutes passed by not yet time
watch shows 13:03. 13:03 - 13:02 = 1 minute passed by not yet time
watch shows 13:04. 13:04 - 13:02 = 2 minutes passed by not yet time
watch shows 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven
New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)
You did a repeated comparing how much time has passed by
This is what non-blocking timing does
In the code looking at "How much time has passed by" is done
currentTime - startTime >= bakingTime
bakingTime is 10 minutes
13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!
So your loop() is doing
void loop()
// doing all kinds of stuff like reading the newspaper
if (currentTime - previousTime >= period) {
previousTime = currentTime; // first thing to do is updating the snapshot of time
// time for timed action
}
it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function millis() automatically
baldengineer.com has a very good tutorial about timing with function millis() too .
There is one paragraph that nails down the difference between function delay() and millis() down to the point:
The millis() function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!
Instead of “waiting a certain amount of time” like you do with delay(), you can use millis() to ask “how much time has passed”?
best regards Stefan