Wifimanager + blynk

HI! im working in a project where i want to connect to a SSID wifi and put a Blynk Token so i can get notifications and so on.

The thing is that everything works fine the first time. If i reboot the Wemos D1 mini the blynk token fails to valid the auth and i get the error (Invalid auth token).

Maybe the FS is not saving the token or anything.

I paste my code below.

Anyone can help?

Thanks a lot in advance.

#include <ESP8266WiFi.h>
#include <DHT.h>

//needed for WiFiManager library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

#include <ArduinoJson.h>

#define BLYNK_PRINT Serial    
#include <BlynkSimpleEsp8266.h>

#define DHTTYPE DHT11
#define DHTPIN D4     // D2 fisical pin

DHT dht(DHTPIN, DHTTYPE);

const int sensorPin = A0;

//define your default values here, if there are different values in config.json, they are overwritten.
char mqtt_server[40] = "blynk-cloud.com";
char mqtt_port[6] = "8080";
char blynk_token[33] = "your-token"; 

//flag for saving data
bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();

  Serial.println("********************");
  Serial.println("DHT11");
  dht.begin();

  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.println(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" *C ");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.println(" *C ");

  Serial.println("********************");
  Serial.println("SENSOR HUMEDAD");
  int sensorValue = analogRead(0);

  // ver bien el mapeo, no funciona bien
  // hay que mapear 1024 a 0 para tener el valor mas bajo
  Serial.print("Moisture Sensor value: ");
  sensorValue = map(sensorValue, 0, 1023, 1023, 0);
  Serial.print(sensorValue);
  Serial.println(" %\t");

  Serial.println("Publishing to Blynk...");
  Blynk.virtualWrite(V0, sensorValue);
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
  Blynk.run();

  Serial.println("********************");
  Serial.println("BLYNK");
  Serial.println("Waiting...");
  delay(10000);

  // WIFIMANAGER CONFIGS
  //clean FS, for testing
  SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");

          strcpy(mqtt_server, json["mqtt_server"]);
          strcpy(mqtt_port, json["mqtt_port"]);
          strcpy(blynk_token, json["blynk_token"]);

        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read

  // The extra parameters to be configured (can be either global or just in the setup)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length
  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 33);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  //set static ip
  //wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  //add all your parameters here
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_mqtt_port);
  wifiManager.addParameter(&custom_blynk_token);

  //reset settings - for testing
  //wifiManager.resetSettings();

  //set minimu quality of signal so it ignores AP's under that quality, defaults to 8%
  //wifiManager.setMinimumSignalQuality(30);

  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  //fetches ssid and pass from eeprom and tries to connect
  //if it does not connect it starts an access point with for auto generated name ESP + ChipID, no password
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect()) {
    Serial.println("FallĂ´ al conectar WiFi :( ");
    delay(3000);

    Serial.println("********************");
    Serial.println("DEEP SLEEP");
    Serial.println("Deep Sleep on...");
    Serial.println("********************");
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    //ESP.deepSleep(60e6); // 60 segs
    //ESP.deepSleep(1.08e+10); // 3 horas
    //ESP.deepSleep(2.16e+10); // 6 horas
    delay(100);
  }

  //if you get here you have connected to the WiFi
  Serial.println("Wifi Conectado!: ");

  //read updated parameters
  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(mqtt_port, custom_mqtt_port.getValue());
  strcpy(blynk_token, custom_blynk_token.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config...");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["mqtt_server"] = mqtt_server;
    json["mqtt_port"] = mqtt_port;
    json["blynk_token"] = blynk_token;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  Serial.println("\nlocal ip:");
  Serial.println(WiFi.localIP());

  //still not connected to the Blynk server yet
  //it will try to connect when it reaches first Blynk.run() or Blynk.connect() call
  Blynk.config(custom_blynk_token.getValue(), custom_mqtt_server.getValue(), atoi(custom_mqtt_port.getValue()));

  //to get the status of connection to Blynk Server use:
  bool result = Blynk.connected();

}

void loop() {

  Blynk.run();

}

If you don’t comment this line out then your SPIFFS storage will be reformatted every time the device boots, erasing the stored Auth code.

Pete.

This will erase the credentials stored in SPIFFS every time you restart the device. You need to remove this from setup.

Create a separate function with SPIFFS.format(); to clear the credentials ( on demand portal ) .

Ok, thanks for the responses.

If i comment or remove that line SPIFFS.format() i get this output from the monitor and it doesn’t connect propperly.

local ip:
192.168.1.238
[19215]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ / '/
/
//_, /////_
/
__/ v0.6.1 on ESP8266

*WM: freeing allocated params!
[19231] Connecting to :8080
pm open,type:2 0
[24232] Connecting to :8080
[29233] Connecting to :8080
[34234] Connecting to :8080
[40400] Connecting to ⸎⸎⸎⸎⸎⸎⸎:8080

Your code structure is very odd.
Taking temperature reading in void setup (which executes just once), trying to send reading to Blynk before you are connected, etc.

Do you really need to use WiFiManager rather than hard-coding your with code?

Pete.

Ok…the thing is i will be using Deep Sleep after and i need to declare all in the void setup. But that is not a problem now and the code works fine just once.
The hard-coding is not an option because i want to share this project between people and i need something friendly to use. Imagine hard-code every setting for people that i dont know…

Wifi manager is a great option and also the embedded blynk library. I need to use this.

I’ve read that this issue is very common between users here in the forum.

Thanks a lot!

So is this going to be a semi-commercial project? Choosing the DHT11 sensor isn’t a good choice if it is.

Is the system going to be battery powered?
The thing about deep sleep is that you really want the device to be awake for the absolute minimum time period, otherwise you’re defeating the point of doing deepsleep. I’d expect your wake time to be somewhere between 5 and 10 seconds if the code is written well.
Your code contains a 10 second delay, and a several other delays that should be avoided.
You also have a ‘return’ command in your void setup, which isn’t good coding practice. There is nothing to prevent you calling functions when using deepsleep, in fact it’s the approach that I prefer as it makes code structuring much simpler.

If you search the forum for “Beehive Connected” you’ll find a much better way to structure deepsleep code. It doesn’t contain any Wifimanager functionality, but it would be a much better starting point than the code you are currently using.

Pete.

Ok as i said, i need help with the Blynk embedded library, i will choose later the deep sleep function and how to make it work properly, maybe i not even use it. Now i need the blynk issue to get it resolved because i know is not so difficult to make it work.

The code is not perfect, that is normal. My doubt is that it works ok the first time and the second time don’t, that is because the token is not well saved on the FS or anything im missing out.

Regards.

Dou didn’t answer the question about whether or not this will be a semi-commercial project, because understanding that will influence the best approach to take. here are alternatives to Wifimanager, including Blynk’s own dynamic provisioning system, and knowing how the system will be used and supported will influence/inform the best choice of which way to go.

Pete.

I think there is no different really, what other alternatives there are depending on if there is a semi-commercial or not?. Based on your experience what is the best option with a non-hard-coded code?.

There are lots of differences, but if you’re not prepared to elaborate then I’m not going to take the time to go through the various options and the pros and cons to each.

Pete.

I don’t understand the etic of the forum. It is suppose to help other people and not offend them. Your answer is not the best and it doesn’t help to other people to investigate and research their own answers. Answer “you are not prepared…” is very unpolite and offended.

I’m an electronic-arduino enthusiastic person with a lot of time to learn and make mistakes, anyone will not tell me how to make my own mistakes and correct them.
I help other people in a lot of forums and when anyone doesn’t know anything i help them.

Best.

WifiManager works well for the “non-hard-coded” option. As to why it is not working well for you, I do not know. I have used it successfully many times on many projects. If I were you I would start with the basic version of the WifiManager AutoConnectWithFSParameters example, and make sure it is working correctly. I would not change anything from the example except adding the BLYNK libraries and basic necessary code for BLYNK (in the appropriate places of coarse). Also, make sure you are running the correct version of the ArduinoJson Library or it will not compile (unless you make the needed syntax changes for the latest version of the ArduinoJson library).

One thing that I notice from the code you had posted is that you are missing #include <FS.h> //this needs to be first, or it all crashes and burns... at the very top of the code. Whether this was due to a copy and past error, or it is actually missing, I do not know.

Ok…first…WifiManager alone works well, it connects, it reconnects, and works great. There is a library with the Blynk embedded which also works ok, but it fails if disconnect the device (arduino wemos d1) and the blynk part just cant valid the token again. So i think there is a problem storing the token or anything.

I missed the #include <FS.h> but i have it in my code…thanks for that!.

I don’t know what is the issue with the token reconnection.

You asked what alternatives there are to hard coding your Blynk/Wifi Parameters, to which the reply was this all depends on how you plan to use/distribute the device.

I think what your are not understanding is that based on how this device will be used/distributed will depend on what solution is recommended.

I could write pages upon pages of information about the various credentials management/provisioning options available to you, plus options for remote firmware updates.
I’m not going to take the time to do that, if you aren’t prepared to give me a steer on whether or not this will be a semi-commercial project and how it will be supported.

If you want my time and knowledge for free then you have to provide sufficient background detail to make my like a little easier - the choice is yours.

Pete.

The project is semi-commercial but now im going to test it at home. I choose to accept your help but you have to understand the skills of the users that publish here. There are people who have great skills and others who dont.

So, what do you suggest about the blynk issue? what is wrong there and i want to understand what is it fail on reconnect?.

Here is a basic example. This works for me. Using ArduinoJson 5.13.5

I do not use mqtt server or port so those portions have been commented out.

#include <FS.h>                   //this needs to be first, or it all crashes and burns...

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <BlynkSimpleEsp8266.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson

//define your default values here, if there are different values in config.json, they are overwritten.
//char mqtt_server[40];
//char mqtt_port[6] = "8080";
char blynk_token[34] = "YOUR_BLYNK_TOKEN";

//flag for saving data
bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();

  //clean FS, for testing
  //SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");

          //strcpy(mqtt_server, json["mqtt_server"]);
         //strcpy(mqtt_port, json["mqtt_port"]);
          strcpy(blynk_token, json["blynk_token"]);

        } else {
          Serial.println("failed to load json config");
        }
        configFile.close();
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read



  // The extra parameters to be configured (can be either global or just in the setup)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length
  //WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  //WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  //set static ip
  //wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
  
  //add all your parameters here
  //wifiManager.addParameter(&custom_mqtt_server);
  //wifiManager.addParameter(&custom_mqtt_port);
  wifiManager.addParameter(&custom_blynk_token);

  //reset settings - for testing
  //wifiManager.resetSettings();

  //set minimu quality of signal so it ignores AP's under that quality
  //defaults to 8%
  //wifiManager.setMinimumSignalQuality();
  
  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  //fetches ssid and pass 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
  if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
    Serial.println("failed to connect and hit timeout");
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(5000);
  }

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");

  //read updated parameters
  //strcpy(mqtt_server, custom_mqtt_server.getValue());
  //strcpy(mqtt_port, custom_mqtt_port.getValue());
  strcpy(blynk_token, custom_blynk_token.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    //json["mqtt_server"] = mqtt_server;
   // json["mqtt_port"] = mqtt_port;
    json["blynk_token"] = blynk_token;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

 while (WiFi.status() != WL_CONNECTED) {
       int mytimeout = 5;
       delay(500);
       Serial.print(".");
       if((millis() / 1000) > mytimeout ){ // try for less than 6 seconds to connect to WiFi router
         Serial.println(" ");
          break;
        }
   }

   if(WiFi.status() == WL_CONNECTED){  
    //if you get here you have connected to the WiFi
   Serial.println(" ");
   Serial.println("connected to WiFi!! yay :)");
   Serial.println("IP address: ");
   Serial.println(WiFi.localIP()); 
 
 
  Blynk.config(blynk_token);
  bool result = Blynk.connect();

  if (result != true)
  {
  Serial.println("BLYNK Connection Fail");
  Serial.println(blynk_token);
  wifiManager.resetSettings();
  ESP.reset();
  //delay (5000);
  }
  else
  {
  Serial.println("BLYNK Connected!! Yay again");
  }
 }
 else if (WiFi.status() != WL_CONNECTED){
  Serial.println("WiFi Connection Fail");
 } 

}

void loop() {
  // put your main code here, to run repeatedly:
Blynk.run();

}

Okay, in that case you really need to use the Blynk provisioning features.
Any type of commercial project requires a paid subscription to Blynk, and the Blynk developers will assist you in setting-up a project that is supportable by them - hence why the Blynk provisioning functionality rather than an unsupported system like WifiManager would almost certainly be their preferred choice of credentials management/provisioning.

Using the free version of Blynk to prototype the functionality and develop a PoC of the project is a good way to go, but using the correct tools is important. Opening a dialogue with the guys at Blynk.io, or directly with @Pavel, at an early stage in the project’s development is a the best idea because they will be able to point you in the right direction.

Pete.

Thanks! it works ok, apparently there are some lines that i didn’t have in my code.