I have an ESP8266-12e (ESP1) that is connected to Blynk with a momentary button. When the button is activated it makes pin D5 HIGH which goes through a transistor and powers the set side of a latching relay. When this happens the relay turns the ESP1 off, and another ESP8266-12e (ESP2) on. The ESP2 runs for about 15 seconds connecting to ThingSpeak and then sets pin D5 to HIGH activating the reset side of the latching relay. This time the relay turns the ESP2 off and the ESP1 on. The set side of the latching relay can also be activated through an RF signal going through the transistor.
When the RF activates the relay with a 0.5 s signal everything works fine. The ESP1 turns off, the ESP2 turns on and goes through its code and then activates the relay. After that everything works as it should.
However, when I press the Blynk button associated with the ESP1 it doesn't turn itself off and turn the ESP2 on, but instead the blue LED on the ESP1 flashes, the latching relay doesn't engage, and the ESP1 stays on. When after about 10 s I tap the Blynk button again the ESP2 comes on and the ESP1 turns off. The ESP goes through its code and then resets the relay.
I know that when the ESP2 turns itself off it is not finishing its code, so the pin D5 is still HIGH when it is powered off. Is this what is causing the ESP1 to restart when it is supposed to turn off and the ESP2 to turn on?
Is it possible I should put a small capacitor between the ESP2's Vcc and ground so that when the latching relay turns it off there is still enough power to have the ESP2 finish its code and turn the pin D5 LOW? I would think that by being powered off it would start everything from scratch. I am posting my code for both ESPs and a schematic.
ESP1 (Blynk button code)
#define BLYNK_PRINT Serial
//NodeMCU 1.0 (ESP-12E Module constant connect)
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//NEW AUTOCONNECT
#include <FS.h> //https://github.com/esp8266/Arduino
#include <EEPROM.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>
//NEW AUTOCONNECT
const byte numChars = 32;
char receivedChars[numChars];
char Password[36]="";
char apiKey[32]="";
char apiKey2[32]="";
char channelKey[16];
char channelKey2[16];
String channelKey21= "&";
char auth[] = "";
byte pinState = LOW;
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";
WiFiClient client;
// NEW AUTOCONNECT
char defaultHost[100] = ""; // Thing Speak IP address (sometime the web address causes issues with ESP's :/
const byte wifiResetPin = 13;
int interruptPinDebounce = 0;
long debouncing_time = 1000;
volatile unsigned long wifiResetLastMillis = 0;
bool shouldSaveConfig = false;
int address = 0;
byte value;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void handleWifiReset() {
if (millis()<wifiResetLastMillis) {
wifiResetLastMillis = millis();
}
if ((millis() - wifiResetLastMillis)>= debouncing_time) {
Serial.println("Clearing WiFi data resetting");
WiFiManager wifiManager;
wifiManager.resetSettings();
SPIFFS.format();
ESP.reset();
delay(1000);
}
wifiResetLastMillis = millis();
}
int addr = 0;
//END NEW AUTOCONNECT
void setup() {
Serial.begin(115200);
pinMode(D5,OUTPUT);
digitalWrite(5, LOW);
// NEW AUTOCONNECT
WiFiManager wifiManager;
pinMode (wifiResetPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(wifiResetPin), handleWifiReset, FALLING);
WiFiManagerParameter customAPIKey("apiKey", "Authorization Code", apiKey, 32);
wifiManager.addParameter(&customAPIKey);
wifiManager.autoConnect("FloWT2");
Serial.println("Connected");
strcpy(apiKey, customAPIKey.getValue());
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["defaultHost"] = defaultHost;
json["apiKey"] = apiKey;
Serial.println("API");
Serial.println("CHANNEL");
Serial.print(apiKey);
Serial.print(channelKey);
String(apiKey2) = String(apiKey);
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(configFile);
json.printTo(Serial);
delay(1000);
configFile.close();
//end save
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
strcpy(apiKey,customAPIKey.getValue());
String(apiKey2) = String (apiKey);
Serial.println("apiKEY");
Serial.print(apiKey);
EEPROM.begin(512); // Initialize EEPROM
EEPROM.write(addr, 'A'); // Write character A
addr++; // Increment address
EEPROM.write(addr, 'B'); // Write character B
addr++; // Increment address
EEPROM.write(addr, 'C'); // Write character C
addr++; // Increment address
EEPROM.write(addr, 'D'); // Write character D
String www = apiKey2;
Serial.println("thisiswww");
Serial.print (www);
for (int i=0; i<www.length(); i++) { // loop upto string lenght www.length() returns length of string
EEPROM.write(0x0F+i, www[i]); // Write one by one with starting address of 0x0F
}
EEPROM.commit();
WiFiClient client;
EEPROM.begin(512);
Serial.println("WHAT"); // Goto next line, as ESP sends some garbage when you reset it
Serial.print(char(EEPROM.read(addr))); // Read from address 0x00
addr++; // Increment address
Serial.print(char(EEPROM.read(addr))); // Read from address 0x01
addr++; // Increment address
Serial.println(char(EEPROM.read(addr))); // Read from address 0x02
addr++; // Increment address
Serial.println(char(EEPROM.read(addr))); // Read from address 0x03
addr++; // Increment address
Serial.println(char(EEPROM.read(addr))); // Read from address 0x04
//Read string from eeprom
String uuu;
for (int i=0;i<32;i++) {
uuu = uuu + char(EEPROM.read(0x0F+i)); // Read one by one with starting address of 0x0F
}
Serial.println("this");
Serial.print(uuu); // Print the text on serial monitor
uuu.toCharArray(auth, 33);
Serial.println("auth");
Serial.print(auth);
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
}
ESP2 code
#include <ESP8266WiFi.h>
// NEW AUTOCONNECT
#include <FS.h> // https://github.com/esp8266/Arduino
#include <EEPROM.h> // needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>
// END NEW AUTOCONNECT
// String apiKey = "8RXVFOW83KRZHSNL"; pool filler
// const char* ssid = "Gary's Wi-Fi Network";
// const char* password = "Homenetwork";
const char* server = "api.thingspeak.com";
//NEW AUTOCONNECT
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
char Password[36] = "";
char apiKey[16] = "";
char apiKey2[16] = "";
char channelKey[16];
String channelKey2= "&";
// END NEW AUTOCONNECT
// DHTesp dht;
// DHTesp dht2;
// DHTesp dht3;
WiFiClient client;
// NEW AUTOCONNECT
char defaultHost[100] = ""; // Thing Speak IP address (sometimes the web address causes issues with ESP's :/
long itt = 500;
const byte wifiResetPin = 13;
int interruptPinDebounce = 0;
long debouncing_time = 1000;
volatile unsigned long wifiResetLastMillis = 0;
bool shouldSaveConfig = false;
int address = 0;
byte value;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void handleWifiReset() {
if (millis()<wifiResetLastMillis) {
wifiResetLastMillis = millis();
}
if ((millis() - wifiResetLastMillis) >= debouncing_time) {
Serial.println("Clearing WiFi data resetting");
WiFiManager wifiManager;
wifiManager.resetSettings();
SPIFFS.format();
ESP.reset();
delay(1000);
}
wifiResetLastMillis = millis();
}
int addr = 0;
// END NEW AUTOCONNECT
void setup() {
pinMode(D5,OUTPUT);
digitalWrite(D5,LOW);
// NEW AUTOCONNECT
WiFiManager wifiManager;
pinMode(wifiResetPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(wifiResetPin), handleWifiReset,FALLING);
WiFiManagerParameter customAPIKey("apiKey", "ThingSpeakWriteAPI", apiKey, 16);
WiFiManagerParameter customAPIKey2("channelKey", "ThingSpeakChannel Number", channelKey, 16);
// END NEW STUFF
// WiFiManager
// Local intialization. Once its business is done, there is no need to keep it around
// WiFiManager wifiManager;
// NEW STUFF START
// wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.addParameter(&customAPIKey);
wifiManager.addParameter(&customAPIKey2);
// END NEW STUFF
// reset saved settings
// wifiManager.resetSettings();
// set custom ip for portal
// wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
// fetches ssid and pass from eeprom and tries to connect
// if it does not connect it starts an access point with the specified name
// here "AutoConnectAP"
// and goes into a blocking loop awaiting configuration
wifiManager.autoConnect("FloWT1");
Serial.println("Connected");
// NEW STUFF START
strcpy(apiKey, customAPIKey.getValue());
strcpy(channelKey, customAPIKey2.getValue());
String chan = String(channelKey);
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["defaultHost"] = defaultHost;
json["apiKey"] = apiKey;
Serial.println("API");
Serial.println("CHANNEL");
Serial.print(apiKey);
Serial.print(channelKey);
String(apiKey2) = String(apiKey);
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(configFile);
json.printTo(Serial);
delay(1000);
configFile.close();
// end save
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
// END NEW STUFF
// or use this for auto generated name ESP + ChipID
// wifiManager.autoConnect();
// Serial.println("WriteApi");
// Serial.println(apiKey);
// if you get here you have connected to the WiFi
// Serial.println("K)");
// save the custom parameters to FS
strcpy(apiKey,customAPIKey.getValue());
strcpy(channelKey,customAPIKey2.getValue());
String( apiKey2) = String (apiKey);
Serial.println("apiKEY");
Serial.print(apiKey);
EEPROM.begin(512); // Initialize EEPROM
// write appropriate byte of the EEPROM.
// these values will remain there when the board is
// turned off.
EEPROM.write(addr, 'A'); // Write character A
addr++; // Increment address
EEPROM.write(addr, 'B'); // Write character B
addr++; // Increment address
EEPROM.write(addr, 'C'); // Write character C
Serial.print(addr,'A');
// Write string to eeprom
/*String uuu = channelKey;
for (int i=0; i<uuu.length(); i++) { // loop upto string lenght uuu.length() returns length of string
EEPROM.write(0x0F+i,uuu[i]); // Write one by one with starting address of 0x0F
}*/
String uuu = channelKey;
String www = apiKey2 + uuu;
Serial.print (www);
for (int i=0;i<www.length();i++) { // loop upto string lenght www.length() returns length of string
EEPROM.write(0x0F+i,www[i]); // Write one by one with starting address of 0x0F
}
EEPROM.commit();
// Read string from eeprom
Serial.begin(115200);
// dht.setup(D3, DHTesp::DHT11);
// dht2.setup(D6, DHTesp::DHT11);
// dht3.setup(D7, DHTesp::DHT11);
// WiFi.begin(ssid, password);
// Serial.println();
// Serial.println();
// Serial.print("Connecting to ");
// Serial.println(ssid);
// WiFi.begin(ssid, password);
// while (WiFi.status() != WL_CONNECTED) {
// delay(500);
// Serial.print(".");
// }
// Serial.println("");
// Serial.println("WiFi connected");
}
void loop() {
digitalWrite(D5,LOW);
itt = 0;
Serial.println("input");
Serial.print(itt);
// digitalWrite(D1,HIGH);
delay(1000);
WiFiManager wifiManager;
if (WiFi.status() == WL_DISCONNECTED) {
wifiManager.autoConnect("FloWT1");
}
delay(3000);
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Connected");
delay(3000);
WiFiClient client;
char defaultHost[100] = "api.thingspeak.com";
EEPROM.begin(512);
Serial.println("WHAT"); // Goto next line, as ESP sends some garbage when you reset it
Serial.print(char(EEPROM.read(addr))); // Read from address 0x00
addr++; // Increment address
Serial.print(char(EEPROM.read(addr))); // Read from address 0x01
addr++; // Increment address
Serial.println(char(EEPROM.read(addr))); // Read from address 0x02
addr++; // Increment address
Serial.println(char(EEPROM.read(addr))); // Read from address 0x03
// Read string from eeprom
String www;
// Here we don't know how many bytes to read it is better practice to use some terminating character
// Lets do it manually www.circuits4you.com total length is 20 characters
for (int i=0; i<16; i++) {
www = www + char(EEPROM.read(0x0F+i)); // Read one by one with starting address of 0x0F
}
String uuu;
for (int i=31; i<32; i++) {
uuu = uuu + char(EEPROM.read(0x0+i));
}
Serial.println("this");
Serial.print(www); // Print the text on serial monitor
Serial.println("that");
Serial.print(uuu);
String one = "&";
String two = one + "field";
String three = two + uuu;
String four = three + "=";
channelKey2 = four;
delay(3000);
delay(5000);
Serial.print(channelKey2);
if (client.connect(server, 80)) {
Serial.println("hi");
String postStr = apiKey;
Serial.print( postStr);
postStr += channelKey2;
postStr += String(itt);
Serial.print(postStr);
// postStr += "&field4=";
// postStr += String(f2);
// postStr += "&field5=";
// postStr += String(f3);
postStr += "\r\n\r\n";
Serial.println("NOW");
Serial.print(www);
Serial.println("THEN");
Serial.print(uuu);
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+String (www) + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n\n");
client.print(postStr);
Serial.println("Sending data to Thingspeak");
}
delay(2000);
digitalWrite(D5, HIGH);
Serial.println("d5HIGH");
delay(500);
client.stop();
Serial.println("Waiting 20 secs");
// thingspeak needs at least a 15 sec delay between updates
// 20 seconds to be safe
}
}
If placing the capacitors would help, what size should they be? The ESP-12e uses around 100 mA at 3.3 V.
With the example that was suggested there is a possibility to put the capacitor before the voltage regulator. In my case the voltage regulator is before the relay that cuts the power to the ESPs, so the capacitor wouldn't be able to supply the power to the ESPs.
- Will a capacitor solve the problem?
- Do capacitors store voltage or current? If voltage then I need to have a 3.3 V capacitor of ? μF. If current only is stored then what size would I need? I did an experiment and found the first time the ESP1 fires there is a small amount of current going to the ESP2 for a split second. I suppose I could just try a capacitor to the ESP2 and see. I just don't want to burn it. Maybe a 25 V at 1000 μF; is that too big? I am not an EE and need some guidance.