2
\$\begingroup\$

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.

  1. Will a capacitor solve the problem?
  2. 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.

Updated schematic

\$\endgroup\$
9
  • 2
    \$\begingroup\$ Does this answer your question? Keeping NodeMCU operating with a super capacitor \$\endgroup\$ Apr 12, 2020 at 17:05
  • \$\begingroup\$ So I'm thinking a 3000uf 3.3v super capacitor will charge up enough in 15 seconds to power a 3.3v ESP-12e at 100mA for .5 seconds. Does anyone have a comment on this? \$\endgroup\$ Apr 13, 2020 at 1:27
  • \$\begingroup\$ It looks to me like that will give you about 10ms of running time. Can you show your math? \$\endgroup\$ Apr 13, 2020 at 11:54
  • \$\begingroup\$ I was trying to figure it out but apparently got confused and off. Can you provide me with a formula to do this? AND do you think this is the problem and will solve the problem. \$\endgroup\$ Apr 13, 2020 at 14:10
  • \$\begingroup\$ The formula you are looking for is \$i = C\frac{dV}{dt}\$. I don't know whether this will solve the problem or not, there are just too many variables and not enough information. It would help if you added schematics and looked at your voltages with an oscilloscope. \$\endgroup\$ Apr 13, 2020 at 15:34

1 Answer 1

1
\$\begingroup\$

So by changing the code on the Reset ESP so that it disconnected from wifi before it turned on pin D5, everything now works great. Every time RF or Blynk ESP send a signal to relay it activates the set side and the Reset ESP runs and activates the Reset ESP 1st time every time. It is the code shown in the Reset ESP code above at the end.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.