Я довольно новичок в C ++ и Arduino. Я купил гаджет под названием Defusable Будильник. Я хочу изменить код, чтобы при включении он автоматически запускал обратный отсчет. Прямо сейчас вы должны вручную нажать красную кнопку (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);
}
Это связано со светодиодными индикаторами. Если кнопка будильника нажата и обратный отсчет не отображается на экране, некоторые светодиоды включатся, иначе они будут выключены. Также 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
содержит количество секунд, оставшихся до конца обратного отсчета (очевидно). И затем код также сообщает логике дисплея, чтобы отобразить этот отсчет на экране.
if (!buttonPressed(DET_BUTTON)) {
if (detPressed) {
detPressed = false;
defaultCountdownSeconds = countdownSeconds;
writeEEPROM();
countdown();
}
}
Это последняя часть. Внутренняя логика произойдет, когда вы отпустите кнопку DET. Это установит defaultCountDown
секунд до текущего отсчета секунд, я думаю, это потому, что вы можете изменить обратный отсчет, пока кнопка нажата, написать что-то (обратный отсчет по умолчанию?) в eeprom и … начать отсчет!
Теперь, я надеюсь, у вас достаточно информации, чтобы самим понять, как изменить программу нужным вам способом.
20 секундный ответ:
в соответствии:
if ((buttonPressed(ALARM_BUTTON)) && (!displayCountdown))
удалить кнопкуPress (ALARM_BUTTON) условие.
И, возможно, вы получите то, что вы хотите.