我对 C++ 和 Arduino 很陌生。我购买了一个叫做可拆解闹钟的小工具。我正在寻找修改代码,以便在启动时自动开始倒计时。现在,您必须手动按下红色按钮 (DET) 才能开始倒计时。有没有办法可以绕过红色按钮并自动倒计时?
这是默认代码:
https://gist.github.com/anonymous/a5acc051ae6157e6e7f1
谢谢你的帮助!
查看代码,您可以识别 4 个不同的输入按钮:
pinMode(HOUR_BUTTON_PIN, INPUT);
pinMode(MIN_BUTTON_PIN, INPUT);
pinMode(ALARM_BUTTON_PIN, INPUT);
pinMode(DET_BUTTON_PIN, INPUT);
显然,红色按钮是 ALARM 或 DET 按钮。
让我们看看何时读取每个按钮的输入。负责这个玩具逻辑的代码不是digitalRead
直接使用,而是通过buttonPressed
,buttonPressedNew
和buttonHeld
函数。每个函数接收一个代表按钮的数字,如果按钮处于函数名称建议的状态,则返回 true。按钮编号在开头定义并通过buttonPins
数组映射到按钮引脚。
#define MIN_BUTTON 0
#define HOUR_BUTTON 1
#define DET_BUTTON 2
#define ALARM_BUTTON 3
...
byte buttonPins[4] = {MIN_BUTTON_PIN, HOUR_BUTTON_PIN, DET_BUTTON_PIN, ALARM_BUTTON_PIN};
回到我们的问题,我们来看一下查询到 DET_BUTTON 和 ALARM_BUTTON 的位置。我将只关注设置和循环,因为这些是“按下红色按钮开始”逻辑最有可能发生的地方。
if (buttonPressed(DET_BUTTON)) {
// enable silent mode for testing
beep(3500, 50);
silent = true;
while (buttonPressed(DET_BUTTON)); // wait for release
}
这是用于蜂鸣器的通电测试 - 您在重置时按住按钮,只要您继续按住它,就会发出哔声。
// check input
if ((buttonPressed(ALARM_BUTTON)) && (!displayCountdown)) {
displayAlarmTime = true;
if (alarmpm) {
digitalWrite(LED_PM, HIGH);
} else {
digitalWrite(LED_PM, LOW);
}
if (alarmMode == ALARM_OFF) {
digitalWrite(LED_ALARM, LOW);
digitalWrite(LED_DET, LOW);
} else {
digitalWrite(LED_ALARM, HIGH);
if (alarmMode == ALARM_DET) {
digitalWrite(LED_DET, HIGH);
} else {
digitalWrite(LED_DET, LOW);
}
}
} else {
displayAlarmTime = false;
digitalWrite(LED_ALARM, LOW);
digitalWrite(LED_DET, LOW);
}
这与 LED 指示灯有关。如果按下警报按钮并且屏幕上未显示倒计时,则某些 LED 将亮起,否则它们将熄灭。还有displayAlarmTime
一个标志,指示应在屏幕上显示警报时间。
if (!buttonPressed(ALARM_BUTTON)) {
if (countdownSeconds < 5940) {
countdownSeconds += 60;
countdownDuration += 60;
}
这段代码在if (buttonPressedNew(HOUR_BUTTON) || buttonHeld(HOUR_BUTTON, 150))
blkock 里面,所以没意思。下一个片段的类似判决,我没有费心复制。
if (buttonPressedNew(DET_BUTTON)) {
if (displayAlarmTime) {
alarmMode++;
if (alarmMode > ALARM_DET) {
alarmMode = ALARM_OFF;
}
if (alarmMode == ALARM_OFF) {
snoozeActivated = false;
}
return;
}
if ((displayZeros) || (isDefused)) {
isDefused = false;
displayZeros = false;
displayCountdown = false;
return;
}
// The DET button has been pressed but not released yet.
detPressed = true;
countdownSeconds = defaultCountdownSeconds;
displayCountdown = true;
}
第一部分与警报有关。这对我来说有点令人费解,因为只有三种警报模式,而数字最高的模式实际上是ALARM_DET
,所以这条线alarmMode > ALARM_DET
永远不会是真的。
无论如何,它看起来不像我们的候选人。
现在关于看起来更有希望的第二部分。我假设的标志displayZeros
表明显示屏上显示零,这意味着您没有按时化解。旗帜isDefused
表明你确实拆除了炸弹。一起,if ((displayZeros) || (isDefused))
表示您处于“游戏”的结尾(您赢了或输了),因此应该采取的措施是重置显示。
该标志detPressed
用于记住按下了 DET 按钮。它将在检查 DET 按钮未被按下的代码中被重置,因此只要按下按钮,它就会保持不变。
该变量countdownSeconds
保存倒计时结束的 os 秒数(显然)。然后代码还告诉显示逻辑在屏幕上显示这个倒计时。
if (!buttonPressed(DET_BUTTON)) {
if (detPressed) {
detPressed = false;
defaultCountdownSeconds = countdownSeconds;
writeEEPROM();
countdown();
}
}
这是最后一部分。当您释放 DET 按钮时,内部逻辑将发生。它将defaultCountDown
秒数设置为当前的倒计时秒数,我猜这是因为您可以在按下按钮时更改倒计时,向 eeprom 写入一些内容(默认倒计时?)并...启动倒计时!
现在,我希望您有足够的信息来弄清楚如何以您想要的方式更改程序。
20秒答案:
在行中:
if ((buttonPressed(ALARM_BUTTON)) && (!displayCountdown))
删除 buttonPressed(ALARM_BUTTON) 条件。
也许你会得到你想要的。