неділя, 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, то буду вдячний за будь-які "донати".