Proper method for reading/interacting with input pins

I have been trying to debug this code (new to C and Arduino). All I am trying to do is configure this State Machine to:

  1. start in unarmed state and react to the PIR sensor to trigger the alarm, but only if the switchPin is HIGH.
  2. if the PIR has been triggered, a delay is allowed so the the alarm can be disabled via a keypad input (this part works fine but I have removed it from this code and substituted it with an external switch for debugging.
    The result has been not able to get the proper input signal tot he program. I am hoping that this is a simple problem with my inexperience. I have the input pins grounded with a 10K resistor. Can anyone assist? Thanks.
//////////////////////////// Initialize & Includes //////////////////////////
#include "SIM900.h"
#include "sms.h"
#include "Keypad.h"
#include <GSM.h>
SMSGSM sms;
boolean pir_SensorPin = 2;
int led_OutPin = 11; // green
int alarm_OutPin = 12; // red
int alarm_count = 0;
boolean switchPin = 3; // alarm on test
boolean PIRtriggerCheck = false;
int keypadPIN;
int z = 0;
int i = 0;
int waitTime = 5000;

//////////////////////////////// Setup ///////////////////////////////////
void setup() {
  Serial.begin (9600);  // Establish Serial connection;
  pinMode (switchPin, INPUT);
  //  digitalWrite (switchPin, LOW);
  pinMode (led_OutPin, OUTPUT);     // Set pinMode.
  pinMode (alarm_OutPin, OUTPUT);   // Set pinMode.
  pinMode (pir_SensorPin, INPUT);   // Set pinMode.
  //  digitalWrite (pir_SensorPin, LOW);
  digitalWrite (led_OutPin, LOW);   // Set output pins to LOW for start.
  digitalWrite (alarm_OutPin, LOW); // Set output pins to LOW for start.
  Serial.println ("Studio Alarm starting up."); // Serial message that GSM shield is starting up
  if (gsm.begin(4800)) {    // Set GSM shield to recommended 4800 baud rate.
    Serial.println ("Status = Network READY");
    //    digitalWrite (led_OutPin, HIGH);
  }
  attachInterrupt (digitalPinToInterrupt (2), trigger, CHANGE); // PIR as interrupt
  // Could make use of the interrupts by checking in the interrupt if the state is "armed" and
  // then setting the state to "alarm".
  Serial.println ("System Ready");
  //  switchPin = LOW;
  pir_SensorPin = LOW;
  // keyPadCheck = activated;
  // keypadPIN = LOW;
}

//////////////////////////// State Setup //////////////////////////
enum STATE {
  armed, // system acknowledges trigger
  unarmed, // system unarmed via keypad entry setting keypadPIN = LOW
  justActivated, // PIR-triggered
  alarm // confirm system unarmed then goto unarmed state else start alarm
};

STATE systemState = unarmed;
long timeGettingArmed;

/////////////////////////// Trigger ///////////////////////////////
void trigger() {
  PIRtriggerCheck = true;
}
// Could make use of the interrupts by checking in the interrupt
// if the state is "armed" and then setting the state to "alarm".

//////////////////////////// State Machine //////////////////////////
void loop() {
  check();
  Serial.println (systemState);
  Serial.print ("switchPin = "); Serial.println (switchPin);
  Serial.print ("PIRtriggerCheck = "); Serial.println (PIRtriggerCheck);
  switch (systemState) {
    case armed:
      Serial.println ("armed");
      if (PIRtriggerCheck == true) {
        systemState = alarm;
      } else if (keypadPIN == LOW) {
        systemState = unarmed;
      }
      break;
    case unarmed:
      if (keypadPIN == HIGH) {
        Serial.println ("armed");
        timeGettingArmed = millis(); // Or could just do a delay here.
        systemState = justActivated;
      }
      break;
    case justActivated:
      Serial.println ("justActivated");
      if (timeGettingArmed + waitTime < millis()) {
        systemState = alarm;
      }
      break;
    case alarm:
      Serial.println ("alarm");
      if (keypadPIN == LOW) {
        systemState = unarmed;
      } else {
        beep();
      }
      break;
  }
}

//////////////////////////// Alarm //////////////////////////
void beep() {
  Serial.println("at beep");
  // (sms.SendSMS("**********", "*** Motion Detected in Studio! ***"));
  Serial.println ("MOTION detected: SMS Sent");
  for (alarm_count = 0; alarm_count <= 5; alarm_count++) { // Cycle outputs if triggered
    digitalWrite (alarm_OutPin, HIGH); delay (1000); // On/Off/On/Off/Off
    digitalWrite (alarm_OutPin, LOW); delay (500);
    digitalWrite (led_OutPin, HIGH); // delay (1000);
    Serial.println (alarm_count);
  }
  PIRtriggerCheck = false;
  timeGettingArmed = millis();
  systemState = unarmed;
}
///////////////////////////////// check //////////////////////
void check() {
  if (switchPin == HIGH) {
    (keypadPIN = LOW); // unarmed
  }
  else {
    (keypadPIN = HIGH); // armed
  }
  Serial.print ("switchPin = "); Serial.println (switchPin);
}
boolean pir_SensorPin = 2;
boolean switchPin = 3; // alarm on test

A boolean variable can have only 2 values, (false, 0, LOW) or (true, 1, HIGH), try:

byte pir_SensorPin = 2;
byte switchPin = 3; // alarm on test
Serial.print ("switchPin = "); Serial.println (switchPin);

This will always print "3", did you mean:

Serial.print ("switchPin = "); Serial.println (digitalRead(switchPin));
byte pir_SensorPin = 2;
byte switchPin = 3; // alarm on test

even better

const byte pir_SensorPin = 2;
const byte switchPin = 3; // alarm on test

because the values will never change

Even better

const byte PirSensorPin = 2;
const byte SwitchPin = 3; // alarm on test

Don't mix and match variable name styles ;) Stick to one. A "default" with Arduino is to useNamesLikeThis (lowerCamelCase) or UseThisForConst (UpperCamelCase).

Thanks. Your suggestions seem to work, but still having trouble with my "boolean PIRtriggerCheck = false;" which is set by the attacheInterrupt call. Is it handled the same way? Doesn't seem so.

void setup() {
  Serial.begin (9600);  // Establish Serial connection;
  pinMode (switchPin, INPUT);
  pinMode (led_OutPin, OUTPUT);     // Set pinMode.
  pinMode (alarm_OutPin, OUTPUT);   // Set pinMode.
  pinMode (pir_SensorPin, INPUT);   // Set pinMode.
  digitalWrite (led_OutPin, LOW);   // Set output pins to LOW for start.
  digitalWrite (alarm_OutPin, LOW); // Set output pins to LOW for start.
  Serial.println ("Studio Alarm starting up."); // Serial message that GSM shield is starting up
  if (gsm.begin(4800)) {    // Set GSM shield to recommended 4800 baud rate.
    Serial.println ("Status = Network READY");
  }
  attachInterrupt (digitalPinToInterrupt (2), trigger, CHANGE); // PIR as interrupt
  Serial.println ("System Ready");
}

//////////////////////////// State Setup //////////////////////////
enum STATE {
  armed, // system acknowledges trigger
  unarmed, // system unarmed via keypad entry setting keypadPIN = LOW
  justActivated, // PIR-triggered
  alarm // confirm system unarmed then goto unarmed state else start alarm
};

STATE systemState = unarmed;
long timeGettingArmed;

/////////////////////////// Trigger ///////////////////////////////
void trigger() {
  PIRtriggerCheck = true;
}

but still having trouble with my "boolean PIRtriggerCheck = false;" which is set by the attacheInterrupt call.

Rubbish. The interrupt handler, if it is actually called, sets the value to true.

A PIR sensor is slow to detect motion. Why do you think that you need to react INSTANTLY when a slow sensor finally gets around to noticing that there is motion?

You need to ALWAYS post ALL of your code. It should not be necessary to wade through several posts, trying to piece together your code.

Variables manipulated in interrupt service routines, and used in other functions, MUST be declared volatile.

Your comments have been noted. My struggle is to understand why I am not getting the expected flow of my code in response to a PIR trigger. The code is also to be monitoring the level of an external switch (switchPin) to set the alarm to active or inactive. The switch reports the proper reading, but its affect on the code is not correct. I am trying to set keyPadPin to HIGH or LOW based on the switch level (switchPin), which is to then either accept or ignore the PIR sensor (pir_SensorPin). There may be another issue with what I am trying to do with a time delay which is to allow a delay after a trigger (but only when the state is alarm) to give time to disable the alarm with the switchPin switch. I have tried with and without an interrupt. I am still learning by mistakes, so any help is appreciated. Code follows:

//////////////////////////// Initialize & Includes //////////////////////////
#include "SIM900.h"
#include "sms.h"
#include "Keypad.h"
#include <GSM.h>
SMSGSM sms;
const byte pir_SensorPin = 2;
int led_OutPin = 11; // green
int alarm_OutPin = 12; // red
int alarm_count = 0;
const byte switchPin = 3; // alarm on test
volatile boolean pirTriggerCheck = false;
int keyPadPin;
int z = 0;
int i = 0;
int waitTime = 15000;

//////////////////////////////// Setup ///////////////////////////////////
void setup() {
  Serial.begin (9600);  // Establish Serial connection;
  pinMode (switchPin, INPUT);
  //  digitalWrite (switchPin, LOW);
  pinMode (led_OutPin, OUTPUT);     // Set pinMode.
  pinMode (alarm_OutPin, OUTPUT);   // Set pinMode.
  pinMode (pir_SensorPin, INPUT);   // Set pinMode.
  //  digitalWrite (pir_SensorPin, LOW);
  digitalWrite (led_OutPin, LOW);   // Set output pins to LOW for start.
  digitalWrite (alarm_OutPin, LOW); // Set output pins to LOW for start.
  Serial.println ("Studio Alarm starting up."); // Serial message that GSM shield is starting up
  if (gsm.begin(4800)) {    // Set GSM shield to recommended 4800 baud rate.
    Serial.println ("Status = Network READY");
  }
  //  attachInterrupt (digitalPinToInterrupt (2), trigger, HIGH); // PIR as interrupt
  // Could make use of the interrupts by checking in the interrupt if the state is "armed" and
  // then setting the state to "alarm".
  Serial.println ("System Ready");
}

//////////////////////////// State Setup //////////////////////////
enum STATE {
  armed, // system acknowledges trigger
  unarmed, // system unarmed via keypad entry setting keyPadPin = LOW
  justActivated, // PIR-triggered
  alarm // confirm system unarmed then goto unarmed state else start alarm
};

STATE systemState = unarmed;
long timeGettingArmed;

/////////////////////////// Trigger ///////////////////////////////
void trigger() {
  pirTriggerCheck = true;
}

//////////////////////////// State Machine //////////////////////////
void loop() {
  check();
  Serial.println (systemState);
  Serial.print ("switchPin = "); Serial.println (digitalRead(switchPin));
  //  Serial.print ("pirTriggerCheck = "); Serial.println (digitalRead(pirTriggerCheck));
  switch (systemState) {
    case armed:
      Serial.println ("armed");
      if (digitalRead(pir_SensorPin == HIGH)) {
        systemState = alarm;
      } else if (digitalRead(keyPadPin == LOW)) {
        systemState = unarmed;
      }
      break;
    case unarmed:
      if (digitalRead(keyPadPin == HIGH)) {
        Serial.println ("armed");
        timeGettingArmed = millis(); // Or could just do a delay here.
        systemState = justActivated;
      }
      break;
    case justActivated:
      Serial.println ("justActivated");
      if (timeGettingArmed + waitTime < millis()) {
        systemState = alarm;
      }
      break;
    case alarm:
      Serial.println ("alarm");
      if (digitalRead(keyPadPin == LOW) && (pir_SensorPin == HIGH)) {
        pirTriggerCheck = false;
        systemState = unarmed;
      } else {
        beep();
      }
      break;
  }
}

//////////////////////////// Alarm //////////////////////////
void beep() {
  Serial.println("at beep");
  // (sms.SendSMS("8656171435", "*** Motion Detected in Studio! ***"));
  Serial.println ("MOTION detected: SMS Sent");
  for (alarm_count = 0; alarm_count <= 5; alarm_count++) { // Cycle outputs if triggered
    digitalWrite (alarm_OutPin, HIGH); delay (1000); // On/Off/On/Off/Off
    digitalWrite (alarm_OutPin, LOW); delay (500);
    digitalWrite (led_OutPin, HIGH); // delay (1000);
    Serial.println (alarm_count);
  }
  if (digitalRead(pir_SensorPin) == false); {
    timeGettingArmed = millis();
    systemState = unarmed;
  }
}
///////////////////////////////// check //////////////////////
void check() {
  if (digitalRead(switchPin == LOW)) {
    keyPadPin = LOW; // unarmed
  } else if (digitalRead(switchPin == HIGH)) {
    keyPadPin = HIGH; // armed
  }
  Serial.print ("switchPin = "); Serial.println (digitalRead(switchPin));
}
  if (digitalRead(switchPin == LOW))
  {
    keyPadPin = LOW; // unarmed
  }
  else if (digitalRead(switchPin == HIGH))
  {
    keyPadPin = HIGH; // armed
  }

So, you set keyPadPin LOW or HIGH, then later you do this

      else if (digitalRead(keyPadPin == LOW))

Which pin do you think that digitalRead() is reading ?

keyPadPin suggests, to me, that the variable hold a pin number. keyPadState would suggest that it holds a state.

Meaningful names ARE important.

Be crystal clear between a pin number, a variable holding a pin state, and the digitalRead() call that reads a pin's state - usually a variable to hold the state is unnecessary and can cause issues, so don't use one without a reason. The variable is a snapshot of the pin state, it is not the live pin state.

If you want to name active pin states clearly, a macro is one way to do this:

#define keyPadPinState (digitalRead(keyPadPin))
#define keyPadPinActive (keyPadPinState == LOW)

...
if (keyPadPinActive)
  ...

Thanks for the reply and suggestions. However, I want to make sure that I understand. Currently, with the following code, I seem to be trapped in the initial state, “unarmed” and not sure why. I feel that I may still be wrongly using pin inputs or variable readings. I determined this by a series of Serial.print statements giving me the following:
unarmed
switchPin = 1
systemState = 1
pirSensorPin = 0
pirTriggerCheck = 0
keyPadPin = 0

Aaaaaargh!

//////////////////////////// Initialize & Includes //////////////////////////
#include "SIM900.h"
#include "sms.h"
#include "Keypad.h"
#include <GSM.h>
SMSGSM sms;
const byte pir_SensorPin = 2;
int led_OutPin = 11; // green
int alarm_OutPin = 12; // red
int alarm_count = 0;
const byte switchPin = 3; // alarm on test
boolean pirTriggerCheck;
int keyPadPin;
int z = 0;
int i = 0;
int waitTime = 15000;

//////////////////////////////// Setup ///////////////////////////////////
void setup() {
  Serial.begin (9600);  // Establish Serial connection;
  pinMode (switchPin, INPUT);
  //  digitalWrite (switchPin, LOW);
  pinMode (led_OutPin, OUTPUT);     // Set pinMode.
  pinMode (alarm_OutPin, OUTPUT);   // Set pinMode.
  pinMode (pir_SensorPin, INPUT);   // Set pinMode.
  //  digitalWrite (pir_SensorPin, LOW);
  digitalWrite (led_OutPin, LOW);   // Set output pins to LOW for start.
  digitalWrite (alarm_OutPin, LOW); // Set output pins to LOW for start.
  Serial.println ("Studio Alarm starting up."); // Serial message that GSM shield is starting up
  if (gsm.begin(4800)) {    // Set GSM shield to recommended 4800 baud rate.
    Serial.println ("Status = Network READY");
  }
  attachInterrupt (digitalPinToInterrupt (2), trigger, CHANGE); // PIR as interrupt
  // Could make use of the interrupts by checking in the interrupt if the state is "armed" and
  // then setting the state to "alarm".
  Serial.println ("System Ready");
}

//////////////////////////// State Setup //////////////////////////
enum STATE {
  armed, // system acknowledges trigger
  unarmed, // system unarmed via keypad entry setting keyPadPin = LOW
  justActivated, // PIR-triggered
  alarm // confirm system unarmed then goto unarmed state else start alarm
};

STATE systemState = unarmed;
long timeGettingArmed;

/////////////////////////// Trigger ///////////////////////////////
void trigger() {
  pirTriggerCheck = true;
}

//////////////////////////// State Machine //////////////////////////
void loop() {
  check();

  Serial.print ("switchPin = "); Serial.println (digitalRead(switchPin));
  Serial.print ("systemState = "); Serial.println (systemState);
  Serial.print ("pirSensorPin = "); Serial.println (digitalRead(pir_SensorPin));
  Serial.print ("pirTriggerCheck = "); Serial.println (pirTriggerCheck);
  Serial.print ("keyPadPin = "); Serial.println (keyPadPin);
  Serial.println ("");

  switch (systemState) {
    case armed:
      Serial.println ("armed");
      if (digitalRead(pir_SensorPin == HIGH)) {
        systemState = alarm;
      } else if (digitalRead(switchPin == LOW)) {
        systemState = unarmed;
      }
      break;
    case unarmed:
    Serial.println ("unarmed");
      if (keyPadPin == true) {
        Serial.println ("armed");
        timeGettingArmed = millis(); // Or just do a delay here.
        systemState = justActivated;
      }
      break;
    case justActivated:
      Serial.println ("justActivated");
      if (timeGettingArmed + waitTime < millis()) {
        systemState = alarm;
      }
      break;
    case alarm:
      Serial.println ("alarm");
      if ((keyPadPin) == LOW && digitalRead(pir_SensorPin == HIGH)) {
        //       pirTriggerCheck = false;
        systemState = unarmed;
      } else {
        beep();
      }
      break;
  }
}

//////////////////////////// Alarm //////////////////////////
void beep() {
  Serial.println("at beep");
  // (sms.SendSMS("8656171435", "*** Motion Detected in Studio! ***"));
  Serial.println ("MOTION detected: SMS Sent");
  for (alarm_count = 0; alarm_count <= 5; alarm_count++) { // Cycle outputs if triggered
    digitalWrite (alarm_OutPin, HIGH); delay (1000); // On/Off/On/Off/Off
    digitalWrite (alarm_OutPin, LOW); delay (500);
    digitalWrite (led_OutPin, HIGH); // delay (1000);
    Serial.println (alarm_count);
  }
  if (digitalRead(pir_SensorPin) == false); {
    timeGettingArmed = millis();
    systemState = unarmed;
  }
}

///////////////////////////////// check //////////////////////
void check() {
  if (digitalRead (switchPin == LOW)) {
    keyPadPin = LOW; // unarmed
  } else if (digitalRead (switchPin == HIGH)) {
    keyPadPin = HIGH; // armed
  }
}
if (digitalRead(pir_SensorPin == HIGH))

Go look at the reference page for digitalRead and see if you can't spot what you did wrong here. Or really any example code that uses it. Pay particular attention to the parenthesis.

      if (digitalRead(pir_SensorPin == HIGH))

Whoops ! Check how you are using digitalRead()