IF statement not working - variable issue?

I have looked for over an hour, and re-written the code several times, but I'm still having trouble:

Here is the full code:

//v001 - Wemos D1 mini - garage alarm
//
//Blynk app "Garage alarm"
//Blynk documentation and help https://docs.blynk.cc/
//
//To do list:
//Fix if statement for app notification
//Add Blynk terminal
//Add date and time of events to terminal
//


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>


char auth[] = ""; //Enter the Auth code which was send by Blynk

char ssid[] = "";  //Enter your WIFI Name
char pass[] = "";  //Enter your WIFI Password

const byte AlarmState = D5;     // INPUT - is the alarm set, or unset/alarmed? (Set/armed = HIGH/3.3V and Unset/alarmed = LOW/0V)
const byte SounderActive = D6;  // INPUT - is the sounder on or off? (Sounder on = LOW/0.33V and Sounder off = HIGH/3.3V)
const byte SetAlarm = D4;       // OUTPUT - set or unset the alarm (HIGH = unset the alarm,  LOW = set the alarm)


//Setup Blynk virtual pin states
static unsigned long last_interrupt_time = 0;  
bool LastVirtualButtonState = 0; // "0", "FALSE", "LOW' means exactly the same


void setup()
{
  pinMode(AlarmState, INPUT);       // is the alarm set, or unset/alarmed? (Set/armed = HIGH/3.3V and Unset/alarmed = LOW/0V)
  pinMode(SounderActive, INPUT);    //is the sounder on or off? (Sounder on = LOW/0.33V and Sounder off = HIGH/3.3V)
  pinMode(SetAlarm, OUTPUT);        // set or unset the alarm (HIGH = unset the alarm,  LOW = set the alarm)
  digitalWrite(SetAlarm, LOW);      //ensures the alarm defaults to SET condition after power loss of Wemos
  
  Blynk.begin(auth, ssid, pass);   //connects to WiFi network, then connects to Blynk server
  
  
  //read the current state of the alarm
int lastAlarmState = digitalRead(AlarmState);        //reads state of the alarm i.e. set or unset
int lastSounderActive = digitalRead(SounderActive);  // reads state of sounder i.e on or off

//write the current state to the Blynk app
 Blynk.virtualWrite(V5, (lastAlarmState * 255));      // writes set or unset state of alarm to Blynk virtual LED pin V5
 Blynk.virtualWrite(V6, (!lastSounderActive * 255));   //writes sounder on or off state to Blynk virtual LED pin V6 (inverted logic as sounder is on when at 0V


//set up interupts to capture changes of state
  attachInterrupt(digitalPinToInterrupt(AlarmState), updateAlarmState, CHANGE);         // upon change of state - call the function updateAlarmState
  attachInterrupt(digitalPinToInterrupt(SounderActive), updateSounderActive, CHANGE);   // upon change of state - call the function updateSounderActive
}



void loop()
{
 Blynk.run();  // This function should be called frequently to process incoming commands and perform housekeeping of Blynk connection.
}



void updateAlarmState()  // a function called by a CHANGE interrupt, which write the input state to a Blynk virtual LED
{
 Blynk.virtualWrite(V5, digitalRead(AlarmState)*255);   //read alarm state (set or unset/alarmed and write to Blnk V5 virtual LED
}


void updateSounderActive()  // a function called by a CHANGE interrupt, which write the input state to a Blynk virtual LED
{
  
  if (SounderActive == LOW)
  {
    Blynk.notify("Garage alarm is sounding!");  //only send Blynk app notification when then sounder is ON
  }

Blynk.virtualWrite(V6, !digitalRead(SounderActive)*255); //Using ! to invert the write, to match the alarm panel logic (sounder on when at 0V)

}


// BLYNK_WRITE is a function called every time device gets an update of a Virtual Pin value from the server (or app): e.g. Blynk app virtual button is pressed
// Contains virtual button "latching" code
BLYNK_WRITE(V3)
{
    int VirtualButtonState = param.asInt(); // assigning incoming value from pin V3 to a variable

    if ((VirtualButtonState) && (!LastVirtualButtonState)) // "VirtualButtonState" is the Blynk virtual button current state ||||||  this means same as "if ((VirtualButtonState == 1) && (LastVirtualButtonState == 0))"
    //if V3 virtual button is still being pressed, the LastVirtualState is set to 1, and !LastVirtualState will therefore be 0. Hence 1 && 0 condition == 0 and therefore function will not be called.
  
  {
    digitalWrite(SetAlarm, !digitalRead(SetAlarm));       //writes the inverse value to the pin  (booleon NOT operator )
    Blynk.virtualWrite(V0, digitalRead(SetAlarm)*255);    //writes the new state to the Blynk app LED at V0
  }
  
  LastVirtualButtonState = VirtualButtonState;  // sets LastVirtualButtonState to the same as pinValue, so if pinValue (V5 button) is high, LastVirtualPinState gets set to high
}

The problem is with the **updateSounderActive() ** function, which is triggered by a CHANGE interrupt.

void updateSounderActive()  // a function called by a CHANGE interrupt, which write the input state to a Blynk virtual LED
{
  
  if (SounderActive == LOW)
  {
    Blynk.notify("Garage alarm is sounding!");  //only send Blynk app notification when then sounder is ON
  }

Blynk.virtualWrite(V6, !digitalRead(SounderActive)*255); //Using ! to invert the write, to match the alarm panel logic (sounder on when at 0V)

}

-The input goes HIGH or LOW
-The code "Blynk.virtualWrite(V6, !digitalRead(SounderActive)*255);" changes the state of the LED on my phone - works.
-I want only the LOW states to trigger the phone notification via "Blynk.notify"

My original code sent the app notification on every change of state, so I know that part works:

void updateSounderActive()  // a function called by a CHANGE interrupt, which write the input state to a Blynk virtual LED
{
  
Blynk.virtualWrite(V6, !digitalRead(SounderActive)*255); //Using ! to invert the write, to match the alarm panel logic (sounder on when at 0V)
Blynk.notify("Garage alarm is sounding!");  //only need to send Blynk app notification when then sounder is ON (LOW logic)
  }

But I only want it to send the app notification on a LOW logic level.

I'm wondering if it's because of how I set the variables up as "cont byte", I tried "int" and "const int" but still the same.

Any advice appreciated!

const byte SounderActive = D6;Not ever going to equal LOW

AWOL:

const byte SounderActive = D6;

Not ever going to equal LOW

Thanks AWOL, I suspected that earlier but wasn't sure.

Should it be "const int"?

I read the Arduino guide on const and it says it makes it read only. So I thought that might be part of the issue.

Also earlier I tried " if (SounderActive == 0)" and that didn't work either.

Confused myself now :slight_smile:

LOW is zero, whether byte, int or unsigned long.

I don't know what the value of D6 is (it may depend on platform), but it looks like a pin number to me.

Are you missing a digitalRead?

const byte SounderActive = D6;
  pinMode(SounderActive, INPUT);

SounderActive is set to be a pin number and what is more it is a constant so cannot change (which is good)

However, later you do this

 if (SounderActive == LOW)

As pointed out SounderActive is never going to equal LOW

Did you mean to do

 if (digitalRead(SounderActive) == LOW)

Thanks you AWOL that was the issue!

I assumed that the value of SounderActive would be read magically I think!!

Here is the working code:

void updateSounderActive()  // a function called by a CHANGE interrupt, which write the input state to a Blynk virtual LED
{

  if (digitalRead(SounderActive) == 0) 
   {
    Blynk.notify("Garage alarm is sounding!");  //only send Blynk app notification when then sounder is ON
  }

Blynk.virtualWrite(V6, !digitalRead(SounderActive)*255); //Using ! to invert the write, to match the alarm panel logic (sounder on when at 0V)

}

Thanks again! :slight_smile:

@UKHeliBob also thank you, yes you are correct!

I guess

if (digitalRead(SounderActive) == LOW)

or

if (digitalRead(SounderActive) == 0)

would work, I will try it now to confirm for myself..

EDIT - both work but I'm sure you knew that.

Thanks both!!