Pages: 1 [2] 3 4   Go Down
Author Topic: Set countdown time with Keypad?  (Read 5063 times)
0 Members and 1 Guest are viewing this topic.
Cleveland, TN
Offline Offline
Full Member
***
Karma: 2
Posts: 207
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your setuppass is true, then you can enter numbers and accept any number of digits. That way when you press the '#' while setuppass is true but setup is false, then you can handle the time anyway you want. If they have only entered 2 digits, treat it as seconds etc...

if ((setuppass == true) && (setup == false))
{


}

And then to handle everything once your setup is done:

If (setup == true) //you don't have to include the setuppass boolean in this since it must be true before you can ever set you setup to true.
{


}

I would put everything inside the if(key) loop.

I used only 1 switch case in my loop. I handle any checks for boolean in the sub functions. I do have a setup as well in order to assign the device an ID. It doesn't set time but it functions sort of the same.

The only thing I check in my switch case is to see if I have exceed the number of digits. But I always require 4 so this works for me.

Code:

switch(key)
{
  case '#':
    if(entryindex == 4)    //This is the count of how many digits I have entered if it equals 4 then move on, if not then ignore it. Since you
                                    //may be accepting less than four you will need to do this a little different and include a look at your booleans here
                                    //if (setuppass == true)    //I have entered the passcode for setup time
                                    //{
                                    //   if  (entryindex >0)      //Make sure at least one number has been pressed.
                                    //   }
                                    //  setuptime();
                                    //   }
                                    //}
                                    //else         //in every other case you are going to look for 4 digits before you move on
                                    //{
                                    //  if (entryindex == 4)
                                    //   {
                                    //    checkpassword();
                                    //   }   
                                    //}
    {
      checkpassword();   //Call to a subfunction that checks the password against all passwords, I have three.
    {
    break;                     //Don't forget the breaks. Switch will not work correctly without these.
  case '*':
    break;                 //I don't use this key so I ignore it. If you are not going to use your letters, you will have to do the same for those.
                                 //If you are going to use them aas part of the password it will get more complicated since you will need to ignore
                                 //them when you are entering time
   default:
     if(entryindex + 1 == 5)
     {
     //I flash my RGB led red here to let them know they have tried to enter more than 4 digits
     }
     else
     {
     appendentry(key)     //I pass the key presssed to a function that adds it to the array. You could do it here since it is simple code
     //entry[entryindex] = key;
     //entryindex ++;
     //entry[entryindex] = '/0';       //Adds string terminator at the end of the string each time a new char is added.

     }




That check password function is where everything happens.


« Last Edit: April 04, 2012, 12:41:55 pm by Sacman » Logged

Luck,

Wade

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I do not really understand what the setuppass function is?
This is the part I do not really understand:
Quote
Add a boolean variable that is false when your turn it on. Once you have set your time you turn it to true. Also add a second boolean that you can set if the code entered matches the setup password. Then you can check those in your loop. If setuppass == true then the next buttons you press will be for setting time. Once your time is completely set, set your setup to true.

I'm a bit confused that you have a setup and a setuppass function:
Quote
if ((setuppass == true) && (setup == false))

Thanks again for the help smiley-wink
« Last Edit: April 04, 2012, 01:08:16 pm by TiboJ » Logged

Cleveland, TN
Offline Offline
Full Member
***
Karma: 2
Posts: 207
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

setuppass and setup are boolean variables.

When you first start up these are both false. Until you enter the setup password, nothing else should work.

So you enter 4 numbers and hit '#'.

This sends control to the checkpassword() function that looks like this:

Code:
void checkpassword()
{
char tempentry;
char temppass;

 for(int i = 0;i <5; i++)
 {
  tempentry = entry[i];                         //These next two lines just give you something that is comparable. The first one takes each of your
                                                           //entered digits.
  temppass = setuppassword[i];            //This one takes each digit of your password used for setup.
  if ((tempentry ==  '/0') && (temppass == '/0')     //If you have reached the end of your two strings this is what you should get
  {
   setuppass = true;            //Since your entered code = setuppass, set your setuppass boolean to true.
                                        //Now that setuppass = true, the next time through your loop it will behave differently
  if (tempentry != temppass)      //If at any time your entered code does not equal your setuppassword durng the 5 iterations through the
                                                //for loop
  {
   entryindex = 0;                      //Reset your entryindex so that it effectively clears your entry.
   entry[entryindex] = '/0';         //Always add the null
   //Since you have a display, use this opportunity to print something to the display saying that the two did not match.
  }
  }

 }
}


This code will not handle multiple passwords. It will only look for the setuppassword. What you will need to do is add more levels to it to look for the arm/disarm codes if setup = true. You will set setup to true after you have entered your time and pressed the '#' again. Once setup is true, when you check your password, you will want to ignore this check and check instead for an arm password. You can use a boolean that tells you if it is armed. When it is false, check for an arming password. If it is true check for the disarm passoword. The code above will work for all three you just have to reconfigure it for each. 
Logged

Luck,

Wade

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for explaining.
Here is my code at this time:

Code:
#include <LiquidCrystal.h>
#include <ShiftLCD.h>       // Include Library's
#include <Keypad.h>

#define SETUP 0
#define SETTIME 1  //  case for setting time
#define ON 2       // case for arming bomb
#define ARMED 3    // case for countdown
#define DISARMED 4  // case for stopping countdown
#define DETONATED 5  // case for finished countdown

int bombState=0; // 0 = Setup, 1 = Set time, 2 = On, 3 = Armed ,4 = Disarmed, 5 = Detonated


int time;
int setTime;

const byte ROWS = 4; // Keypad has 4 rows
const byte COLS = 4; // Keypad has 4 columns
char keys[ROWS][COLS] = {
  {
    '1','2','3','A'  }
  ,
  {
    '4','5','6','B'  }
  ,         // define which character is on a button
  {
    '7','8','9','C'  }
  ,
  {
    '*','0','#','D'  }
};
byte rowPins[ROWS] = {
  5,6,7,8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  9,10,11,12}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );    

ShiftLCD lcd(2, 4, 3); // pins connected to LCD

char clearButton[1] = {
  '*'};
char EnterButton[1] = {
  '#'};
char SetupPW[4] = {
  '1','2','3','4'};
char TimeCode[4];
char ArmCode[4] = {
  '7','8','9','1'};   // password to arm the bomb
char inputArray[4];   // array to gather user keypad presses
char inputSetupArray[4];
int i = 0; // store keypresses here
int x = 0; // store the keypresses here



void setup()
{
  lcd.begin(16,2); // open the LCD
  // bootup screen
  lcd.print("AIRSOFT BOMB V1"); // print some text
  lcd.setCursor(4,1);
  lcd.print("BY TIBO");  
  delay(2500); // display text for 2500ms
  lcd.clear(); // clear display
}
void loop()
{

  // cases
  switch(bombState) {

    ////////////// SET COUNTDOWN TIME//////////////////////////  

  case SETUP:
    {
      SetupCode();
    }
    break;    



  case SETTIME: // set the countdown time
    {

    }
    break;


    ///////////////////////////////////////////////////////////
    //////////////////////ENTER ARM CODE/////////////////////////
  case ON: // enter the right code to arm the bomb
    {

    }
    break;

    ////////////////////////////////////////////////////////////////////////

  case ARMED:
    {

    }
    break;


  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////getArmCode////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean getArmCode()
{

}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////SetupCode//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean SetupCode() {

  
  char key = keypad.getKey();
  //if a key is pressed
  if(key)
  {
    inputSetupArray[x] = key; //store entry into array
    x++;
    lcd.setCursor(0,1); // set cursor at column 0 and row 1
    lcd.print(key); // print keypad character entry to lcd
    if (x == 4 && EnterButton['#']) // if 4 presses on the keypad have been made
    {
      if (inputSetupArray[0] == SetupPW[0] && // if first character pressed on keypad = first character in password for arming bomb
      inputSetupArray[1] == SetupPW[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
      inputSetupArray[2] == SetupPW[2] && // and if third character pressed on keypad = third character in password for arming bomb
      inputSetupArray[3] == SetupPW[3]) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb

      {
       checkpassword();
      }
    }
  }
}

//////////////////////////////////////////////////////

void checkpassword()
{
  char tempentry;
  char temppass;
  int entryindex;

  for(int x = 0;x <5; x++)
  {
    tempentry = inputSetupArray[x];                         //These next two lines just give you something that is comparable. The first one takes each of your        
    //entered digits.
    temppass = SetupPW[x];      //This one takes each digit of your password used for setup.
  }
  if ((tempentry ==  '/0') && (temppass == '/0'))  //If you have reached the end of your two strings this is what you should get
  {
      SetupCode() = true;         //Since your entered code = setuppass, set your setuppass boolean to true.
  }                                //Now that setuppass = true, the next time through your loop it will behave differently
  if (tempentry != temppass)      //If at any time your entered code does not equal your setuppassword durng the 5 iterations through the
    //for loop
  {
    entryindex = 0;                      //Reset your entryindex so that it effectively clears your entry.
    inputSetupArray[entryindex] = '/0';         //Always add the null
    //Since you have a display, use this opportunity to print something to the display saying that the two did not match.
  }
}


Am I doing it right?

I get this error with the SetupCode() = true; :
lvalue required as left operand of assignment
« Last Edit: April 05, 2012, 04:24:06 am by TiboJ » Logged

Cleveland, TN
Offline Offline
Full Member
***
Karma: 2
Posts: 207
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've only got a minute but a couple of things. You have done this differently than I did but in theory most of it will work.

First where you start your setupcode function you call it a boolean function. The way you are using it, you want it to be a void. You are not returning a value so instead of:

boolean setupcode() {

you want

void setupcode(){

Second, you have already verified your password in the setupcode function. Again doing it a different way but it should work fine. So if it is true, you don't need to call checkpassword. In fact the way you have handled it, you can delete the whole checkpassword function.

The reason you get that error is that you are trying to set a function to true. You can't do that. Your setupcode is a function not a boolean variable. I can see where that got confusing over my last few posts. When I said declare a boolean called setupcode, I meant at the top of you code in the declarations section you should declare it as such:

boolean setupcode;

To be used later in the program. The way you are managing your code you don't need this.

Don't forget to handle a situation where they have entered the wrong password. The way your code is written right now you can't do this. Where you check for 4 digits and the '#' key, you will need to nest those two if loops. First check that the '#' key is pressed, then check if you have 4 digits. Then you inner loop can handle any situation where either you don't have 4 digits or your matching the codes returns false.

Do these couple of things and here you have called checkpassword. Just print something to the LCD to show you it worked. You are on a different track than I was but it should work.
Logged

Luck,

Wade

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for clearing it up man! I really appreciate your help!
Maybe I'm doing it the other way as you do, but your explanation of it helps me a lot.

While I was stuck with the 'true' error, I tried to code it on my way.
Everything works fine, unless the countdown:

So first off all, I need to enter the setup password, it that is correct, then I need to set the countdown time.
If I've set the countdown time(for example 120(seconds)), and I press '#' on the keypad, then the time is set and I need to enter the arm code.
If I've entered the arm code, then the countdown starts, but with problems: it wont countdown for the countdown value I set before. It just countdown from the number of keys I've pressed. So for 120 it will countdown from 3 to 0, because 120 has 3 numbers. For 1200 it will countdown from 4 to 0, because 1200 has 4 numbers, from 12 it will countdown from 2 to 0,...and so forth.

I think there is something wrong in my code, but I don't see what. Maybe you can see what's wrong?
Probably it is wrong in the arrays(TimeValue or inputTimeArray), the Countdown function or the SetTimeCode.
Again, thanks for helping me. smiley-wink

Code:
#include <LiquidCrystal.h>
#include <ShiftLCD.h>       // Include Library's
#include <Keypad.h>

#define SETUP 0
#define SETTIME 1  //  case for setting time
#define ARMCODE 2       // case for arming bomb
#define ARMED 3    // case for countdown
#define DISARMED 4  // case for stopping countdown
#define DETONATED 5  // case for finished countdown

int bombState=0; // 0 = Setup, 1 = Set time, 2 = Arm Code, 3 = Armed ,4 = Disarmed, 5 = Detonated


int time;
int setTime;

const byte ROWS = 4; // Keypad has 4 rows
const byte COLS = 4; // Keypad has 4 columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},         // define which character is on a button
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5,6,7,8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9,10,11,12}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );   

ShiftLCD lcd(2, 4, 3); // pins connected to LCD

char clearButton[1] = {'*'};
char EnterButton[1] = {'#'};
char SetupPW[] = {'1','2','3','4'};
char TimeValue[4];
char ArmCode[4] = {'7','8','9','1'};   // password to arm the bomb
char inputTimeArray[4];   // array to gather user keypad presses
char inputSetupArray[4];
char inputArmArray[4];
int i = 0; // store keypresses here
int x = 0; // store the keypresses here
int a = 0;



void setup()
{
  lcd.begin(16,2); // open the LCD
  // bootup screen
  lcd.print("AIRSOFT BOMB V1"); // print some text
  lcd.setCursor(4,1);
  lcd.print("BY TIBO"); 
  delay(2500); // display text for 2500ms
  lcd.clear(); // clear display
}
void loop()
{
 
  // cases
  switch(bombState) {
   
////////////// SET COUNTDOWN TIME//////////////////////////   

    case SETUP:
    {
      SetupCode();
    }
break;   
     
     
     
    case SETTIME: // set the countdown time
    {
      SetTimeCode();
    }
        break;
   
 
    case ARMCODE: // enter the right code to arm the bomb
  {
    TypeArmCode();
  }
break;


case ARMED:
{
Countdown();
}
break;


  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////SetupCode//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean SetupCode() {

  lcd.setCursor(0,0);
  lcd.print("Enter Password:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{
  inputSetupArray[x] = key; //store entry into array
  x++;
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
if (x == 4) // if 4 presses on the keypad have been made
 {
   if (inputSetupArray[0] == SetupPW[0] && // if first character pressed on keypad = first character in password for arming bomb
inputSetupArray[1] == SetupPW[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
inputSetupArray[2] == SetupPW[2] && // and if third character pressed on keypad = third character in password for arming bomb
inputSetupArray[3] == SetupPW[3] ) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb

{
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Pass Correct"); // display some text
  delay(1000); // display text for 1000ms
  lcd.clear();
  bombState = SETTIME; // switch to ARMED case
 
}
else {
    lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Pass Incorrect"); // display some text
  delay(1000); // display text for 1000ms
  x = 0;                      //Reset your entryindex so that it effectively clears your entry.
  inputSetupArray[x] = '/0';         //Always add the null
  lcd.clear();
 
}

  }
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////SetTimeCode//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean SetTimeCode() {
 

lcd.setCursor(0,0);
lcd.print("Enter Time:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{

  inputTimeArray[i] = key; //store entry into array
 i++;
 inputTimeArray[i] = '/0';
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
 
 if (key == '#') {
 inputTimeArray[i] = TimeValue[i];
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Time Set"); // display some text
  delay(1000); // display text for 1000ms
  bombState = ARMCODE; // switch to ARMED case
  lcd.clear();
 }
}
}


 
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////TypeArmCode////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean TypeArmCode() {
 
    lcd.setCursor(0,0);
  lcd.print("Enter ArmCode:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{
  inputArmArray[a] = key; //store entry into array
  a++;
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
if (a == 4) // if 4 presses on the keypad have been made
 {
   if (inputArmArray[0] == ArmCode[0] && // if first character pressed on keypad = first character in password for arming bomb
inputArmArray[1] == ArmCode[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
inputArmArray[2] == ArmCode[2] && // and if third character pressed on keypad = third character in password for arming bomb
inputArmArray[3] == ArmCode[3] ) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb

{
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Bomb Armed!"); // display some text
  delay(1000); // display text for 1000ms
  lcd.clear();
  bombState = ARMED; // switch to ARMED case
}

else {
    lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Code Incorrect"); // display some text
  delay(1000); // display text for 1000ms
  a = 0;                      //Reset your entryindex so that it effectively clears your entry.
  inputSetupArray[a] = '/0';         //Always add the null
  lcd.clear();
 
}

  }
}
}
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////Countdown/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean Countdown() {
 
  while(i > 0) {
lcd.setCursor(0,0);
   lcd.print("Time remaining:");
   i -= 1;
   delay(1000);
   lcd.clear();
   lcd.setCursor(7,1);
   lcd.print(i);
  if (i == 0) {
    lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Bomb Exploded");
  }
}
}



« Last Edit: April 05, 2012, 08:03:56 am by TiboJ » Logged

Cleveland, TN
Offline Offline
Full Member
***
Karma: 2
Posts: 207
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay. So sounds like you are really close.

First you are storing your time data as a char array. This might be how you need to use it for printing to the LCD but you need this data in int form to do math on it. Since you are using unique arrays for each of your inputs, you don't need your timevalue[4] at all. It doesn't serve any purpose.

Also, in your code, you are setting it backwards anyway. You are actually setting your inputtimearray  = to your timevalue array which is declared as '0','0','0','0'. This means that no matter what you entered, you were setting it back to all 0.

So what you need now is a way to increment the time you entered. It looks like you assume that you are not forcing a colon so if you enter one or two numbers, you get only seconds, if you enter 3 or 4 numbers, you get minutes and seconds. This will work you just have to account for it.

So first you have to convert your char to ints. Then you have to put them together in an order that makes sense.

First, in your declarations, you need to declare two integers:
Code:
int timemin;
int timesec;


Then in you timesetcode function after you have pressed the '#' key:

 
Code:
timesec = ((inputtimecode[0] - '0') * 10) + (inputtimecode[1] - '0');    //This places the first digit you entered into the tens spot on the     
                                                                                                     //seconds and adds to it the second digit.  The -'0' is an easy way to
                                                                                                     // convert a char number into an integer.
 timemin = ((inputtimecode[2] - '0') * 10) + (inputtimecode[3] - '0');  // this does the same for the minutes.

//It doesn't matter how many digits you press since if the value is 0 it will give you 0.


So now the next bit is to decrement those. Decrement the seconds first. If seconds = 0, reset seconds to 59 unless minutes = 0. If minutes does not = 0 then you will decrement minutes at that point:

Although Delay(1000) is not the best way to countdown, since your code doesn't need to do anything else, it will probably work.

So in your countdown() function:

Code:

delay(1000)

If (timesec == 0) && (timemin == 0)
{
// Bomb blew up set the appropriate mode. The next time you hit your loop it will see that instead of countdown mode.
}
If (timesec > 0)
{
 timesec -= 1;
}
else if (timesec == 0) && (timemin > 0)
{
timesec = 59;
timemin -=1;
}

//this will decrement your time appropriately. Not the challenge is that you can't write those values back to the display unless I am wrong.
//I have never used the 16x2 but I assume you must write the values in char format so you use that timevalue you declared and I told you
//was useless. Leave it alone, we can use it here although I think you might have to make it bigger. Make it timevalue[10] just to have
//some room to move. You are not critical on RAM so it should be fine.

//First lets convert the integers back to a char. This assumes that you cannot print the integers directly. I really don't know if that is the case.

sprintf(timevalue, "%2d:%02d, timemin, timesec);
lcd.setcursor(7,1);
lcd.print(timevalue);

//If you can print the integers directly then you don't need the timevalue[10] or the sprintf statement. Just print them out in the format
//that you want.




This is interesting to watch. Everything you have done is completely different from the way I have done it yet it still seems to function like it should.

Just remember that people will do weird things and enter things that don't make any sense. You always need to idiot proof. Think of every way that they could break your code. What happens if I press 5 keys for my password. Does it ignore the 5th? What if I press the '*' key? What happens if I press one of the letters while I am entering time. It will work but give you a really messed up value. You have to trap these kinds of errors and make sure you have handled them in code. The worst thing is to have this thing all boxed up and have to remove the battery or do a hard reset because someone did something that you should have accounted for.


Logged

Luck,

Wade

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you!!!! This helped me very much!

It counts down now, but there is a little bug:

If I want to countdown from 20 seconds, then I enter '2000' and press enter.
That all works fine, until it eaches 9 seconds, then it shows 90>80>70>60>50>40>30>20>10>00 instead of 9>8>7>6>5>4>3>2>1>0.

If I want to countdown from 20 seconds, and I enter '20', then it counts down from 20 to 00, and the minutes are -130.

The bug happens not only with number 20, but also with other numbers.

Here is the code:

Code:
#include <LiquidCrystal.h>
#include <ShiftLCD.h>       // Include Library's
#include <Keypad.h>

#define SETUP 0
#define SETTIME 1  //  case for setting time
#define ARMCODE 2       // case for arming bomb
#define ARMED 3    // case for countdown
#define DISARMED 4  // case for stopping countdown
#define DETONATED 5  // case for finished countdown

int bombState=0; // 0 = Setup, 1 = Set time, 2 = Arm Code, 3 = Armed ,4 = Disarmed, 5 = Detonated


int time;
int setTime;

const byte ROWS = 4; // Keypad has 4 rows
const byte COLS = 4; // Keypad has 4 columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},         // define which character is on a button
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5,6,7,8}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9,10,11,12}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );    

ShiftLCD lcd(2, 4, 3); // pins connected to LCD

char clearButton[1] = {'*'};
char EnterButton[1] = {'#'};
char SetupPW[] = {'1','2','3','4'};
char ArmCode[4] = {'7','8','9','1'};   // password to arm the bomb
char inputTimeArray[4];   // array to gather user keypad presses
char inputSetupArray[4];
char inputArmArray[4];
int i = 0; // store keypresses here
int x = 0; // store the keypresses here
int a = 0;



void setup()
{
  lcd.begin(16,2); // open the LCD
  // bootup screen
  lcd.print("AIRSOFT BOMB V1"); // print some text
  lcd.setCursor(4,1);
  lcd.print("BY TIBO");  
  delay(2500); // display text for 2500ms
  lcd.clear(); // clear display
}
void loop()
{
  
  // cases
  switch(bombState) {
    


    case SETUP:
    {
      SetupCode();
    }
break;    
      
      
      
    case SETTIME: // set the countdown time
    {
      SetTimeCode();
    }
        break;
    
  
    case ARMCODE: // enter the right code to arm the bomb
  {
    TypeArmCode();
  }
break;


case ARMED:
{
Countdown();
}
break;


  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////SetupCode//////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean SetupCode() {

  lcd.setCursor(0,0);
  lcd.print("Enter Password:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{
  inputSetupArray[x] = key; //store entry into array
  x++;
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
if (x == 4) // if 4 presses on the keypad have been made
 {
   if (inputSetupArray[0] == SetupPW[0] && // if first character pressed on keypad = first character in password for arming bomb
inputSetupArray[1] == SetupPW[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
inputSetupArray[2] == SetupPW[2] && // and if third character pressed on keypad = third character in password for arming bomb
inputSetupArray[3] == SetupPW[3] ) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb

{
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Pass Correct"); // display some text
  delay(1000); // display text for 1000ms
  lcd.clear();
  bombState = SETTIME; // switch to ARMED case
  
}
else {
    lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Pass Incorrect"); // display some text
  delay(1000); // display text for 1000ms
  x = 0;                      //Reset your entryindex so that it effectively clears your entry.
  inputSetupArray[x] = '/0';         //Always add the null
  lcd.clear();
  
}

  }
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////SetTimeCode//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean SetTimeCode() {
  

lcd.setCursor(0,0);
lcd.print("Enter Time:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{

  inputTimeArray[i] = key; //store entry into array
 i++;
 inputTimeArray[i] = '/0';
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
  
 if (key == '#') {
 inputTimeArray[i] = TimeValue[i];
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Time Set"); // display some text
  delay(1000); // display text for 1000ms
  bombState = ARMCODE; // switch to ARMED case
  lcd.clear();
 }
}
}


  
  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////TypeArmCode////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean TypeArmCode() {
  
    lcd.setCursor(0,0);
  lcd.print("Enter ArmCode:");
char key = keypad.getKey();
//if a key is pressed
if(key)
{
  inputArmArray[a] = key; //store entry into array
  a++;
  lcd.setCursor(0,1); // set cursor at column 0 and row 1
lcd.print(key); // print keypad character entry to lcd
if (a == 4) // if 4 presses on the keypad have been made
 {
   if (inputArmArray[0] == ArmCode[0] && // if first character pressed on keypad = first character in password for arming bomb
inputArmArray[1] == ArmCode[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
inputArmArray[2] == ArmCode[2] && // and if third character pressed on keypad = third character in password for arming bomb
inputArmArray[3] == ArmCode[3] ) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb

{
  lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Bomb Armed!"); // display some text
  delay(1000); // display text for 1000ms
  lcd.clear();
  bombState = ARMED; // switch to ARMED case
}

else {
    lcd.clear(); // clear display
  lcd.setCursor(0,0);
  lcd.print("Code Incorrect"); // display some text
  delay(1000); // display text for 1000ms
  a = 0;                      //Reset your entryindex so that it effectively clears your entry.
  inputSetupArray[a] = '/0';         //Always add the null
  lcd.clear();
  
}

  }
}
}
  
  
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////Countdown/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

boolean Countdown() {
  
  while(i > 0) {
lcd.setCursor(0,0);
   lcd.print("Time remaining:");
   i -= 1;
   delay(1000);
   lcd.clear();
   lcd.setCursor(7,1);
   lcd.print(i);
  if (i == 0) {
    lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Bomb Exploded");
  }
}
}



Do you know why it shows the numbers wrong?
I'll also take a look at it now.

This is the to-do-list:

- Fix the bug
-Change boolean to void where possible
-Make disarm function
-Make it idiot proof

Quote
This is interesting to watch. Everything you have done is completely different from the way I have done it yet it still seems to function like it should.
Yes it is, that's something of the cool things of Arduino.

btw: it can print the integers directly.
« Last Edit: April 06, 2012, 10:07:47 am by TiboJ » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That all works fine, until it eaches 9 seconds, then it shows 90>80>70>60>50>40>30>20>10>00 instead of 9>8>7>6>5>4>3>2>1>0.
It looks like your lcd.clear is not working.

Code:
inputTimeArray[i] = '/0';
That is not a NULL. For a NULL, the slash goes the other way.

Code:
if (key == '#') {
 inputTimeArray[i] = TimeValue[i];
Where did TimeValue get a value?

Figuring out the minutes issue is not something I want to do, after seeing that the time to count down is stored in i. One letter variables are generally used only for loop indices. Global variables should never have one letter names.

It appears as though i is used for many purposes, so it really shouldn't be global. Another variable with a meaningful name SHOULD be added to hold the time to count down.

I don't see where you characters entered to a time in minutes and seconds, anyway.

Removing the superfluous braces and blank lines from your code, and using Tools + Auto Format to neaten it up would make the code a lot easier to read, too.

When a function has a return type of other than void, there is supposed to be a return statement to actually return a value. None of your functions return anything.
Logged

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It looks like your lcd.clear is not working.

Adding lcd.clear fixed the bug, thank you!

Quote
Where did TimeValue get a value?

That's from the old code, it's removed now.

For the rest, thank you for the tips smiley-wink
Logged

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For some reason I can't enter the TypeDisarmCode function.
If I press # nothing happens, it just keeps counting down.

Here is the code:

Code:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////Countdown/////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Countdown() {

  delay(1000);
 
  char key = keypad.getKey();
  //if a key is pressed
  if (key == '#') {
    TypeDisarmCode();
  }

  if ((timesec == 0) && (timemin == 0))
  {
    bombState = DETONATED;
  }
  if (timesec > 0)
  {
    timesec -= 1;
    lcd.clear();
  }
  else if ((timesec == 0) && (timemin > 0))
  {
    timesec = 59;
    timemin -=1;
  }
  lcd.setCursor(0,0);
  lcd.print("Time Remaining:");
  lcd.setCursor(3,1);
  lcd.print(timesec);
  lcd.setCursor(0,1);
  lcd.print(timemin);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////TypeDisarmCode////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void TypeDisarmCode() {

  char key = keypad.getKey();
  //if a key is pressed
  if(key)
  {

    inputTimeArray[b] = key; //store entry into array
    b++;
    inputTimeArray[b] = '\0';
    lcd.setCursor(6,1); // set cursor at column 0 and row 1
    lcd.print(key); // print keypad character entry to lcd

    if (inputDisarmArray[0] == DisarmCode[0] && // if first character pressed on keypad = first character in password for arming bomb
    inputDisarmArray[1] == DisarmCode[1] &&  // and if second character pressed on keypad = second character in password for arming bomb
    inputDisarmArray[2] == DisarmCode[2] && // and if third character pressed on keypad = third character in password for arming bomb
    inputDisarmArray[3] == DisarmCode[3] ) // and if fourth charactet pressed on keypad = fourth character in password for arming bomb
    {
      lcd.clear(); // clear display
      lcd.setCursor(0,0);
      lcd.print("Bomb Disarmed!"); // display some text
      delay(1000); // display text for 1000ms
      lcd.clear();
    }
    //It doesn't matter how many digits you press since if the value is 0 it will give you 0.
  }
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If I press # nothing happens, it just keeps counting down.
If you press the # key, the function gets called. It is not a blocking function, so it doesn't wait for a key press. If no key is being pressed when it looks, it simply returns.
Logged

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay, how can I make it work?

Logged

Cleveland, TN
Offline Offline
Full Member
***
Karma: 2
Posts: 207
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does it print Bomb Disarmed to the screen for a flash and then go back to counting?

In your disarm function you need to change the bomb state. You status is still in Armed so when it goes through the loop again it goes back to the armed function.

If you want to be able to re-arm it you will need to add another case in your void loop to handle that.




Logged

Luck,

Wade

Belgium
Offline Offline
Full Member
***
Karma: 2
Posts: 211
I love Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If the # button is pressed during the countdown, then the user is able to enter the disarm code.
If the code is right, then the countdown stops and the lcd prints 'bomb disarmed".
If the code is wrong, then the lcd prints 'code wrong' and it just keeps counting down.
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: