HOWTO · Arduino
在 Arduino 中制作计数器
可以使用 Arduino 中的循环制作计数器。
本页内容
要用 Arduino 制作计数器,请将按钮连接到数字输入引脚和 GND,每次按下只读取一次,让变量递增,并将数值打印到串口监视器。下面的示例适用于兼容 Uno 的开发板,并会在达到可配置的上限后将计数归零。内置 LED 或外接 LED 可用于提示按钮已被识别,但不能显示计数数值。
Arduino 计数器的工作原理
计数器是一个用于存储数字的变量;事件发生时,它的值会改变。在这个项目中,事件就是按下按钮。Arduino 会反复运行 loop() 并检查输入;当按钮从松开变为按下时,计数值增加一次。短暂的消抖间隔可以过滤实体开关闭合时可能产生的快速电气变化。
循环也可以重复固定次数的操作。例如,for 循环可以让 LED 闪烁五次后停止,这就是有限循环;Arduino 的 loop() 则会持续运行。这里的主程序使用持续运行的循环来监测按钮。
连接按钮和 LED
使用 INPUT_PULLUP 时,将按钮的一端连接到数字引脚 2,另一端连接到 GND。开发板的内部上拉电阻会在按钮松开时使输入保持 HIGH;按下按钮后,引脚会接到 GND,读数变为 LOW。采用这种接线方式时,不需要外接上拉电阻。
如果使用外接 LED,请将数字引脚 13 通过限流电阻连接到 LED 的阳极(长脚),再将阴极(短脚)连接到 GND。Uno 的内置 LED 通常连接到引脚 13;使用其他开发板时,请先查看引脚图。程序使用 LED_BUILTIN,以调用开发板定义的内置 LED 引脚。LED 电路的电流必须保持在开发板引脚的限制范围内。
编写并上传按钮计数器程序
下面的完整 C++ 源代码可以作为 Arduino IDE 中的草图使用。在桌面 C++ 构建中,随附的测试框架会提供三次按钮按下输入,让计数逻辑产生可见结果。将 resetAt 设为计数器应归零的第一个计数值;消抖间隔为 30 毫秒。
#ifdef ARDUINO
#include <Arduino.h>
#else
// Desktop harness for a deterministic button sequence.
#include <iostream>
using byte = unsigned char;
const int HIGH = 1, LOW = 0, INPUT_PULLUP = 2, OUTPUT = 3;
const int LED_BUILTIN = 13;
unsigned long mockNow = 0;
void pinMode(byte, int) {}
void digitalWrite(byte, int) {}
unsigned long millis() { return mockNow; }
int digitalRead(byte) {
bool pressed = (mockNow >= 10 && mockNow < 50) ||
(mockNow >= 100 && mockNow < 140) ||
(mockNow >= 190 && mockNow < 230);
return pressed ? LOW : HIGH;
}
struct MockSerial {
void begin(int) {}
void println(int value) { std::cout << value << '\n'; }
void println(const char* value) { std::cout << value << '\n'; }
} Serial;
#endif
const byte buttonPin = 2;
const byte ledPin = LED_BUILTIN;
const unsigned long debounceMs = 30;
const int resetAt = 3;
int counter = 0;
int lastRawReading = HIGH;
int stableReading = HIGH;
unsigned long lastChangeTime = 0;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int reading = digitalRead(buttonPin);
unsigned long now = millis();
if (reading != lastRawReading) {
lastRawReading = reading;
lastChangeTime = now;
}
if (now - lastChangeTime >= debounceMs && reading != stableReading) {
stableReading = reading;
if (stableReading == LOW) {
counter++;
digitalWrite(ledPin, HIGH);
Serial.println(counter);
if (counter >= resetAt) {
counter = 0;
Serial.println("Counter reset");
}
} else {
digitalWrite(ledPin, LOW);
}
}
}
#ifndef ARDUINO
int main() {
setup();
for (mockNow = 0; mockNow <= 230; mockNow += 10) loop();
}
#endif
1
2
3
Counter reset
在桌面测试框架中,提供的三次按下输入会达到 resetAt,因此输出会先显示每次计数,随后显示重置消息。
在 Arduino IDE 中,选择已连接的开发板和端口并上传草图,然后打开 Tools > Serial Monitor,将波特率设为 9600。每次计数时按下并松开按钮。串口监视器会打印 1、2 和 3;第三次按下后会打印 Counter reset,下一次按下则会打印 1。按钮保持稳定按下时 LED 会亮起,松开后熄灭。在硬件上,setup() 和 loop() 使用 Arduino 核心库;桌面测试框架则为相同的计数逻辑提供固定输入序列。
显示并重置计数
这个示例使用串口监视器显示数字。单个 LED 可以提示按钮按下已被识别,但无法显示计数值。若要在设备上显示数字,可以使用七段显示模块或 LCD,并接好所需线路、使用相应库;本草图没有实现这些显示功能。
计数器会在达到 resetAt 时自动重置:草图先打印达到的阈值,再将存储的计数值设为零并继续运行。将 resetAt 改为另一个正整数即可设置不同的上限。代码没有使用单独的重置按钮。如果要添加重置按钮,请为它分配独立输入,并明确说明接线和行为,不要依赖未使用的引脚。
常见问题
需要哪些组件?
一块兼容 Uno 的开发板、一个按钮、跳线和一根 USB 线,就足以统计按钮按下次数并在电脑上查看结果。可以使用内置 LED,也可以添加带限流电阻的外接 LED 来提供视觉反馈。
可以使用其他显示屏吗?
可以。LCD 或七段显示器都能显示数字,但两者都需要合适的接线和显示代码。上面的示例会将数字发送到串口监视器,并且只用 LED 提示按钮按下。
如何更改重置上限?
编辑草图开头附近的 resetAt。计数器会在打印达到上限的数值后立即重置。
计数器可以递减吗?
可以。要制作递减计数器,可在识别到按钮按下时减一,并决定计数到达下限时应如何处理。上面的草图没有实现这一改动。
可以添加更多按钮吗?
可以。为每个额外按钮分配一个引脚、配置其输入,并设置不同的操作,例如递减或手动重置。根据所选的输入模式为每个按钮接线;主示例只处理一个按钮。