搜索代码

第14/31-2课:Arduino编程millis()示例2与事件

第14/31-2课:Arduino编程millis()示例2与事件

在本教程中,您将学习如何使用Arduino的millis()函数,在指定时间过去后触发操作,而不会阻塞程序的其余部分。这是创建响应式Arduino项目的基础技术,在这些项目中,多个任务需要并发运行,例如在读取传感器或监测按钮按下时闪烁LED。这个具体示例侧重于在五秒后触发事件,但该逻辑可以应用于无数现实场景。

组装好的Sunfounder小车

以下是一些实际示例,说明您可能如何在您自己的项目中使用此模式:

  • 延迟激活:仅在系统运行设定时间后打开风扇或水泵。
  • 安全联锁:要求按钮被按下并保持一段时间后,才能执行危险操作,例如启动电机。
  • 基于时间的警报:如果传感器读数在特定时间内没有变化,则触发警报或通知。
  • 非阻塞定时器:创建一个“看门狗”定时器,如果设备无响应则重置它。

这解决的核心问题是delay()函数的局限性。当您使用delay(5000)时,Arduino在这五秒内停止执行任何其他代码。这对于简单的草图来说没问题,但在更复杂的项目中,当您需要在等待时读取传感器、更新显示器或监听按钮按下时,这就成了一个大问题。millis()函数计算自电路板上电以来的毫秒数,允许您在不暂停程序的情况下检查时间。

所需硬件

  • Arduino板(Uno、Nano、Mega等)
  • 一个按钮
  • 跳线

接线指南

此示例的接线非常简单。它使用内部上拉电阻,因此按钮不需要外部电阻。

  • 将按钮的一条腿连接到Arduino上的GND引脚。
  • 将按钮的另一条腿连接到Arduino上的数字引脚2

因为我们在代码中使用INPUT_PULLUP,当按钮未按下时引脚将读取HIGH,当按钮按下时将引脚连接到地,读取LOW(视频中08:29处)

理解代码

这段代码演示了一个简单的事件驱动定时器。程序不断将当前的millis()值打印到串行监视器。当按钮被按下并保持,且Arduino已运行至少5秒时,它将打印“Take action”到串行监视器。关键是millis()检查不会停止时间的连续打印。

让我们分解代码中用户可配置的部分:

unsigned long event = 5000;// 5秒

这是最重要的可配置变量。它定义了“事件”的持续时间(以毫秒为单位)。在此示例中,设置为5000,即5秒。要更改延迟,只需修改此数字。例如,将其设置为10000将使操作在10秒后触发。使用unsigned long数据类型至关重要,因为millis()的值可能变得非常大,最终会超过标准int变量的最大值,导致比较错误。(视频中05:46处)

pinMode(2,INPUT_PULLUP);

此行将数字引脚2配置为输入并激活其内部上拉电阻。这是一个关键的配置步骤,允许您在没有外部电阻的情况下连接按钮。引脚默认读取HIGH,当按钮按下时将其连接到地,读取LOW。如果您希望使用不同的引脚,请在此处和循环中的digitalRead(2)行中更改数字2(视频中08:46处)

loop()内部的逻辑很简单。它读取按钮的状态。如果按钮被按下(pb == LOW),则检查当前时间(millis())是否大于或等于您定义的event时间。如果两个条件都为真,则打印操作消息。循环的其余部分(打印时间)继续不间断地运行,展示了millis()相对于delay()的优势。

此示例从Arduino启动时开始检查时间。视频系列中的第三个示例在此基础上构建,记录第一次按下按钮的时间,并且仅当第二次按下发生在至少5秒后才触发操作。该逻辑在第14课/31-3:Arduino编码millis()示例3与按钮中介绍。

实时项目演示

上传代码并打开串行监视器(波特率9600)后,您将看到连续的数字流,表示自电路板上电以来的毫秒数。如果您在5秒过去之前按下并保持按钮,则不会发生任何事情。但是,如果您在5秒标记之后按下并保持按钮,您将看到消息“Take action”打印在串行监视器中。只要按钮被保持,操作将继续打印。这演示了一个非阻塞定时器,允许其他代码(打印)无缝运行。(视频中10:52处)

本视频的相关项目

本视频是关于Arduino定时和映射函数的多部分系列的一部分。探索基于相同源材料创建的其他教程:

章节

  • [00:00] millis()和SunFounder套件简介
  • [01:19] 什么是millis(),为什么用它代替delay()?
  • [03:06] 实际演示:打印millis()值
  • [05:46] 使用millis()和unsigned long创建事件
  • [08:29] 使用INPUT_PULLUP接线和编码按钮
  • [10:52] 运行带按钮的事件示例
  • [12:14] 示例3预览:检测第二次按钮按下
  • [17:20] map()函数简介
  • [19:47] 使用LED编码和演示map()函数

图像

Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
917-Lesson 14/31-2: Arduino coding millis() example 2 with event
语言: C++
/*
Lesson 14/31: Arduino coding millis() example 2 with event
Get this code and watch video Download and resource page https://robojax.com/RJT597
YouTube video https://www.youtube.com/watch?v=lqgzQohNiIM
 
  
 * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


unsigned long event = 5000;// 5 seconds
void setup() {
  Serial.begin(9600);//initialize serial monitor
  Serial.println("Introduction to millis");
  pinMode(2,INPUT_PULLUP);
  


}

void loop() {
  // Robojax.com millis() example 1
  Serial.println(millis());
  int pb = digitalRead(2);// read pin 2
  if(pb ==LOW)
  {
      if(millis() >= event)
      {
        Serial.println("Take action");
      }// if end
  }// if end
  
}// loop end

资源与参考

文件📁

用户手册