反应计时器
Arduino C++在你刚组装好的板子上做一个反应计时游戏。13 号引脚上的 LED 在随机的 1 到 3 s 后亮起;玩家尽快按下 D2 上的按钮(接到 GND),从 LED 亮到按下的时间被打印出来,例如 Reaction: 312 ms。在 LED 亮之前按下则打印 Too soon!。每次按下后 LED 熄灭,开始新的一轮。用 D2 上的中断捕捉按下,做消抖,所有计时都用 millis(),永远不要用 delay()。
检查
- 尚未运行使用了 attachInterrupt、INPUT_PULLUP 和 millis(),从不使用 delay()
- 尚未运行LED 一开始保持熄灭
- 尚未运行LED 在 3 s 内亮起
- 尚未运行按下后 LED 立即熄灭,并开始新的一轮
- 尚未运行打印反应时间,例如 Reaction: 312 ms
- 尚未运行在 LED 亮起之前按下会打印 Too soon!
提示
- attachInterrupt(digitalPinToInterrupt(2), onFall, FALLING) 会在 D2 下降的那一刻运行 onFall。中断程序要短:把 millis() 记到一个 volatile 变量里,再设置一个标志。
- 触点在按下时和松开时都会抖动几毫秒。只有 20 ms 后引脚仍然读到 LOW,才算一次边沿。
- 不用 delay():记下 LED 应该亮起的时间 millis() + random(1000, 3001),并在 loop() 里用 (long)(millis() - goAt) >= 0 来比较,这样即使 millis() 溢出也没问题。
- 关掉中断后再复制中断写入的数据(noInterrupts() … interrupts()):unsigned long 有 4 个字节,而 AVR 一次只读一个字节。