I have a keypad that works of a passcode. I also have a door contact plus gsm that sends an sms when the door is opened. Both of these at present are working *separately.
What I need is for the door contact to only send sms when the system is set. The system is set via the keypad. I have had the code for the doorState in the (Loop function) and tried removing it from their and creating its own (doorState function). Which I then tried to call from the systemSet function by putting in doorState();. But as expected it only runs once, since its no longer in the "LOOP".
So I think I need to leave the "doorState" in the (Loop function) and add code to it their to look at the (checkPIN function). Is this the correct way to do it.
here is the code snippet of these function.
void systemSet()
{
systemSetTone();
lcd.print (" System Set ");
}
void systemUnSet()
{
systemUnSetTone();
lcd.print (" System Unset ");
}
//------------------------------PASSWORD-CODE-SECTION-------------------------------
void checkPIN()
{
int correct = strcmp(attempt, PIN);
if (correct < 0)
systemUnSet();
else if (correct == 0)
systemSet();
else if (correct > 0)
systemUnSet();
return;
}
//------------------------------KEYPAD-CHECKING-------------------------------------
void readKeypad()
{
char key = keypad.getKey();
if (key != NO_KEY) // only do something if a key was pressed
{
fromKeypad++; //Each time there is a character received, increment the counter:
lcd.setCursor(fromKeypad-1, 1);
lcd.print(key);
switch(key)// look for the special keys to initiate an event
{
case '*':
z=0;
fromKeypad = 0;
break;
case '#':
delay(100); // for extra debounce
fromKeypad = 0;
lcd.clear();
checkPIN();
break;
default:
attempt[z]=key;
z++;
attempt[z] = '\0';
KeyPadTone();// play a beep to acknowledge that key pressed
}
}
}
void loop()
{
readKeypad();
}
//-------------------doorState------------------------------------------------------
static bool DoorIsClosed=true; // Let's assume it's closed for starting
static bool SMSSent=false; // Tells us whether we've sent an SMS for the latest instance of the door being open
int currDoorState = digitalRead(doorContactPin); //current door state is the current condition of the door contact pin.
if(currDoorState != prevDoorState) // checked against above statement. Door was closed and is now open or door was open and is now closed
{
if(currDoorState == LOW)
{
DoorIsClosed=true; // Door is now closed
}
else
{
DoorIsClosed=false; // Door is now open
doorOpenTime = millis();
}
SMSSent=false; // Door state changed, we may have a new opportunity to send SMS
}
prevDoorState = currDoorState; //previous door state is NOW the current door state.
if(!DoorIsClosed && !SMSSent) // Now see if the door is open TRUE if the door is not closed and sms is not sent
{
if(millis() - doorOpenTime >= time_threshold) // if the overall time minus the door open time is greater then time threashold send sms
{
sendSMS();
SMSSent=true;
}
}
}
All that code after loop() is not in a function. So, no.
The systemSet() and systemUnset() functions don't actually do anything. They need to, at a minimum set/clear a flag that says that the alarm is/is not set.
so I need to leave it where it is and create an interupt is that correct.
No. Interrupts are external events that need to be handled immediately, like serial data arriving. Nothing about your program needs to be dealt with immediately. A few milliseconds later will be fine. So, polling is good enough.
how do you pole?. is the example sketch BlinkWithoutDelay using polling? thats comes with the arduino software?
/* Blink without Delay
Turns on and off a light emitting diode(LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.
The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/
// constants won't change. Used here to
// set pin numbers:
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
from previous
so I need to leave it where it is
do I leave the doorState in the void loop. or do I need to put it in a function.
void loop()
{
readKeypad();
}
//-------------------doorState------------------------------------------------------
static bool DoorIsClosed=true; // Let's assume it's closed for starting
static bool SMSSent=false; // Tells us whether we've sent an SMS for the latest instance of the door being open
int currDoorState = digitalRead(doorContactPin); //current door state is the current condition of the door contact pin.
if(currDoorState != prevDoorState) // checked against above statement. Door was closed and is now open or door was open and is now closed
{
if(currDoorState == LOW)
{
DoorIsClosed=true; // Door is now closed
}
else
{
DoorIsClosed=false; // Door is now open
doorOpenTime = millis();
}
SMSSent=false; // Door state changed, we may have a new opportunity to send SMS
}
prevDoorState = currDoorState; //previous door state is NOW the current door state.
if(!DoorIsClosed && !SMSSent) // Now see if the door is open TRUE if the door is not closed and sms is not sent
{
if(millis() - doorOpenTime >= time_threshold) // if the overall time minus the door open time is greater then time threashold send sms
{
sendSMS();
SMSSent=true;
}
}
}
in general terms, I'm even more confused now with what seems to be a wealth of options.
As I understand, If I leave the part of the code in the void loop I need it to call to some piece of code in another function to test a condition. Based on the result of that condition. The part of the void loop that runs the doorState code will do either something or something else.
It looks kind of simple but I can't code what I am trying to achieve in my head. I have no logic
Always. There are ways to skin a dog, too. And a deer, and a variety of other animals.
It looks kind of simple but I can't code what I am trying to achieve in my head. I have no logic
I suspect that is because you are trying to write the whole program at once.
What I like to do is write a whole lot of comments in loop, describing what the whole program is going to do. Then, in between some of the comments, I write some code to perform a specific task. When that works, I write some more code. After a while, loop() is too long, so I move some working code into functions.
Sometimes I get stuck on how to do something, so I create a function that does nothing, and call it in the place I'm stuck. I just have it return a value that makes it seem like it actually did something complex.
Then, I'll go back and make that function do what it is supposed to do, one step at a time. Each time I get stumped, I write a lot of comments.