неділю, 8 липня 2018 р.

Blynk: контроль підключеннями до серверу Blynk та мережі WiFi

update 25.12.2020: написав нову статтю на цю тему плюс відео: "Blynk: підключення до точки WiFi та серверу Blynk, очікування WiFi точки, перепідключення до WiFi та серверу Blynk, робота основного коду без блокування при очікування з'єднання для ESP32/ESP8266"

Передмова

Надихнуло на написання цієї статті це відео з каналу "Інженерка" - рекомендую.

Коли справно працює ваша мережа WiFi, безперебійний доступ до інтернету, та доступ до серверу Blynk, то й немає ніяких проблем з пристроєм який виконує свій функціонал в парі з системою Blynk. Але коли нештатна ситуація з підключенням, при увімкнені пристрою, чи обірвався зв'язок з мережею, чи сервером Blynk, то треба програмно передбачити такі ситуації і передбачити повторне підключення до серверу у разі втрати зв'язку. А також, коли немає зв'язку з сервером з якихось причин, функція Blynk.run(); буде "гальмувати" ваш пристрій, при кожному виклику (за замовчуванням аж 30 секунд). А викликається ця функція в головному циклі як найчастіше. Тому, як не передбачити втрату зв'язку, ви навіть не в змозі будете щось увімкнути на своєму пристрої. Наприклад, це буде у вас WiFi реле. То увімкнути, чи вимкнути реле з кнопки, скоріше за все в вас не вийде, або вийде з величезною затримкою. У всякому разі таким пристроєм користуватись буде не зручно.

Основа

Беремо за основу "пустий" приклад скетчу для роботи з Blynk:
*************************************************************

  Youll need:
   - Blynk App (download from AppStore or Google Play)
   - ESP8266 board
   - Decide how to connect to Blynk
     (USB, Ethernet, Wi-Fi, Bluetooth, ...)

  There is a bunch of great example sketches included to show you how to get
  started. Think of them as LEGO bricks  and combine them as you wish.
  For example, take the Ethernet Shield sketch and combine it with the
  Servo example, or choose a USB sketch and add a code from SendData
  example.
 *************************************************************/

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


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

// 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";

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

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
}

void loop()
{
  Blynk.run();
  // You can inject your own code or combine it with other sketches.
  // Check other examples on how to communicate with Blynk. Remember
  // to avoid delay() function!
}
Тепер додамо до цієї основи програмний контроль підключення до WiFi і Blynk.

Доопрацьований базовий скетч з контролем підключення до Wi-Fi та Blynk

Код для скетчу можете копіювати звідси або завантажити файл:
/* Comment this out to disable prints and save space */
#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"));
  }
}
І трішки пояснень по порядку:

  • змінна triggerBlynkConnect саме в цьому скетчі не використовується. Їй назначається true або false, але ніде не аналізується цей стан. Але коли знадобиться такий аналіз, то змінна, значення якої залежить чи є з'єднання з сервером blynk, або немає такого з'єднання з сервером, у вас вже буде.
  • змінна isFirstConnect потрібна для того, щоб синхронізація шпильок відбувалась тільки раз при першому підключенні.
  • оголошуємо таймер BlynkTimer timer і оголошуємо прототип функції для реконекту static void timerReconnect(void)
  • конектимось до WiFi мережі і в разі успіху конектимось до серверу блінк, як ні, то до серверу блінк і не намагаємось пробитись.
  • запускаємо таймер реконекту timer.setInterval(60000L, timerReconnect) - кожну хвилину буде виконуватись функція static void timerReconnect(void), де буде здійснюватись підключення до WiFi і Blynk у разі потреби, а як з конектом буде все гаразд, то нічого не буде виконуватись в цій функції.
  • в безкінечному циклі loop буде виконуватись Blynk.run(); тільки в тому разі, коли є підключення до серверу Blynk, а у разі втрати з'єднання, ваш код не буде "гальмувати".
  • функція BLYNK_CONNECTED() викликається кожного разу при з'єднанні з сервером Blynk і щоб кожного разу, при реконекті не синхронізувались всі шпильки, аналізуємо стан змінної isFirstConnect
До цього базового, доопрацьованого скетчу можете додавати свій функціонал і не боятись втрати зв'язку. Коли зв'язок відновиться, ваш пристрій знову підключиться до мережі і серверу. А також не буде "гальмуватись" ваш код коли не буде зв'язку, бо функція Blynk.run(); буде викликатись тільки коли є зв'язок з сервером.

Післямова

Як вам сподобалась стаття і хочете підтримати проект і бачити нові статті про Blynk, то буду вдячний за будь-які "донати".

16 коментарів:

  1. Здравствуйте, большое вам спасибо за код. Очень помогло.
    Не могли бы написать похожий код для платы Arduino Ethernet Shield W5100 . Я пытался переделать ваш код, но у меня не получилось .

    ВідповістиВидалити
    Відповіді
    1. Перепрошую. В мене немає "Arduino Ethernet Shield W5100" і я зовсім не в курсі особливостей цієї плати.

      Видалити
  2. Может у вас получиться по аналогии с esp8266 сделать ?

    ВідповістиВидалити
  3. #define BLYNK_PRINT Serial
    #include
    #include
    #include

    char auth[] = "YourAuthToken";

    void setup()
    {
    Blynk.begin(auth);
    }

    void loop()
    {
    Blynk.run();

    }

    ВідповістиВидалити
  4. Это код подключается к Blynk. Но если нет интернета, то все зависает .

    ВідповістиВидалити
    Відповіді
    1. Ну так вставте код з цієї статті. Бачу, що різниці ніякої.

      Видалити
  5. // Following includes are for Arduino Ethernet Shield (W5100)
    // If you're using another shield, see Boards_* examples
    #include
    #include
    #include

    bool result = false;
    bool isFirstConnect = true;

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

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

    void setup()
    {

    // Here your Arduino connects to the Blynk Cloud.
    Blynk.begin(auth);
    timer.setInterval(60000L, timerReconnect);

    }



    void loop()
    {
    if (Blynk.connected())
    {
    Blynk.run(); // Initiates Blynk Server
    }
    timer.run(); // Initiates BlynkTimer
    }

    BLYNK_CONNECTED()
    {

    if (isFirstConnect)
    {
    Blynk.syncAll();

    isFirstConnect = false;
    }
    }

    static void timerReconnect(void)
    {
    result = Blynk.connected();
    if (result = false)
    {

    Blynk.begin(auth);
    }

    }

    ВідповістиВидалити
  6. Здравствуйте, в моем коде какая то ошибка:
    Если в момент загрузки платы связь с сервером Blynk есть, то весть остальной код хорошо работает. Даже если потом отключить интернет.
    А вот если в момент загрузки платы интернета нет, то весь остальной код зависает. И ничего не работает пока нет подключения к интернету.

    ВідповістиВидалити
    Відповіді
    1. Вітання.
      Треба відокремити підключення до мережі і підключення до сервера блінк.
      На ESP8266 в моєму скетчі є окреме підключення до мережі WiFi функцією Blynk.connectWiFi(ssid, pass), а потім йде перевірка, як є підключення до WiFi то підключаємось і до блінку, як немає, то й до блінку не стукаємось. При реконекті теж саме, спочатку перевіряємо чи є WiFi, як немає намагаємось підключитись, як є, перевіряємо підключення до блінк, як немає то намагаємось підключитись.
      Так само і у вас має бути. Певно що для вашої плати ви використовуєте якусь бібліотеку, чи в бібліотеці блінк є якісь специфічні функції саме для керування Arduino Ethernet Shield (W5100) і підключенням її до мережі інтернет. Тут я не в курсі.

      Спробуйте як варіант в функції static void timerReconnect(void) замість "Blynk.begin(auth);" використовувати "Blynk.connect()" так буде правильніше. Результат напишіть будь ласка.

      Видалити
    2. Наче зрозумів чому можливо не коректно працює ваш скетч.
      На початку, в функції setup(), рядок Blynk.begin(auth); поміняйте на Blynk.config(auth); Blynk.connect();. В функції реконекту замість Blynk.begin(auth); напишіть "Blynk.connect();
      Має допомогти.

      Видалити
  7. Шкода, але на Ардуіно Мега з ЕСП модулем скетч видає помилки і це у мене єдина плата, яка має проблеми з реконектом після втрати світла чи інтернету.

    ВідповістиВидалити
    Відповіді
    1. Звісно цей скетч не підходить для вашого варіанту. Переробіть під своє залізо по аналогії.

      Видалити
    2. Без вашого коду і тексту помилки важко щось сказати.

      Видалити
    3. матюкається на цей рядок:
      if (WiFi.status() == WL_CONNECTED)

      Connect.h:56: error: 'WL_CONNECTED' was not declared in this scope

      Видалити
    4. Для "Ардуіно Мега з ЕСП" має бути щось інше, звісно що. Я не маю ардуіну і не використовував в такій зв'язці. В бібліотеці для ардуіно, яка працює з єсп, має бути якийсь спосіб взнати чи єсп в конекті з вайфай мережею чи ні. Та умова перевіряє чи є зв'язок з мережею вайфай. Вам треба ознайомитись з документацією на бібліотеку яка керує есп і знайти щось подібне.

      Видалити
  8. спасибо!!!
    работает,только синтаксис ошибки есть в коде

    ВідповістиВидалити