I’m sorry I’ve been sick and I have not been able to respond.
To make it easier to understand my project, I have done an electrical scheme of what would be both an input and an output, I have simplified the code of my program, since it is repeated or very similar for each of the inputs, and I have translated the comments into English to make it easier to follow my code.
The outputs are activated for a second, for this I perform a timing, these timings sometimes fail, and I think it is due to the interruption caused by the PCF8574 input port.
My program
#include <BlynkSimpleEsp8266.h>
#include <dummy.h>
#include <WidgetLED.h>
#include <Wire.h>
#include “ESP8266WiFi.h”
#include <SimpleTimer.h>
#define AdrPortIn0PCF8574A 0X21 // DirecciĂłn del puerto 0 del PCF8574A configurado como entradas.
#define AdrPortOut0PCF8574T 0x20 // DirecciĂłn del puerto 0 del PCF8574A configurado como entradas.
char ssid[] = “”; // your network SSID (name)
char pass[] = “”; // your network password (use for WPA, or use as key for WEP)
char auth[] = “”;
boolean MirrorPinPortIn0PCF8574A[7];
volatile boolean TempPinPortIn0PCF8574A[7];
volatile boolean FlagINT=false; // Bandera para saber que se ha producido la interrupciĂłn.
SimpleTimer timer;
int timerID;
WidgetLED Led0(V0); // Led Interior garage lights
WidgetLED Led1(V1); // Led Exterior garage lights
WidgetLED Led2(V2); // Led Interior light garage detector
int status = WL_IDLE_STATUS;
void InicalizaLedsBlynk(); // Para poder llamarla desde "void setup() hay que declararla.
void InicalizaButtonsBlynk();
void IntPortInPCF8574();
void UpdateDataPortIns(byte AdrPort);
byte ReadDataPortPCF8574A (byte device);
void UpdatePortOut0PCF8574APulse();
void OffPinPortOutPCF8574APulse();
void WriteDataPortPCF8574A(byte device,byte data);
void UpdateProgram();
byte AdrDeviceOut;
int PinOut;
/* FunciĂłn para configuar y establecer las condiciones iniciales del programa */
void setup()
{
Wire.begin(); //Activate Bus I2C
Blynk.begin(auth, ssid, pass);
while (Blynk.connect() == false) {
// Wait until connected
}
InicalizaLedsBlynk(); // I read the inputs to update the Blynk Led
InicalizaButtonsBlynk(); //Depending on the inputs I update the function of the buttons.
attachInterrupt(D5,IntPortInPCF8574,FALLING); // When an interruption occurs, it is downhill FALLING
}
/* FUNCIÓN QUE SE EJECUTA AL PRODUCIRSE LA INTERRUPCIÓN PARA LOS PUERTOS PCF8574 USADOS COMO ENTRADAS */
void IntPortInPCF8574()
{
UpdateDataPortIns(AdrPortIn0PCF8574A); // Function to update the variable “TempPinPortIn0PCF8574A[7]”, for
// Then in main program when comparing with MirrorPinPortIn0PCF8574A[7]
// Know the entry that has changed status.
FlagINT=true; // Interruption flag
} // In main program I call the function “UpdateProgram()”.
/* FUNCTION TO READ THE INPUT PORT, DETERMINE THE INPUT THAT HAS CHANGED AND HAS CAUSED THE INTERRUPTION, /
/ AND UPDATING THE VARIABLE MIRROR USED /
/ Input data: address on the I2C bus of the port to read */
void UpdateDataPortIns(byte AdrPort)
{
byte DataPortIn,DataPortInAgain;
byte InOn=B00000001;
byte InOnTemp;
int NRead=0;
DataPortIn=ReadDataPortPCF8574A(AdrPort); // Read Port In,s PCF8574A
for (int i=0;i<8;i++) // I examine each of the bits of the input port
{
InOnTemp=DataPortIn & InOn;
if(InOnTemp == InOn)
TempPinPortIn0PCF8574A[i]=HIGH;
else TempPinPortIn0PCF8574A[i]=LOW;
InOn=InOn<<1;
}
}
/* FUNCTION TO UPDATE PUERTO LAS SALIDAS /
/ Input data: /
/ - Address on the I2C bus of the output port /
/ - Output bit to update /
/ The outputs from 0 to 2 are activated by giving a pulse. */
void UpdatePortOut0PCF8574APulse()
{
if(PinOut==0) // For output port 0 outputs
{
WriteDataPortPCF8574A(AdrDeviceOut,B11111110); // Activates output 0 -> Turn On Garage Lights.
timerID=timer.setTimeout(1000, OffPinPortOutPCF8574APulse); // Call the function OffPinPortOutPCF8574APulse After 1 second.
}
if(PinOut==1) // For output port 1 outputs
{
WriteDataPortPCF8574A(AdrDeviceOut,B11111101); // Activates output 1 -> Turn Off Garage Lights.
timerID=timer.setTimeout(1000, OffPinPortOutPCF8574APulse); // Call the function OffPinPortOutPCF8574APulse After 1 second.
}
if(PinOut==2) // For output port 2 outputs
{
WriteDataPortPCF8574A(AdrDeviceOut,B11111011); // Activates output 1 -> On/Off exterior garage lights.
timerID=timer.setTimeout(1000, OffPinPortOutPCF8574APulse); // Call the function OffPinPortOutPCF8574APulse After 1 second.
}
}
/* FUNCTION TO DEACTIVATE THE OUTPUT WE HAVE BEEN ACTIVATED PREVIOUSLY */
void OffPinPortOutPCF8574APulse()
{
WriteDataPortPCF8574A(AdrDeviceOut,B11111111);
timer.deleteTimer(timerID);
}
/* FUNCTION TO UPDATE THE LED STATUS IN BLYNK IN THE FUNCTION OF THE INPUT THAT HAS CHANGED FROM STATE */
void UpdateProgram()
{
for (int i=0;i<8;i++) // To examine each of the bits of the input port.
{
if (MirrorPinPortIn0PCF8574A[i] != TempPinPortIn0PCF8574A[i]) // I update the mirror variable, for this I determine the input
{ // Which has caused the interruption.
MirrorPinPortIn0PCF8574A[i]=TempPinPortIn0PCF8574A[i];
switch (i)
{
case 0: if (MirrorPinPortIn0PCF8574A[i]==HIGH)
{
Led0.on(); // Led State interior garage lights
Blynk.setProperty(V8,"onLabel","ENCENDER"); // button Focos Garaje
Blynk.setProperty(V8,"offLabel","APAGAR");
}
else
{
Led0.off();
Blynk.setProperty(V8,"onLabel","APAGAR");
Blynk.setProperty(V8,"offLabel","ENCENDER");
}
break;
case 1: if (MirrorPinPortIn0PCF8574A[i]==HIGH)
{
Led1.on(); // Led State exterior garage lights
Blynk.setProperty(V9,"onLabel","ENCENDER"); // button exterior garage lights
Blynk.setProperty(V9,"offLabel","APAGAR");
}
else
{
Led1.off();
Blynk.setProperty(V9,"onLabel","APAGAR");
Blynk.setProperty(V9,"offLabel","ENCENDER");
}
break;
case 2: if (MirrorPinPortIn0PCF8574A[i]==HIGH)
Led2.on(); // Led Status Detector Light Interior Garage
else
Led2.off();
break;
}
}
}
}
/* FUNCTION TO READ A PORT OF INPUTS CONNECTED TO BUS I2C /
/ Input Data: the address of the port to read /
/ Output data: returns the data read from the port */
byte ReadDataPortPCF8574A (byte device)
{
byte data;
Wire.requestFrom(device,1);
data=Wire.read();
Wire.endTransmission();
// Serial.println(data,BIN);
return data;
}
/* FUNCTION TO WRITE ON AN INPUT PORT CONNECTED TO I2C BUS /
/ Input Data: the address of the port to read, and data to write /
/ Output data: returns the data read from the port */
void WriteDataPortPCF8574A(byte device,byte data)
{
Wire.beginTransmission(device);
Wire.write(data);
Wire.endTransmission();
}
/* FUNCTION TO KNOW INITIALLY THE STATE OF THE TICKETS */
void InicializaMirrorIns()
{
byte DataPortIn;
byte InOn=B00000001;
byte InOnTemp;
DataPortIn=ReadDataPortPCF8574A(AdrPortIn0PCF8574A);
for (int i=0;i<8;i++) // To examine each of the bits of the input port.
{
InOnTemp=DataPortIn & InOn;
if(InOnTemp == InOn) // In the mirror variable " MirrorPinPortIn0PCF8574A[7]" I’m saving the last
MirrorPinPortIn0PCF8574A[i]=HIGH; // State in which the entries are found, if any changes, comparing them
else MirrorPinPortIn0PCF8574A[i]=LOW; // With this variable know that input has changed state.
InOn=InOn<<1;
}
}
/* PUSH-BUTTON TO IGNITION THE INTERIOR GARAGE LIGHTS */
BLYNK_WRITE (V8)
{
if(param.asInt()==1 && MirrorPinPortIn0PCF8574A[0]==LOW) // Turn On Interior Garage Lights.
{
Serial.println(“Focos On”);
AdrDeviceOut=AdrPortOut0PCF8574T;
PinOut=0;
UpdatePortOut0PCF8574APulse();
}
else if (param.asInt()==1 && MirrorPinPortIn0PCF8574A[0]==HIGH) // Turn Off Interior Garage Lights.
{
Serial.println(“Focos Off”);
AdrDeviceOut=AdrPortOut0PCF8574T;
PinOut=1;
UpdatePortOut0PCF8574APulse();
}
}
/* PUSH-BUTTON TO IGNITION THE EXTERIOR GARAGE LIGHTS */
BLYNK_WRITE (V9)
{
if(param.asInt()==1 && MirrorPinPortIn0PCF8574A[1]==LOW) // Turn On Exterior Garage Lights.
{
AdrDeviceOut=AdrPortOut0PCF8574T;
PinOut=2;
UpdatePortOut0PCF8574APulse();
}
else if (param.asInt()==1 && MirrorPinPortIn0PCF8574A[1]==HIGH) // Turn On Exterior Garage Lights.
{
AdrDeviceOut=AdrPortOut0PCF8574T;
PinOut=2;
UpdatePortOut0PCF8574APulse();
}
}
/* FUNCTION TO INITIALLY ESTABLISH THE STATE OF THE LEDS IN BLYNK */
void InicalizaLedsBlynk()
{
WriteDataPortPCF8574A(AdrPortIn0PCF8574A,0XFF); // To initialize the PCF8574 used as Inputs.
InicializaMirrorIns(); // Leo port entries, and I keep it in the variable MirrorPinPortIn0PCF8574A
if (MirrorPinPortIn0PCF8574A[0]==HIGH) Led0.on(); // Led State interior garage lights
else Led0.off();
if (MirrorPinPortIn0PCF8574A[1]==HIGH) Led1.on(); // Led State exterior garage lights
else Led1.off();
if (MirrorPinPortIn0PCF8574A[2]==HIGH) Led2.on(); // Led Status Detector Light Interior Garage
else Led2.off();
}
/* Function to initially set the status of Blynk buttons */
void InicalizaButtonsBlynk()
{
if (MirrorPinPortIn0PCF8574A[0]==HIGH) // PUSH-BUTTON interior garage lights
{
Blynk.setProperty(V8,“onLabel”,“ENCENDER”);
Blynk.setProperty(V8,“offLabel”,“APAGAR”);
}
else
{
Blynk.setProperty(V8,“onLabel”,“APAGAR”);
Blynk.setProperty(V8,“offLabel”,“ENCENDER”);
}
if (MirrorPinPortIn0PCF8574A[1]==HIGH) // PUSH-BUTTON exterior garage lights
{
Blynk.setProperty(V9,“onLabel”,“ENCENDER”);
Blynk.setProperty(V9,“offLabel”,“APAGAR”);
}
else
{
Blynk.setProperty(V9,“onLabel”,“APAGAR”);
Blynk.setProperty(V9,“offLabel”,“ENCENDER”);
}
}
/* MAIN PROGRAM */
void loop()
{
Blynk.run();
timer.run();
if(FlagINT==true) // There has been interruption of the input port, I update the program based on the inputs.
{
FlagINT=false;
UpdateProgram();
}
}