Timer program

Thanks AWOL
I removed the DEC and fixed the issue with the code not displaying what I typed in. : :smiley:

Quote

lcd.print(password[0]);

soul1974:
I am having problems getting the program to reset once the correct code is imputed and once the time limit has been reach.

...

this is the only forum that has bothered to help a noob.

For future reference, you get more help in general if you explain the problem better. Some posts I look at and I think "I haven't the faintest idea of what he wants" and I just move on.

I teased out of you that this is something to do with defusing a timer, and you have x seconds to do it, and so on. That helps people understand what you want to do, and what isn't working. You could have mentioned that in the first post.

Also try taking a bit of care. Your original post has this in it:

[font=Verdana][font=Verdana]

Now that isn't C code, try to look at what you are posting and see if it makes sense.

There is no shame in being a noob, we have all been there. But you can try to clearly explain the problem.

  1. when you type in the defuse code it does not reset ,it says reseting but continues to count down.
  2. when you type in the code and the screen changes part of the sentence stays behind e.g. 2:30omb
  3. when the bomb goes of it does not reset the unit automaticaly, when I pres the # key it restarts the timer.
  1. suggest that some of the "obscene" number of LCD controls mentioned earlier maybe weren't so profane at all.

The rest? Well, now is the time to roll up your sleeves and start putting in some debug prints.
I do not have a keypad, so can't easily build a version of this project, and I don't have the time or inclination to dry-run this.
Unless you can get someone who does have similar hardware to try, you're going to have to do some work yourself and report the results here.

HI Guys,

I have never done programing before, how do I debug the code. :frowning:

You liberally scatter your code with short but informative prints.
Then you read the prints as you run the program, and see if your expectations match reality.

Hi,

I am using the arduino 022 program to compile the code and upload it then I run it on the uno.
I have looked but dont see a debug feature.

See reply #24

Sry clueless . I am not as clued up as you and I might seem like a dip but I am realy trying hard .

Thanks for the help.

AWOL:
See reply #24

Notice he didn't say "use the debug function" (which doesn't exist)... he said "liberally scatter your code with short but informative prints".

Meaning, you make your own debugger using the program itself.

If you're having trouble with code that says "a = b; if (b==255) doStuff();", and doStuff() isn't running, you'd add something like "Serial.print("b set itself to: "); Serial.println(b, DEC);", and watch your serial monitor as the program runs to see what's going on in its head - since you just added the "print" lines that make it tell you that.

Hi all,

I found a artical on creating a debug macro here from Fabio Varesano :http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271517197

Now I am a bit stuck , I have created the Header file and it works but where/ how do i insert the DEBUG command in my code. :disappointed_relieved:

/*Airsoft TIMER
 Version 1.5
Creators:
 Chase Cooley
 Joey Meyer
Turned into usable code, 6/16/2011:
 Matt Falcon*/

#define DEBUG
#include "DebugUtils.h" 
#include <Keypad.h>
#include <LiquidCrystal.h>
#define pound 14
#define LED_RED 5
#define LED_GREEN 6
#define KP_ROWS 3
#define KP_COLS 4




unsigned int timerSeconds = 300; // start with 5 minutes on the clock
byte password[4];
byte entered[4];
int currentLength = 0;
byte i = 0;

LiquidCrystal lcd(7, 8, 10, 11, 12, 13);

//Keypad
char keys[KP_ROWS][KP_COLS] = { { '1', '2', '3', '4' }, { '5', '6', '7', '8' }, {
		 '*', '9', '0', '#' } };
byte rowPins[KP_ROWS] = { 2, 14, 15 }; //connect to the row pinouts of the keypad {18, 2, 14, 16}
byte colPins[KP_COLS] = { 16, 17, 18, 19 }; //connect to the column pinouts of the keypad {17, 19, 15}
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KP_ROWS, KP_COLS);

char key;

//LCD setup
void setup() {
	 pinMode(LED_RED, OUTPUT); // sets the digital pin as output
	 pinMode(LED_GREEN, OUTPUT); // sets the digital pin as output
	 lcd.begin(16, 2);
	 lcd.print("Enter Code: ");
	 lcd.cursor();
	 lcd.setCursor(6, 1);
	 while (currentLength < 4) {
		 key = keypad.getKey();
		 if (key != NO_KEY) {
			 lcd.print(key);
			 password[currentLength] = key;
			 currentLength++;
			 lcd.setCursor(currentLength + 6, 1);
		 } else delay(100); // only sample it every 1/10 sec, no need to go apesh!t
	 }
	 lcd.noCursor();
	 lcd.clear();
	 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]);
	 delay(2500);
	 lcd.clear();
	 currentLength = 0;
}

void loop() {
	 lcd.clear();
	 lcd.print("Enter Code: ");
	 lcd.cursor();
	 key = keypad.getKey(); // get the key once per this loop
	 if (key != NO_KEY) {
		 lcd.setCursor(0, 1);
		 lcd.print("               ");
		 lcd.setCursor(6, 1);
		 while (currentLength < 4) {
			 // here, we take the key that broke us into this "if" statement, instead of discarding it. this also pauses the timer, effectively.
			 if (key != NO_KEY) { // redundant for the first loop, but necessary for every next character
				 lcd.setCursor(currentLength + 5, 1);
				 lcd.print("*");
				 lcd.setCursor(currentLength + 6, 1);
				 lcd.print(key);
				 entered[currentLength] = key;
				 currentLength++;
			 } else delay(100); // only sample it every 1/10 sec
			 key = keypad.getKey(); // get the key every time "while" loops
		 }
		 if (memcmp(entered,password,4) == 0) { // shortcut to compare an array of bytes, use memcmp(A, B, length), will return 0 if match.
			 lcd.noCursor();
			 lcd.clear();
			 lcd.print(" Defused ");
			 lcd.setCursor(0, 1);
			 lcd.print("Reset the Bomb");
			 delay(2500); // hold that on screen for 2.5 seconds
			 currentLength = 0;
		 } else {
			 lcd.noCursor();
			 lcd.clear();
			 lcd.print(" Wrong ");
			 lcd.setCursor(0, 1);
			 lcd.print(" Time -1:30"); // Display time penalty
			 if (timerSeconds > 90) timerSeconds -= 90;
			 else timerSeconds = 1; // will trigger BOOM next cycle
			 currentLength = 0;
			 delay(2500); // hold that on screen for 2.5 seconds
		 }
	 }
	 timer(); // prints current time on screen, checks for "go off" time, holds loop for 1 second
}

void timer() {
	 lcd.setCursor(0, 1); // sets cursor to 2nd line
	 lcd.print("Timer: ");
	 lcd.print(timerSeconds / 60); // integer number of minutes on clock
	 lcd.print(":");
	 lcd.print(timerSeconds % 60); // mod 60; gives us number of seconds outside of 60sec/min
	 delay(950); // hold us here for 0.950 seconds
	 digitalWrite(LED_GREEN,!digitalRead(LED_GREEN)); // toggle the green LED once a second
	 tone(9,784, 200); // play bleep for 50ms
	 delay(50); // and there's the rest of that 1 second (not counting LCD delay)
	
	 timerSeconds--;
	 if (timerSeconds == 0) bombomb();
}
void bombomb() {
	 // routine for making ze BOMB GOEZ OFF!!!1 :D
	 lcd.noCursor();
	 lcd.clear();
	 lcd.print(" !BoOo0o0o0om! ");
	 tone(9,110, 200);
	 digitalWrite(LED_RED, HIGH); // sets the red LED on
	 delay(500); // waits half a second
	 tone(9,110, 200);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, LOW); // sets the red LED off
	 digitalWrite(LED_GREEN, HIGH); // sets the green LED on
	 tone(9,110, 200);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, HIGH); // sets the red LED on
	 digitalWrite(LED_GREEN, LOW); // sets the green LED off
	 tone(9,110, 200);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, LOW); // sets the red LED off
	 digitalWrite(LED_GREEN, HIGH); // sets the green LED on
	 tone(9,110, 200);
	 delay(500); // waits half a second
	 digitalWrite(LED_GREEN, LOW); // sets the green LED off
	 key = NO_KEY; // enter the while() loop, otherwise it'll skip. i could use do { } while();, but I'm lazy.
	 while (key == NO_KEY) {
		 key = keypad.getKey();
		 if (key == '#') {
			 lcd.clear();
			 lcd.print("Reset the Bomb");
			 delay(2500); // good ole' 2.5 sec delay
			 timerSeconds = 300; // put 5 minutes on the clock
			 // and we break the loop and go back to timer.
		 } else key = NO_KEY; // continue looking for pound key
	 }
}

Scatter DEBUG_PRINT("I'm a smart coder!! :D"); all over your code.

From the looks of things, DEBUG_PRINT() is just a quick "switchable" way to turn those statements into either "Serial.println(...)" or "" (nothing) depending on if #DEBUG is turned on or off. Does the same thing as using Serial.println().

So, I dunno if I'm being too technical here or what, but it's the same thing we've been saying for the past 6 or 7 posts about "debugging"... you've just... got... to write... your own... debug code. It's not that (f#$%ing) hard, really it's not. Anywhere you want to know what's going on, or where that part of the code is messing up, write:

DEBUG_PRINT("HAPPY PEOPLE FURIOUSLY EAT SLEEPING COLORLESS GREEN IDEAS!");

... Or whatever is relevant to the code you're trying to debug. Then use Tools -> Serial Monitor, and watch what happens.
(Oh, you may also need a "Serial.begin(9600);" line in your Setup().)

Another technique, if your code is timing-dependent, is to use any spare pins to light LEDs.

Make up a little LED board or strip with a few LEDs with suitable series resistors (eg. 220 ohm). Then plug the LEDs into spare pins, configure them for output, and turn them on/off at various places in your code. Looks pretty too!

eg.

digitalWrite (13, HIGH);
do_something ();
digitalWrite (13, LOW);

So when the LED on pin 13 goes on, you know you are in do_something() function. If it stays on you know you are stuck there. If the LED never lights up you know you never got there (or perhaps so briefly you can't see it).

Here is an example of a board I made up on a small piece of prototyping board that does exactly that:

You plug the black wire into the Gnd pin, and the others into whatever pins you like. Then watch the light show as you test your program.

Sometimes it is faster to spend an hour making up a board like that, and seeing what is happening, then spend days trying to puzzle out what is wrong. And of course a board like that can be reused many times.

Thanks, I am busy constructing one . need to go get some parts today, I will keep you informed on the progress. :slight_smile:

Hi,
Thanks again for all the help.

I dont mean to offend you guys, but I have never done coding before and I decided to do something with my son that he wants to do, I live in Africa and it took me 2 months to get the Arduino uno board and parts for this project. Then it was a process working out the components since it is not the same as the project due to availability. then the first Arduino board was faulty and the suppliers swoped it out (thanks for that). then I contact the manufacturers to get help with the code and they recomended you guys.
then when I asked for help I was treated as shit.
FalconFour, Awol and Nick found it in there good nature to help me ,I have never posted on forums before or done coding and I must say you guys are blady briliant at making people feel like crap.

I did the whole debug bug procedure and it means very little to me! all it prints in the serail screen is
(1434687: void loop() C:\Users\Adam\AppData\Local\Temp\build3797742604559976109.tmp\sketch_jun17a.cpp:103 I'm here!) The bomb is supposed to defuse not restart the timer.
And when I go to the line it is (lcd.setCursor(0, 1);.)

FalconFour:
Scatter DEBUG_PRINT("I'm a smart coder!! :D"); all over your code.

From the looks of things, DEBUG_PRINT() is just a quick "switchable" way to turn those statements into either "Serial.println(...)" or "" (nothing) depending on if #DEBUG is turned on or off. Does the same thing as using Serial.println().

So, I dunno if I'm being too technical here or what, but it's the same thing we've been saying for the past 6 or 7 posts about "debugging"... you've just... got... to write... your own... debug code. It's not that (f#$%ing) hard, really it's not. Anywhere you want to know what's going on, or where that part of the code is messing up, write:

DEBUG_PRINT("HAPPY PEOPLE FURIOUSLY EAT SLEEPING COLORLESS GREEN IDEAS!");

... Or whatever is relevant to the code you're trying to debug. Then use Tools -> Serial Monitor, and watch what happens.
(Oh, you may also need a "Serial.begin(9600);" line in your Setup().)

soul1974:
Thanks, I am busy constructing one . need to go get some parts today, I will keep you informed on the progress. :slight_smile:

Ah, right. So there is no confusion, this is the circuit:

All resistors are the same, the value isn't particularly critical, but something around 200 ohms would be about right. Not too low or you might overload your processor.

soul1974:
I have never posted on forums before or done coding and I must say you guys are blady briliant at making people feel like crap.

Apart from the other seven? ...

soul1974:
Thanks again, you are the only one on 8 forums helping.

You might want to reconsider your attitude. Your posts are somewhat insulting ("you guys make people feel like crap"). You say you never posted before, but in fact you said you posted on 8 forums.

People generally try to help, if you clearly state the problem, state what you are trying to achieve, and what you have done so far.

Hi Nick,

Thanks for your diagram I got it to work.

Apart from the other seven? ...

I have only posted on the forums for help within the last few weeks. sorry if this has to be a precise list of events leading to this day.

There are a few problems to be addressed here.

Netiquette:
You say you've posted on eight forums.
Now imagine how we'd feel here if you got an answer on one of those other forums, didn't post the result here, and just left us hanging, carrying on answering your posts.
We'd be wasting our time.

Debugging:
It is quite likely that no-one else has your exact hardware setup, or is willing to configure their kit to match.
So, you have to do a little work yourself.
Now, you've stitched together some code from somewhere, you don't fully understand how it all works (or doesn't) and then you want someone to dig you out of that hole.
Two approaches:
Break down the problem into components, like keypad entry, and concentrate on fully understanding how it all fits together. Write your own simple sketches, and print the results to just about the simplest I/O device on the Arduino, the Serial object.
Don't understand how the Serial object works?
Break it down into simpler sketches, try different things.

The second approach is to take your code as it is, put in debug statements at all the major decision points in the code, and then check that a run of the code matches where you think you think the code ought to go.
If it doesn't go where you think it should, examine the code and the inputs.

There are no shortcuts to learning to program (or debug), but a methodical approach always helps.

Hi Awol,

Thanks for your reply, I have not gone on to the other forums again since I dont want to get confused with to many answers, I believe that the Arduino rep was correct in saying that this site is the best place to get help.
I have learned alot in these past few post from You and the rest of the User that have been helping me , If i had anything useful to post I would have done so, but as you can see I even mess up posting to this site.
I am working on a detailed description and images of the project and will post it here, I hope you and the rest can forgive my attitude as I apologise from the bottom of my bad code.

Thanks Again.

AWOL:
There are a few problems to be addressed here.

Netiquette:
You say you've posted on eight forums.
Now imagine how we'd feel here if you got an answer on one of those other forums, didn't post the result here, and just left us hanging, carrying on answering your posts.
We'd be wasting our time.

Debugging:
It is quite likely that no-one else has your exact hardware setup, or is willing to configure their kit to match.
So, you have to do a little work yourself.
Now, you've stitched together some code from somewhere, you don't fully understand how it all works (or doesn't) and then you want someone to dig you out of that hole.
Two approaches:
Break down the problem into components, like keypad entry, and concentrate on fully understanding how it all fits together. Write your own simple sketches, and print the results to just about the simplest I/O device on the Arduino, the Serial object.
Don't understand how the Serial object works?
Break it down into simpler sketches, try different things.

The second approach is to take your code as it is, put in debug statements at all the major decision points in the code, and then check that a run of the code matches where you think you think the code ought to go.
If it doesn't go where you think it should, examine the code and the inputs.

There are no shortcuts to learning to program (or debug), but a methodical approach always helps.

HI Guys,

Thanks for all your help again , I got the code to work with the hardware but I need to change a few options and was wondering if you were willing to help.

  1. I need to have to set codes , 1 for arming the prop bomb and one for disarming the prop bomb.
  2. How can I get the beeping sound and light to go faster as the time gets less till it detonates the prop bomb
  3. I need the siren at the end to be more urgent sounding and longer lasting lets say 13 seconds or is there away I can use a siren from a home alarm system.
/*Airsoft TIMER
 Version 1.5
Creators:
 Chase Cooley
 Joey Meyer
Turned into usable code, 6/16/2011:
 Matt Falcon*/

//#define DEBUG
//#include "DebugUtils.h" 
#include <Keypad.h>
#include <LiquidCrystal.h>
#define pound 14
#define LED_RED 6
#define LED_GREEN 5
#define KP_ROWS 3
#define KP_COLS 4




unsigned int timerSeconds = 300; // start with 5 minutes on the clock
byte password[4];
byte entered[4];
int currentLength = 0;
byte i = 0;

LiquidCrystal lcd(8,7, 10, 11, 12, 13);


//Keypad
char keys[KP_ROWS][KP_COLS] = { { '1', '2', '3', '4' }, { '5', '6', '7', '8' }, {
		 '*', '9', '0', '#' } };
byte rowPins[KP_ROWS] = {2,14,15}; //connect to the row pinouts of the keypad 
byte colPins[KP_COLS] = { 19,18,17,16 }; //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KP_ROWS, KP_COLS);

char key;

//LCD setup
void setup() {
  Serial.begin(9600);
	 pinMode(LED_RED, OUTPUT); // sets the digital pin as output
	 pinMode(LED_GREEN, OUTPUT); // sets the digital pin as output
	 lcd.begin(16, 2);
	 lcd.print("Enter Code: ");
	 lcd.cursor();
	 lcd.setCursor(6, 1);
	 while (currentLength < 4) {
		 key = keypad.getKey();
		 if (key != NO_KEY) {
			 lcd.print(key);
			 password[currentLength] = key;
			 currentLength++;
			 lcd.setCursor(currentLength + 6, 1);
		 } else delay(10); // only sample it every 1/10 sec, no need to go apesh!t
	 }
	 lcd.noCursor();
	 lcd.clear();
	 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]);
	 delay(2500);
	 lcd.clear();
	 currentLength = 0;
}

void loop() {
	 lcd.clear();
	 lcd.print("Enter Code: ");
	 lcd.cursor();
	 key = keypad.getKey(); // get the key once per this loop
	 if (key != NO_KEY) {
		 lcd.setCursor(0, 1);
		 lcd.print("           ");
		 lcd.setCursor(6, 1);
		 while (currentLength < 4) {
			 // here, we take the key that broke us into this "if" statement, instead of discarding it. this also pauses the timer, effectively.
			 if (key != NO_KEY) { // redundant for the first loop, but necessary for every next character
				 lcd.setCursor(currentLength + 5, 1);
				 lcd.print(key);
				 entered[currentLength] = key;
				 currentLength++;
			 } else delay(10); // only sample it every 1/10 sec
			 key = keypad.getKey(); // get the key every time "while" loops
		 }
	 if (memcmp(entered,password,4) == 0) { // shortcut to compare an array of bytes, use memcmp(A, B, length), will return 0 if match.
			 lcd.noCursor();
			 lcd.clear();
			 lcd.print(" Defused ");
                         tone(9,1200, 4000); // 
                         lcd.clear();
			 lcd.setCursor(0,0);
			 lcd.print("Bomb Rebooting");
                         lcd.setCursor(0,1 );
                         lcd.print("Have a nice day!");
                         delay(4000); // hold that on screen for 2.5 seconds
                         void (*softReset) (void) = 0; //declare reset function @ address 0
                         softReset();
                         lcd.clear();
			 currentLength = 0;
		 } else {
			 lcd.noCursor();
			 lcd.clear();
			 lcd.print(" Wrong ");
                         tone(9,110, 2500);  
			 lcd.setCursor(0, 1);
			 lcd.print("Penalty -2:00"); // Display time penalty
			 if (timerSeconds > 120) timerSeconds -= 120;
			 else timerSeconds = 1; // will trigger BOOM next cycle
			 currentLength = 0;
			 delay(2500); // hold that on screen for 2.5 seconds
                         lcd.clear();
		 }
	 }
	 timer(); // prints current time on screen, checks for "go off" time, holds loop for 1 second
}

void timer() {
	 lcd.setCursor(0, 1); // sets cursor to 2nd line
	 lcd.print("Timer: ");
	 lcd.print(timerSeconds / 60); // integer number of minutes on clock
	 lcd.print(":");
	 lcd.print(timerSeconds % 60); // mod 60; gives us number of seconds outside of 60sec/min
	 delay(950); // hold us here for 0.950 seconds
{
	 digitalWrite(LED_RED,!digitalRead(LED_RED)); // toggle the green LED once a second
}
	 tone(9,800, 250); // play bleep for 50ms
	 delay(50); // and there's the rest of that 1 second (not counting LCD delay)
	
	 timerSeconds--;
	 if (timerSeconds == 0) bombomb();
}
void bombomb() {
	 // routine for making ze BOMB GOEZ OFF!!!1 :D
	 lcd.noCursor();
	 lcd.clear();
	 lcd.print(" !BoOo0o0o0om! ");
         lcd.setCursor(0, 1);
         lcd.print("you LoSe Sucker!");
	 tone(9,110, 100);
	 digitalWrite(LED_RED, HIGH); // sets the red LED on
	 delay(500); // waits half a second
	 tone(9,110, 100);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, LOW); // sets the red LED off
	 digitalWrite(LED_GREEN, HIGH); // sets the green LED on
	 tone(9,110, 100);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, HIGH); // sets the red LED on
	 digitalWrite(LED_GREEN, LOW); // sets the green LED off
	 tone(9,110, 100);
	 delay(500); // waits half a second
	 digitalWrite(LED_RED, LOW); // sets the red LED off
	 digitalWrite(LED_GREEN, HIGH); // sets the green LED on
	 tone(9,110, 100);
	 delay(500); // waits half a second

	 key = NO_KEY; // enter the while() loop, otherwise it'll skip. i could use do { } while();, but I'm lazy.
{	
while (key == NO_KEY) {
		 key = keypad.getKey();
		 if (key == '#') {
			 lcd.clear();
			 lcd.print("Resetting:");
                         lcd.setCursor(6,1);
                         lcd.print("the Bomb!");
			 delay(3000); //  3 sec delay
                          void (*softReset) (void) = 0; //declare reset function @ address 0
softReset();
			 //timerSeconds = 300; // put 5 minutes on the clock
			 // and we break the loop and go back to timer.
		 } else  key = NO_KEY; // continue looking for pound key
	 }
    }
}