Need help with Blynk Project with devices that randomly go offline

I was asking since we connect a blynk.edgent program to the wifi through the mobile app, can we connect it directly through the firmware as well by setting ssid and password information?

But that question diverts from the main topic. What could be possible reasons for it disconnecting now? I don’t have any blockers in the code now and everything is running on timers. Any further recommendations on what to try next or what could be causing the device to randomly go offline?

Thank you.

Those details are stored in EEPROM on the device. Do you have a method to write this configstore data as part of this process?

TBH, its very difficult to un-pick your code, as there isn’t much in the way of in-code comments. Enabling and disabling timers in this way isn’t my favourite approach, as it is difficult to follow at the best of times.

A couple of observations

By default, Serial2 on the ESP32 is on pins 16 & 17. You are using pins 13 & 12, but pin 12 is a potentially problematic pin. If it’s pulled HIGH at boot, the board won’t go in to run mode, instead it will sit in programming code, awaiting code to be uploaded.
As the Edgent sketch has a routine which will do an ESP.restart if it can’t connect to WiFi or Blynk, its possible that the board is being placed into programming mode on these restarts by the sensor connected to pin 12.

Also, have you tried commenting-out the uploadData process? It’s possible that this is interfering with the Blynk communications.
If you’re doing an HTTPS API call then these can be quite slow. Have you put some serial print statements in there to see exactly how long this function takes to complete?

Blynk has a Webhook function which allows the Blynk server to make the API call for you, rather than doing it directly from the board, but before you start investigating that I’d do some experimenting with timings and se if it still goes offline with the API call disabled.

Pete.

I did not know that about pin 12, that was good information. The sensor I have connected to doesn’t send any data until I write the character ‘P’ to it. Is it still possible for that sensor to pull that pin high on boot without receiving a ‘P’?

What I have done right now is uploaded a blank edgent template which just has edgent.run and edgent.begin functions to one of the devices to see if it stays online. Then I can enable one module at a time to see which one causes the disconnects. If it is truly their network disconnecting my devices or blocking me, then I would know from the disconnect on the blank edgent template on that device. This will be a bit of a slow process, but will help me get a solution remotely.

I have Serial.print functions but have not logged the times before. What is the max time a process should take to be considered a blocker? I know if it’s longer than 10 seconds, Blynk considers the device offline.

Yes. Even pulling the pin top an intermediate “floating” state can be enough to prevent booting.

Good idea.

Anything that’s approaching 10 seconds is potentially a worry.

In this topic, I was doing some tests of HTTP versus HTTPS calls to the Blynk server to use the Blynk API as a method of transferring data between devices (like the old Bridge functionality in Legacy).
As you’ll see, HTTPS API calls could take between 2.5 and 40+ seconds, whereas HTTP API calls were taking sub 100ms…

The delays come from the negotiation/authentication process necessary with HTTPS connections.

Pete.

1 Like

It’s possible if the internet is slower than in my office + the other 100s of devices connected to their network taking up bandwidth could cause the API calls to take longer to process. How do I get the data to the Blynk cloud and then to my servers? From what I saw, webhooks are only for change in user information.

Also, isn’t it unsecure to send data with HTTP protocol? But I’m guessing Blynk allows it for faster communication like what you showed in your tests?

Not sure I understand the question, especially not the “change in user information” bit.

Have you read the webhook docs?…

Yes, of course, but not all hardware or environments allow HTTPS Comms.

Pete.

I saw the trigger events on the docs and they only specify trigger events as changes in users within the org. It doesn’t say anything about sending data as webhooks from sensors or peripherals connected to the devices.
image

But I took a look at an actual webhook implementation within the console and it says device datastreams

If you change from GET to POST then you’ll see how you can build a JSON or plain text command with data inserted from virtual pin values etc.

Pete.

BlynkEdgent.h has indeed replaced the above functions and U can ignore the above statements

1 Like

It turns out, that the device I uploaded with this code went offline as well. It could still be the issue with pin 12 since the device is connected to the sensor, but why would the device restart randomly if the network connection is good? Is there any way for me to remotely check if the pin is the issue without me having to tell someone over there to remove the wiring?

#define BLYNK_TEMPLATE_ID ""
#define BLYNK_DEVICE_NAME ""
#define BLYNK_FIRMWARE_VERSION        "1.1.2"
//#define RXD2 13
//#define TXD2 12
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "BlynkEdgent.h"
#define APP_DEBUG

// Uncomment your board, or configure a custom board in Settings.h
#define USE_WROVER_BOARD
//#define USE_TTGO_T7
const char* serverSensyr = "";
const int port = 443;
WiFiClientSecure client;
BlynkTimer timer;

//Sensyrtech Certification

const char* ca_cert = \
                     "-----BEGIN CERTIFICATE-----\n" \

                      "-----END CERTIFICATE-----\n";


int incomValue = 0;
int conn;
float weightBufferVal = 0.6; // This is how much the weight needs to change to be considered unstable within the sampling rate
int sampleRate = 1000; // The sample rate defines how often we sample weight to see unstable data or a change in bucket
int startStabilityIncr = 30; // This is how many increments of seconds the weight has to be stable for the program to start
int transmissIncr = 1; // how often will we transmit to the cloud in increments of realSampleIncr
int realSampleIncr = 60000;
float realBufferVal = 2;// This is how different the values have to be in proper sampling to be considered unstable
float lastWeight;
float currentWeight;
float weightSum;
String body;
int body_len;
String weightSensID = "";
String signalID = "";
int stableState = 0;//0 is unstable weight, 1 is stable weight
int stableCount = 0;
float startLastWeight = -1;
float startCurrentWeight;
int checkWeightID,stabilizationWaitID, unstableDataUploadID;
void setup()
{
//  Serial.begin(115200);
 // delay(100);

  BlynkEdgent.begin();
  //Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  //Serial.println("Starting weight tracking");
  /*client.setCACert(ca_cert);
  timer.setTimeout(3600000L, [] () {} );
  checkWeightID = timer.setInterval(60000L, checkWeight);
  stabilizationWaitID = timer.setInterval(1000L, stabilizationWait);
  unstableDataUploadID = timer.setInterval(600000L, unstableDataUpload);
  delay(100);*/

  //Make sure when the device is booted up first, it finds a valid value and then moves forward with the program and loops endlessly until
 // timer.disable(checkWeightID);

}

void loop() {
  BlynkEdgent.run();
  //timer.run();
}

/*void unstableDataUpload ()
{
  uploadData(weightSensID, 0);
  uploadData(signalID, -1);
}

void checkWeight()
{
  Serial.print("Actual Current Weight: "); Serial.println(getWeight());
  currentWeight = getWeight();
  Serial.print("Current Weight: "); Serial.println(currentWeight);
  if (abs(currentWeight - lastWeight) > realBufferVal || currentWeight == -1)
  {
    timer.enable(stabilizationWaitID);
    timer.disable(checkWeightID);
    timer.enable(unstableDataUploadID);
  }
  else
  {
    Serial.println("Starting to send data");
    weightSum = lastWeight - currentWeight;
    if (weightSum >= 0)
    {
      if (weightSum <= 0.3)
      {
        weightSum = 0;
      }
      else
      {
        lastWeight = currentWeight;
      }


      Serial.print("Weight Sum: " ); Serial.println(weightSum);
      uploadData(weightSensID, weightSum);
      uploadData(signalID, currentWeight);
    }
    else
    {
      Serial.println("Weight difference is too small to account for");
    }
  }

}

float getWeight ()
{
  int weight [14];
  String strWeight;
  float dWeight = -1;
  Serial2.print('P');
  if (Serial2.available() > 0) {
    for (int i = 0; i < 14; i++)
    {
      weight[i] = Serial2.read();
      strWeight.concat(char(weight[i]));
      Serial.print(char(weight[i]));
      delay(10);
    }
    Serial.println("");
    if (strWeight.indexOf('l') > 0)
    {
      Serial.println("");
      dWeight = strWeight.toFloat();
      Serial.println(dWeight);
    }

  }
  return dWeight;
}
// Wait for the weight to become stable before continuing on with the program.
void stabilizationWait()
{
  startCurrentWeight = getWeight();
  if ( startCurrentWeight == -1)
  {
    stableCount = 0;
  }
  else if (abs(startCurrentWeight - startLastWeight) > weightBufferVal)
  {
    startLastWeight = startCurrentWeight;
        stableCount = 0;

  }
  else
  {
  stableCount++;
  startLastWeight = startCurrentWeight;
  }
  Serial.print("Second of Stability: "); Serial.println(stableCount);
  if (stableCount == 30)
  {
    Serial.println("Weight Stabilized");
    timer.disable(stabilizationWaitID);
    timer.enable(checkWeightID);
    timer.disable(unstableDataUploadID);
    lastWeight = getWeight();
  }

}


void uploadData(String sensorID, int val)
{
  String sensorStr;
  int sensorStrLen;
  sensorStr = "";
  Serial.println(sensorStr);
  sensorStrLen = sensorStr.length();
  Serial.println(".....");
  Serial.println(); Serial.print("For sending parameters for off state, connecting to "); Serial.println(serverSensyr);
  conn = client.connect(serverSensyr, port);

  if (conn == 1) {
    Serial.println(); Serial.print("Sending Parameters...");
    //Request
    client.println("POST  HTTP/1.1");
    //Headers
    client.print("Host: "); client.println(serverSensyr);
    client.println("Authorization: bearer ");
    client.println("Content-Type: application/json");
    client.print("Content-Length: "); client.println(sensorStrLen);
    client.println("Connection: Close");
    client.println();
    //Body
    client.println(sensorStr);
    client.println();
  } else {
    Serial.println("Connection Failed");
  }
  client.stop();

}
*/

Not really.

Pete.