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!