Go Down

Topic: Timer program (Read 14093 times) previous topic - next topic

FalconFour


Thank you for taking the time to help a noob.

the code give me this  error.

Code: [Select]
sketch_jun17a.cpp: In function 'void bombomb()':
sketch_jun17a:144: error: 'key' was not declared in this scope


Ahh what the heck... I guess I overlooked that when I was overlooking the "keypad.h" errors. I'll edit it, by the time you read this I should have it fixed. :)

soul1974

#16
Jun 17, 2011, 08:37 am Last Edit: Jun 17, 2011, 08:39 am by soul1974 Reason: 1
Thanks a mil,

I have new issues that have poped up.
1. the code when you type it in for the first time , when it prints ( you have entered: shows wrong code e.g. if i type 1111 it shows 49494949)
2. when you type in the defuse code it does not reset ,it says reseting but continues to count down.
3. when you type in the code and the screen changes part of the sentence stays behind e.g. 2:30omb
4. when the bomb goes of it does not reset the unit automaticaly, when I pres the # key it restarts the timer.

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


Alright, here you go, have a ball.

I went through it line by line, removed an obscene number of useless statements (like lcd.home() and lcd.setCursor(0,0) after a lcd.clear()... or a "if key == key" after a "while (key != key)" statement... ugh!), and did my best to interpret the way it's supposed to work... I don't even have an Arduino board handy here at my office, but I figure this will work fine as long as you provide that "keypad.h" file it's asking for (I didn't bother searching for it... I'm guessing you have it?).

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

#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],DEC);
lcd.print(password[1],DEC);
lcd.print(password[2],DEC);
lcd.print(password[3],DEC);
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 -0:30"); // Display time penalty
if (timerSeconds > 30) timerSeconds -= 30;
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
}
}


Let me know how it works... I literally haven't even tested this! Of course, last time I posted code that "I haven't even tested", I got grilled for it, but whatever... it's better than what the rest of the users here are contributing ;)

edit: Almost forgot... oughtta tack my name into the header =P
edit: declared "key" globally since we use it so often in the program...

soul1974

Thanks it compiled.

I am busy testing it now. some issues found posted it with the code.

Thanks again.



Thank you for taking the time to help a noob.

the code give me this  error.

Code: [Select]
sketch_jun17a.cpp: In function 'void bombomb()':
sketch_jun17a:144: error: 'key' was not declared in this scope


Ahh what the heck... I guess I overlooked that when I was overlooking the "keypad.h" errors. I'll edit it, by the time you read this I should have it fixed. :)

AWOL

49 is the decimal value of the ASCII code for the character '1'

try:
Quote
lcd.print(password[0]);
etc

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

So, I'm potentially wasting my time here?

soul1974

HI,

Thanks for taking the time to look at the code, I sincerely apologise if I offended you in anyway.
this is the only forum that has bothered to help a noob.


49 is the decimal value of the ASCII code for the character '1'

try:
Quote
lcd.print(password[0]);
etc

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

So, I'm potentially wasting my time here?

soul1974

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

Quote
Quote

lcd.print(password[0]);

nickgammon



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:

Code: [Select]
[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.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

AWOL

Quote
2. when you type in the defuse code it does not reset ,it says reseting but continues to count down.
3. when you type in the code and the screen changes part of the sentence stays behind e.g. 2:30omb
4. when the bomb goes of it does not reset the unit automaticaly, when I pres the # key it restarts the timer.

3. 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.

soul1974

HI Guys,

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

AWOL

#24
Jun 18, 2011, 05:55 pm Last Edit: Jun 18, 2011, 06:38 pm by AWOL Reason: 1
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.

soul1974

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.

AWOL


soul1974

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.


See reply #24

FalconFour

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.

soul1974

#29
Jun 19, 2011, 09:02 am Last Edit: Jun 19, 2011, 09:05 am by soul1974 Reason: 1
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. :smiley-sad-blue:
Code: [Select]
/*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
}
}

Go Up