0

I'm pretty new to C++ and Arduino. I purchased a gadget called a Defusable Alarm Clock. I'm looking to modify the code so that when it's powered up it will automatically start the countdown. Right now, you have to manually push the red button (DET) in order for the countdown to start. Is there a way I can bypass the red button and have it countdown automatically?

Here's the default code:

https://gist.github.com/anonymous/a5acc051ae6157e6e7f1

Thanks for any help!

user3258383
  • 29
  • 3
  • 8

2 Answers2

2

Looking at the code you can identify 4 different input buttons:

pinMode(HOUR_BUTTON_PIN, INPUT);     
pinMode(MIN_BUTTON_PIN, INPUT);     
pinMode(ALARM_BUTTON_PIN, INPUT);     
pinMode(DET_BUTTON_PIN, INPUT);     

Obviously the red button is either ALARM or or DET button.

Let's look when the input for each button is read. The code that is responsible for the logic of this toy does not use digitalRead directly but rather through the buttonPressed, buttonPressedNew and buttonHeld functions. Each function receives a number that represents the button and returns true if the button is in the state suggested by the function name. The button numbers are defined at the beginning and mapped to the button pins through the buttonPins array.

#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};

Back to our problem, let's look that the locations where DET_BUTTON and ALARM_BUTTON are being queried. I will focus on setup and loop only as these are the most likely places where where the "press red button to start" logic would go.

 if (buttonPressed(DET_BUTTON)) {
    // enable silent mode for testing
    beep(3500, 50);
    silent = true;
    while (buttonPressed(DET_BUTTON)); // wait for release
  }

This is for power up testing of the buzzer - you hold the button while reseting and as long as you continue holding it, there will be a beep.

// 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);
  }

This is related to LED indicators. If the alarm button is pressed and countdown is not being displayed on the screen some LEDs will turn on otherwise they will be off. Also displayAlarmTime is a flag that indicates that alarm time should be displayed on the screen.

  if (!buttonPressed(ALARM_BUTTON)) {
    if (countdownSeconds < 5940) {
      countdownSeconds += 60;
      countdownDuration += 60;
    }

This code is inside if (buttonPressedNew(HOUR_BUTTON) || buttonHeld(HOUR_BUTTON, 150)) blkock so not interesting. Similar verdict for the next snippet which I did not bother copying.

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;
  }

First part related to alarm. It is a little puzzling to me since there are only three alarm modes and the mode with the highest number is actually ALARM_DET so the line alarmMode > ALARM_DET must never be true.

Anyway it does not look like our candidate.

Now regarding the second part which looks more promising. The flag displayZeros I assume is indicating that zeros are displayed on the display which means you did not defuse on time. The isDefused flag is indicating that you did defuse the bomb. Together, if ((displayZeros) || (isDefused)) is indicating that you are at the end of a "play" ( you either won or lost), thus the action that should be taken is to reset the display.

The flag detPressed is used to remember that DET button was pressed. It will be reset lated in the code that checks that DET button is not pressed, so as long as the button is pressed it will stay ture.

The variable countdownSeconds holds the number os seconds left for end of countdown (obviously). And then the code also tells the display logic to display this count down on the screen.

  if (!buttonPressed(DET_BUTTON)) {
    if (detPressed) {
      detPressed = false;
      defaultCountdownSeconds = countdownSeconds;
      writeEEPROM();
      countdown();
    }
  }

This is the last part. The inner logic will happen when you release the DET button. It will set the defaultCountDown seconds to the current countdown seconds, I guess this is because you can change the countdown while the button is pressed, write something (the default countdown?) to eeprom and ... initiate the countdown!

Now, I hope, you have enough information to figure out yourself how to change the program your desired way.

Artium
  • 5,147
  • 8
  • 39
  • 60
0

The 20 second answer:

in the line:

 if ((buttonPressed(ALARM_BUTTON)) && (!displayCountdown)) 

remove the buttonPressed(ALARM_BUTTON) condition.

And maybe you will get what you want.

Aumnayan
  • 671
  • 3
  • 12