Цикл While в Blynk.begin, Blynk.connectWiFi, Blynk.connect

Доброго времени суток!
Простите, что по-русски, так проще подробно изложить суть проблемы.
Если я правильно понимаю, в библиотеках BLYNK при вызове Blynk.begin () или же Blynk.connectWiFi и Blynk.connect () используется цикл While, т.е. контроллер перестаёт обрабатывать всю остальную часть программы до тех пор, пока не будет установлена связь с роутером (Blynk.connectWiFi) или с сервером (Blynk.connect).
Но проблема в том, что у меня контроллер должен выполнять еще массу других задач, которые не могут быть отложены до подключения к роутеру или серверу, т.к. эти задачи более важны чем подключение к сети. Т.е. сам факт того, что контроллер может в какой-то момент “уйти” в цикл и приостановить выполнение программы меня сильно беспокоит - это принципиально… Если, к примеру, я управляю нагревательным элементом, и в тот момент, когда его пора выключить, контроллер зависает так как пытается подключиться к роутеру или серверу - это недопустимо… Конечно сработает дополнительная защита по перегреву, но в принципе такая работа контроллера неприемлема…
Пытаюсь понять: использование While в библиотеке принципиально? Т.е. неужели нельзя подключаться к сети и серверу периодически, не заводя контроллер в цикл и “зависание” остальной части программы?
Простите за наверно бестолковое объяснение и формулировки, увы я не дружу с кодом, пытаюсь объяснить своими словами…)
Спасибо за помощь!

Добрый день!

Может быть, в таком случае, Вам стоит переложить логику и задачи коммуникации с внешнем миром на другой, дополнительный, контроллер

В документации описаны методы контроля над подключением к облаку:

Https://docs.blynk.cc

В разделе Firmware API

Если Вы имеете ввиду раздел BLYNK FIRMWARE, то я его читал.
Я использую Blynk.config() и Blynk.connectWiFi() - если нет связи с роутером, то контроллер зависает… Если пытаться подключиться Blynk.connect() и нет выхода в интернет, то контроллер тоже висит…
А раздела Firmware API я там не нахожу…

Добрый день.
Это конечно выход, я и сам это понимаю. Но это, как по мне, немного странно)) Неужели нельзя реализовать все одним контроллером без использования While… Контроллеру памяти предостаточно чтоб все обрабатывать.

Только вы там не сказали какой контроллер используете, проблема с зависание решается таймаутом по времени, ну и вы код не показали так что гадать тут бесполезно.

Контроллер WeMos D1.
Код вот такой, для примера.

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "YourAuthToken";

char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";

void setup()
{
Blynk.config(auth);
Blynk.connectWiFi(ssid, pass);
Blynk.connect()
}

void loop()
if (Blynk.connected())
{
  Blynk.run();
}

Вместо Blynk.begin() я использую Blynk.config() и Blynk.connect().
И Blynk.run() выполняю только при условии соединения с сервером - так как прочитал тут на форуме.
Я не понимаю как именно решить проблему с зависанием “таймаутом по времени”…

В define ставите BLYNK_TIMEOUT_MS и число в миллисекундах, по умолчанию вроде 30 секунд стоит, ваш пример не правильный соединяется только один раз в setup нужен таймер и функция для переподключения.

Нашёл часть кода, где это реализовано, только я не пойму что за функция static void timerReconnect(void); ?

  #define BLYNK_PRINT Serial

  #include <ESP8266WiFi.h>
  #include <BlynkSimpleEsp8266.h>

  bool triggerBlynkConnect = false;
  bool isFirstConnect = true; // Keep this flag not to re-sync on every reconnection

  // You should get Auth Token in the Blynk App.
  // Go to the Project Settings (nut icon).
  char auth[] = "YourAuthToken";

  // Your WiFi credentials.
  // Set password to "" for open networks.
  char ssid[] = "YourNetworkName";
  char pass[] = "YourPassword";

  // Оголошення таймеру
  BlynkTimer timer;

  static void timerReconnect(void);

  void setup()
  {
    // Debug console
    Serial.begin(115200);

    // Конфігуруємо підключення до blynk server
    Blynk.config(auth);
    
    //Під'єднуємось до WiFi мережі
    Blynk.connectWiFi(ssid, pass);

    if (WiFi.status() == WL_CONNECTED)
    {
      if (Blynk.connect())
      {
        triggerBlynkConnect = true;
      }
      else
      {
        triggerBlynkConnect = false;
      }
    }

    timer.setInterval(60000L, timerReconnect);
  }

  void loop()
  {
    if (Blynk.connected())
    {
      Blynk.run(); // Initiates Blynk Server  
    }
    else
    {
      triggerBlynkConnect = false;
    }

    timer.run(); // Initiates BlynkTimer
  }

  BLYNK_CONNECTED()
  {
    triggerBlynkConnect = true;

    Serial.println(F("Blynk Connected!"));
    Serial.println(F("local ip"));
    Serial.println(WiFi.localIP());

    if (isFirstConnect)
    {       
      Blynk.syncAll();    

      isFirstConnect = false;
    }
  }

  static void timerReconnect(void)
  {
    if (WiFi.status() != WL_CONNECTED)
    {
      Serial.println(F("WiFi not connected"));
      
      Blynk.connectWiFi(ssid, pass);
    }
    else
    {
      Serial.println(F("WiFi in connected"));
    }

    if (!Blynk.connected() && WiFi.status() == WL_CONNECTED)
    {
      if (Blynk.connect())
      {
        Serial.println(F("Blynk reconnected"));
      }
      else
      {
        Serial.println(F("Blynk not reconnected"));
      }
    }
    else
    {
      Serial.println(F("Blynk in connected"));
    }
  }

тут нет особого смысла использовать static, главное чтобы имя функции было уникальным

Спасибо! Буду разбираться…

на ютубе есть много уроков по С++ даже на русском языке, смотрите и набирайтесь опыта.

Я все таки не могу понять необходимости использования While…
К примеру, я использую FLProg, там есть настройка для подключения ESP8266 в качестве клиента (код ниже). И при подключении (и переподключении), а также при пропадании сигнала от роутера плата не зависает - она не зависает никогда, просто если появился сигнал - переподключается.
Если же использовать функцию Blynk.connectWiFi();, то при отсутствии сигнала от роутера плата зависает…
Не понимаю :slightly_frowning_face:
Вот как подключается к роутеру FLProg:

#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h";
}
bool ESP8266ControllerWifiClient_HRD = 0;
bool ESP8266ControllerWifiClient_status = 1;
bool ESP8266ControllerWifiClient_isDHCP = 1;
bool ESP8266ControllerWifiClient_IsNeedReconect = 0;
bool ESP8266ControllerWifiClient_workStatus = 1;
char ESP8266ControllerWifiClient_SSID[40] = "WiFi_Service";
char ESP8266ControllerWifiClient_password[40] = "46804680";
IPAddress ESP8266ControllerWifiClient_ip(0, 0, 0, 0);
 IPAddress  ESP8266ControllerWifiClient_dns (0, 0, 0, 1);
 IPAddress  ESP8266ControllerWifiClient_gateway (0, 0, 0, 1);
IPAddress ESP8266ControllerWifiClient_subnet (255, 255, 255, 0);
 uint8_t ESP8266ControllerWifiClient_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
void setup()
{
WiFi.mode(WIFI_STA);
_esp8266WifiModuleClientReconnect();
}
void loop()
{if(ESP8266ControllerWifiClient_IsNeedReconect) {_esp8266WifiModuleClientReconnect(); ESP8266ControllerWifiClient_IsNeedReconect = 0; }
ESP8266ControllerWifiClient_status = WiFi.status() == WL_CONNECTED;
if (ESP8266ControllerWifiClient_status) { if ( ! ESP8266ControllerWifiClient_HRD) { ESP8266ControllerWifiClient_ip =  WiFi.localIP();
ESP8266ControllerWifiClient_subnet =  WiFi.subnetMask();
ESP8266ControllerWifiClient_gateway =  WiFi.gatewayIP();
ESP8266ControllerWifiClient_dns =  WiFi.dnsIP();
WiFi.macAddress(ESP8266ControllerWifiClient_mac);
ESP8266ControllerWifiClient_HRD = 1;
}} else {ESP8266ControllerWifiClient_HRD = 0;}





//Плата:1
//Наименование




}
bool _isTimer(unsigned long startTime, unsigned long period )
  {
  unsigned long currentTime;
currentTime = millis();
if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}
  }
int hexStrToInt(String instring)
{
  byte len = instring.length();
  if  (len == 0) return 0;
  int result = 0;
  for (byte i = 0; i < 8; i++)   // только первые 8 цыфар влезуть в uint32
  {
    char ch = instring[i];
    if (ch == 0) break;
    result <<= 4;
    if (isdigit(ch))
      result = result | (ch - '0');
    else result = result | (ch - 'A' + 10);
  }
  return result;
}
 void _esp8266WifiModuleClientReconnect()
{
 if( _checkMacAddres(ESP8266ControllerWifiClient_mac)) {  wifi_set_macaddr(0, const_cast<uint8*>(ESP8266ControllerWifiClient_mac));}
if( ESP8266ControllerWifiClient_isDHCP) { WiFi.config(0U, 0U, 0U, 0U, 0U); } else { 
WiFi.config(ESP8266ControllerWifiClient_ip, ESP8266ControllerWifiClient_gateway, ESP8266ControllerWifiClient_subnet, ESP8266ControllerWifiClient_dns , ESP8266ControllerWifiClient_dns );
}
 WiFi.begin(ESP8266ControllerWifiClient_SSID, ESP8266ControllerWifiClient_password);
}
bool _checkMacAddres(byte array[])
{
  bool result = 0;
  for (byte i = 0; i < 6; i++)
  {
    if (array[i] == 255) {
      return 0;
    }
    if (array[i] > 0 ) {
      result = 1;
    }
  }
  return result;
}

Наверное это потому что блинк это не софт для контроля вайфая, а софт для общения с сервером. Вам ничего не мешает написать свой код по управлению вайфая который покроет ваши нужды. Все библиотеки уже существуют.

Согласен. Я уже занимаюсь этим :slightly_smiling_face:

Здравствуйте. У кого будет такая проблема в будущем я отвечу. Просто есть косяк в бибилиотеке: Если нет подключения то ждать и всё

[Unformatted code removed by moderator]

И просто указываете эту функцию в void loop(), а в аргументе указываете время проверки.
Всё. Удачи.

@Tsybulko please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Pete.

Здравствуйте!
Проблема присутствует. Поделитесь решением, модератор удалил код из Вашего поста.

User @Tsybulko hasnt visited the forum since 19th July 2021

This was the code he posted - with triple backticks added by me so that it displays correctly…

Здравствуйте. У кого будет такая проблема в будущем я отвечу. Просто есть косяк в бибилиотеке: Если нет подключения то ждать и всё

while (WiFi.status() != WL_CONNECTED) {
BlynkDelay(500);
}

Я исправил это своей фунцией Blynk_Net_Conector:

int Blynk_Net_Conector(uint32_t Blynk_TimeOut) {
if (millis() - Blynk_Timer >= Blynk_TimeOut) {
Blynk_Timer = millis();
if (WiFi.status() == WL_CONNECTED && flaga == 0) {
Blynk.begin(auth, ssid, pass);
flaga = 1;
} else if (WiFi.status() != WL_CONNECTED && flaga == 1) flaga = 0;
}
return Blynk_TimeOut;
}

И просто указываете эту функцию в void loop(), а в аргументе указываете время проверки.
Всё. Удачи.

Pete.

The real solution to this issue is to manage your own WiFi connection (don’t use Blynk.connectWiFi()) and use Blynk.config() and Blynk.connect(optional timeout in ms) and perform a Blynk.connected() test in the void loop(), and only execute Blynk.run() if Blynk.connected() == true.

There’s an example here.

Pete.

1 Like