First Project; Bomb Prop

Hi Guys,

This is my first post to the forum, I'm RanSacked and I've just started my journey with Arduino programming. I've read through some programming tutorials but I've only just had a chance to build something as my Arduino has only just arrived.

I've got a couple of quick questions for my first project.

I'm wanting to create a prop bomb for an escape room type scenario where a group has to defuse a bomb before escaping (just to add pressure really) I've found a sketch that seems to fit closest to what I want it to do but there are a few things I'd like to change about it. On the sketch I've found, you enter the code first and then it starts timing down. I'd like it to start counting down as soon as a motion switch is activated (when the lid is opened) and for the password to be pre programmed into it.

My question is a two-parter;

A: For the motion switch, would I put the code for that somewhere in void setup or would it need to be part of the loop? Also, is there a way to disable to motion switch after it has activated the countdown (as I don't want it to keep starting the timer over and over)

B: To store the password into the sketch would I need to use a string variable for the password and the temp password being entered and would that work with the sketch below?

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#define pound 14

Tone tone1;

int Scount = 12; // count seconds
int Mcount = 10; // count minutes
int Hcount = 0; // count hours
int DefuseTimer = 0; // set timer to 0

long secMillis = 0; // store last time for second add
long interval = 1000; // interval for seconds

char password[4]; // number of characters in our password
int currentLength = 0; //defines which number we are currently writing
int i = 0; 
char entered[4];

int ledPin = 4; //red led
int ledPin2 = 3; //yellow led
int ledPin3 = 2; //green led

LiquidCrystal lcd(7,8,10,11,12,13); // the pins we use on the LCD

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {5, A5, A4, A2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A1, A0, A3}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


void setup(){
  pinMode(ledPin, OUTPUT); // sets the digital pin as output
  pinMode(ledPin2, OUTPUT); // sets the digital pin as output
  pinMode(ledPin3, OUTPUT); // sets the digital pin as output
  tone1.begin(9);
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter Code: ");
  while (currentLength < 4)
  {
    lcd.setCursor(currentLength + 6, 1);
    lcd.cursor();
    char key = keypad.getKey();
    key == NO_KEY;
    if (key != NO_KEY)
    {
      if ((key != '*')&&(key != '#'))
      { 
      lcd.print(key);
      password[currentLength] = key;
      currentLength++;
      tone1.play(NOTE_C6, 200);
      }
    }
  }

  if (currentLength == 4)
  {
    delay(500);
    lcd.noCursor();
    lcd.clear();
    lcd.home();
    lcd.print("You've Entered: ");
    lcd.setCursor(6,1);
    lcd.print(password[0]);
    lcd.print(password[1]);
    lcd.print(password[2]);
    lcd.print(password[3]);

    tone1.play(NOTE_E6, 200);
    delay(3000);
    lcd.clear();
    currentLength = 0;
  }
}

void loop()
{
  timer();
  char key2 = keypad.getKey(); // get the key
  
  if (key2 == '*')
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Code: ");
      
      while (currentLength < 4)
        {
          
          timer();
          
          char key2 = keypad.getKey(); 
          if (key2 == '#')
            {
              currentLength = 0;
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("Code: ");
            }
          else                  
          if (key2 != NO_KEY)    
            {
              
              lcd.setCursor(currentLength + 7, 0);
              lcd.cursor();
              
              lcd.print(key2);
              entered[currentLength] = key2;
              currentLength++;
              tone1.play(NOTE_C6, 200);
              delay(100);
              lcd.noCursor();
              lcd.setCursor(currentLength + 6, 0);
              lcd.print("*");
              lcd.setCursor(currentLength + 7, 0);
              lcd.cursor();
            }
        }

      if (currentLength == 4) 
        {
          if (entered[0] == password[0] && entered[1] == password[1] && entered[2] == password[2] && entered[3] == password[3])
            {
              lcd.noCursor();
              lcd.clear();
              lcd.home();
              lcd.print("Bomb Defused");
              currentLength = 0;
              digitalWrite(ledPin3, HIGH);
              delay(2500);
              lcd.setCursor(0,1);
              lcd.print("Reset the Bomb");
              delay(1000000);
            }
      else
        {
          lcd.noCursor();
          lcd.clear();
          lcd.home();
          lcd.print("Wrong Password!");
    
          if (Hcount > 0)
            {
              Hcount = Hcount - 1;
            }
    
          if (Mcount > 0)
            {
              Mcount = Mcount - 59;
            }
          if (Scount > 0)
            {
              Scount = Scount - 59;
            }
        delay(1500);
        currentLength = 0;
  
        }
      }  
    }
}

void timer()
{
  Serial.print(Scount);
  Serial.println();
  
  if (Hcount <= 0)
  {
    if ( Mcount < 0 )
    {
      lcd.noCursor();
      lcd.clear();
      lcd.home();
      lcd.print("The Bomb Has ");
      lcd.setCursor (0,1);
      lcd.print("Exploded!");
      
      while (Mcount < 0) 
      {
        digitalWrite(ledPin, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin2, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin2, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin3, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin3, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100);
      }
    } 
  }

  lcd.setCursor (0,1); // sets cursor to 2nd line
  lcd.print ("Timer:");

  if (Hcount >= 10)
    {
      lcd.setCursor (7,1);
      lcd.print (Hcount);
    }
  if (Hcount < 10) 
    {
      lcd.setCursor (7,1);
      lcd.write ("0");
      lcd.setCursor (8,1);
      lcd.print (Hcount);
    }

  lcd.print (":");

  if (Mcount >= 10)
    {
      lcd.setCursor (10,1);
      lcd.print (Mcount);
    }
  if (Mcount < 10) 
    {
      lcd.setCursor (10,1);
      lcd.write ("0");
      lcd.setCursor (11,1);
      lcd.print (Mcount);
    }
    
  lcd.print (":");

  if (Scount >= 10) 
    {
      lcd.setCursor (13,1);
      lcd.print (Scount);
    }
  if (Scount < 10) 
    {
      lcd.setCursor (13,1);
      lcd.write ("0");
      lcd.setCursor (14,1);
      lcd.print (Scount);
    }

  if (Hcount <0) 
    {
      Hcount = 0; 
    }

  if (Mcount <0) 
    {
      Hcount --; 
      Mcount = 59; 
    }

  if (Scount <1) // if 60 do this operation
    {
      Mcount --; // add 1 to Mcount
      Scount = 59; // reset Scount
    }

  if (Scount > 0) // do this oper. 59 times
    {
      unsigned long currentMillis = millis();
  
      if(currentMillis - secMillis > interval) 
        {
          tone1.play(NOTE_G5, 200);
          secMillis = currentMillis;
          Scount --; // add 1 to Scount
          digitalWrite(ledPin2, HIGH); // sets the LED on
          delay(10); // waits for a second
          digitalWrite(ledPin2, LOW); // sets the LED off
          delay(10); // waits for a second
          //lcd.clear();
        }
    }
}

To me it seems that what I want from it is simpler than what this code is actually doing (whether that actually makes the coding simpler, I don't know), so I don't know if I can use this or if I'd have to start from scratch? Which is a bit daunting to me tbh.

Anyway, hope you guys can help. I've tried finding the answers myself but there is only so many hours you can spend trawling through tutorials and forums before you have to admit defeat and ask for help, haha.

Thanks again,
RanSacked

A: For the motion switch, would I put the code for that somewhere in void setup or would it need to be part of the loop? Also, is there a way to disable to motion switch after it has activated the countdown (as I don't want it to keep starting the timer over and over)

if you put that in the setup and wait there until "activated" then the loop executes and does not check it again, so no option to reset

this is an active wait though - so your arduino won't do much else. if you want to blink a light or do something else, then don't put that in the setup, it belongs to the loop() and just have a boolean variable that checks if it has been activated or not. Once activated, don't go start the timer again.

B: To store the password into the sketch would I need to use a string variable for the password and the temp password being entered and would that work with the sketch below?

don't use the String class; use just null ('\0') terminated char arrays, what is called a string with lower case 's' like const char secret[] = "1515"; and then use the standard C functions to deal with string comparisons (cf stdlib.h or string.h)

Thanks for your reply J-M-L!

Active wait is fine, it'll be in a box so nothing showing until it's opened so that's not an issue

J-M-L:
just have a boolean variable that checks if it has been activated or not. Once activated, don't go start the timer again.

Not entirely sure on how booleans work yet, I couldn't seen an example in the IDE. I'll have to do a google search.

J-M-L:
don't use the String class; use just null ('\0') terminated char arrays, what is called a string with lower case 's' like
Code: [Select]
const char secret[] = "1515";
and then use the standard C functions to deal with string comparisons

Ok, that seems easier. That means I can just use:

if (entered[0] == secret[0] && entered[1] == secret[1] && entered[2] == secret[2] && entered[3] == secret[3])

and that would refer to the constant?

Thanks again for your help,

RanSacked

that could work if you check character by character but if you put that in a null terminated string, then you can use the strings functions (cf stdlib.h and string.h) especially the [url=http://www.cplusplus.com/reference/cstring/strcmp/?kw=strcmp]strcmp()[/url] one

when it comes to boolean, this is just a type of variable that can be either true or false. you put a if statement in your loop that checks the value and if some conditions has happened, then you change the value. for example

const byte buttonPin = 8;
boolean activated = false; // at start we are not activated

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  if (!activated) { // the Boolean Operator ! is standard C and means "not" cf https://www.arduino.cc/en/reference/boolean
    // -----------------------------------------------
    // here do what you want to do when NOT activated
    // -----------------------------------------------

    // check if button is pressed for example (with INPUT_PULLUP, LOW means pressed)
    if (digitalRead(buttonPin) == LOW)  activated = true; // we become activated so won't come back here


  } else {
    // -------------------------------------------
    // here do what you want to do when activated
    // -------------------------------------------


  }

  // ---------------------------------------------------
  // here do what you want to do whether activated or not
  // ---------------------------------------------------

}

Ah! Ok, that makes sense now. I couldn't get my head around it earlier. Thanks so much for your help!

happy to help!