Как отвязаться от wifi?

Тема в разделе "ESP8266, ESP32", создана пользователем Drunkbarbarian, 5 сен 2020.

  1. Drunkbarbarian

    Drunkbarbarian Нерд

    Утро доброе! Появился вопрос более опытным форумчанам. Как сохранить работоспособность и непрерывность работы скетча при обрыве wifi соединения? Вопрос насушный. Ставишь, например, обогреватель на какое-то время. А тут раз с роутером произошло что-то неожиданное.И ESP остается с включенным радиатором, перестает воспринимать настройки максимальной температуры отключения. Че делать то?
     
  2. SergeiL

    SergeiL Оракул Модератор

    А как он примет команду, если нет Wi-Fi?
     
  3. Airbus

    Airbus Радиохулиган Модератор

    Добавить пару строчек кода. Например пинговать. Если if пинг есть то работаем дальше else сразу вырубаем. Или не сразу. Или не вырубаем а переводим в low power. Или еще что угодно. Как то так.
     
    b707, Daniil и Andrey12 нравится это.
  4. Airbus

    Airbus Радиохулиган Модератор

    Вот код для перезагрузки роутера для розетки Sonoff в последних строчках кода вместо перезагрузки тупо вырубаем реле если нет пинга.
     
  5. ИгорьК

    ИгорьК Гуру

    Не согласен. Любое устройство нужно делать так, чтобы оно в принципе не зависело от наличия сети - алгоритм его работы должен храниться в нем самом.

    "Управление из любой точки мира" - полный бред.
     
    Andrey12, Un_ka, b707 и 2 другим нравится это.
  6. ИгорьК

    ИгорьК Гуру

    Это в целом плохая логика. Не должно быть устройства, управляемого через интернет.
    Если по каким-то причинам (не представляю каким, но может быть) это нужно - дублируйте управление через gsm.

    Расскажите, что за устройство вы хотите сделать.
     
    Airbus нравится это.
  7. Airbus

    Airbus Радиохулиган Модератор

    Согласен полностью. Но на всякий случай при пропадании интернета переводил бы устройство в экономичный/безопасный/спящий режим или вырубал бы полностью.Чтобы оно не вышло из под контроля не загорелось и не йопнуло. Это и хотел сказать. А так да GSM+DTMF хорошая связка.
     
  8. parovoZZ

    parovoZZ Гуру

    Есть такое понятие в автоматизации, как безопасный останов работы установки. Так вот если управляющий сигнал исчез, контроллер должен самостоятельно перейти в этот режим.
     
    Andrey12 и ИгорьК нравится это.
  9. SergeiL

    SergeiL Оракул Модератор

    Да я думаю у ТС все гораздо проще, вся обработка в loop(), и в момент реконнекта он подвисает внутри в функции реконнекта.
    Проходили - все лечится правильным кодом. Нужно все реконнекты оставить в loop(), а всю обработку событий перенести в Ticker.
    (библиотека Ticker.h для ESP)
    В квартире все выключатели света на ESP.
    Что есть Wi-Fi, что нет - работают как обычные выключатели. Переключил - тут же свет включился.
     
  10. Drunkbarbarian

    Drunkbarbarian Нерд

    Задача стояла обогреватель сделать с удаленным управлением. Так то вроде все работает. Но интернет от оператора связи в деревне - вещь не на 100% надежная, сами понимаете. А код в том виде как сейчас просто вырубает реле и подвисает в ожидании wifi. Надо чтоб обогревал по заданным параметрам и без wifi,
    Код (C++):
    #include <EEPROM.h>
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPUpdateServer.h>
    #include <SPI.h>

    #define RELAY1    16 //тепловая пушка
    #define ONE_WIRE_BUS 4 //
    int run_1;
    int Gist_1;
    int Gist_2;


    long previousMillis_time = 5000;//0
    long interval_time = 5000;//3


    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);


    #define ssid "333"         //wifi ssid
    #define password "333"     //wifi password
    #define mqtt_server "333.ru"  //
    const int mqtt_port = 333; //
    #define user_name "OBOGREV_1"      // username
    #define mqtt_pswd "*****"   // password


    #define OTAUSER         "Denis"    // Логин для входа в OTA
    #define OTAPASSWORD     "Belov"   // Пароль для входа в ОТА
    #define OTAPATH         "/soft"// Путь, который будем дописывать после ip адреса в браузере.
    #define SERVERPORT      80         // Порт для входа, он стандартный 80 это порт http
    ESP8266WebServer HttpServer(SERVERPORT);
    ESP8266HTTPUpdateServer httpUpdater;



    WiFiClient espClient;
    PubSubClient client(espClient);
    //uint32_t lastMsg = 0; ///только плюс
    int16_t lastMsg = 0; ///проверить!!! может принимать и + и -
    #define MSG_BUFFER_LEN  10u
    char msg[MSG_BUFFER_LEN];

    // Setup WiFi Connection
    void setup_wifi()
    {
      delay(10);
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      httpUpdater.setup(&HttpServer, OTAPATH, OTAUSER, OTAPASSWORD);
      HttpServer.onNotFound(handleNotFound);
      HttpServer.begin();
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }

    void setup()
    // Serial.begin(115200);
    {
      sensors.begin();
      EEPROM.begin(512);
      //EEPROM.begin(3);
      run_1 = EEPROM.read(1);
      Gist_1 = EEPROM.read(2);
      Gist_2 = EEPROM.read(3);
    {

      // Initialize Relay's Pins as Output
      pinMode(RELAY1, OUTPUT );
      // Turn-Off all relays
      digitalWrite( RELAY1, LOW);

       // Intiialize Serial Communication for Debug Messages
      Serial.begin(115200);
      // Setup NodeMcu with WiFi
      setup_wifi();
      client.setServer(mqtt_server, mqtt_port);
      client.setCallback(callback);
    }



    }

    void callback(char* topic, byte* payload, uint16_t length)
    {
      char message[15];
      uint8_t i;


      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");



      for (i = 0; i < length; i++)
      {
       Serial.print((char)payload[i]);
       message[i] = (char)payload[i];
      }
      message[i] = 0;
      Serial.println();

      // Relay1 (Load1R) Topic
      if( strcmp(topic, "load1O") == 0 )

      {
        if ((char)payload[0] == '0')
     
        {    
          run_1 = 0;
          //Serial.println(run_1);
          EEPROM.write(1,run_1);
          EEPROM.commit();
        }
        if ((char)payload[0] == '1')
        {
          run_1 = 1;
          //Serial.println(run_1);
          EEPROM.write(1,run_1);
          EEPROM.commit();
        }
      }
     
      if( strcmp(topic, "GISTER_11") == 0 )
      {
          Gist_1 = atoi(message);
          //Serial.print("Gist_1 = ");
          //Serial.println(Gist_1);
          Gist_2 = EEPROM.read(3);
          if (Gist_1 < Gist_2)
          {
            EEPROM.write(2,(uint8_t) Gist_1);
            EEPROM.commit();
          }
           if (Gist_1 >= Gist_2)
          {
            Gist_1 = Gist_2 - 5;
            EEPROM.write(2,(uint8_t) Gist_1);
            EEPROM.commit();
            //delay(500);
          }
      }
      if( strcmp(topic, "GISTER_12") == 0 )
      {
          Gist_2 = atoi(message);
          //Serial.print("Gist_2 = ");
          //Serial.println(Gist_2);
          Gist_1 = EEPROM.read(2);
          if (Gist_2 > Gist_1)
          {
          EEPROM.write(3,(uint8_t) Gist_2);
          EEPROM.commit();
          }
          if (Gist_2 <= Gist_1)
          {
          Gist_2 = Gist_1 + 5;
          EEPROM.write(3,(uint8_t) Gist_2);
          EEPROM.commit();
          //delay(500);
          }
      }


    }


    // Reconnect with Server Function
    void reconnect()
    {
      // Loop until we're reconnected
      while (!client.connected())
      {
        Serial.print("Attempting CloudMQTT connection...");
        String clientId = "OBOGREV_1";//обязательно задан клиент ID
        Serial.print("Client Id:  ");
        Serial.println(clientId);
        if ( client.connect(clientId.c_str(), user_name, mqtt_pswd) )
        {
          Serial.println("connected");

          client.subscribe("load1O");
          client.subscribe("GISTER_11");
          client.subscribe("GISTER_12");
       
        }
        else
        {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          delay(5000);
        }
      }
    }
    void loop()
    {
    sensors.requestTemperatures();
    float celsius = sensors.getTempCByIndex(0);
    Serial.print("Температура воздуха = ");
    Serial.println(sensors.getTempCByIndex(0));
    char temperaturenow [15];
    dtostrf(celsius, 6, 1, temperaturenow); ////7 знаков общее и 1 знака после запятой
    client.publish("TEMP_OBOGR", temperaturenow); /// send char

    char buffer[20];

       if ((run_1 == 1) && (sensors.getTempCByIndex(0) <= Gist_1))
    {
      digitalWrite( RELAY1, HIGH);
    }
      if ((run_1 == 0) || (sensors.getTempCByIndex(0) >= Gist_2))
    {
      digitalWrite( RELAY1, LOW);
    }
    int Yrssi = WiFi.RSSI();
    int radixY = 10;
    char *RSSI_1;
    RSSI_1 = itoa(Yrssi,buffer,radixY);
    client.publish("RSSI_OBOGR", RSSI_1);

    int a = Gist_1; // исходник
    int radixa = 10; //система счисления
    char *G_1;  //указатель на результат
    G_1 = itoa(a,buffer,radixa);
    client.publish("GISTERout_11", G_1);

    int b = Gist_2; // исходник
    int radixb = 10; //система счисления
    char *G_2;  //указатель на результат
    G_2 = itoa(b,buffer,radixb);
    client.publish("GISTERout_12", G_2);

    IPAddress ip = WiFi.localIP();
    String IPlocal = ip.toString();
    client.publish("IP_OBOGR", IPlocal.c_str());



    Serial.print("Переменная run_1 = ");
    Serial.println(run_1);
    Serial.print("Гистерезис_1 = ");
    Serial.println(Gist_1);
    Serial.print("Гистерезис_2 = ");
    Serial.println(Gist_2);
    Serial.print("Локальный IP = ");
    Serial.println(WiFi.localIP());
    Serial.print("RSSI =  ");
    Serial.println(WiFi.RSSI());
    if (!client.connected())
    {
    digitalWrite( RELAY1, LOW);
    delay(3000);
    reconnect() ;
    }
    {
      HttpServer.handleClient();       // Прослушивание HTTP-запросов от клиентов
    }

    client.loop();
    long now = millis();
    }


    void handleNotFound() {
      HttpServer.send(404, "text/plain", "404: Not found");
    }
     
  11. ИгорьК

    ИгорьК Гуру

    ... который...

    А дальше вместо кода расскажите об ожидаемом алгоритме его работы.

    Вы, кстати, сами писали этот скетч и понимаете как он работает?

    SmartSelect_20200906-084523_Samsung Internet.jpg
     
    Последнее редактирование: 6 сен 2020
  12. Drunkbarbarian

    Drunkbarbarian Нерд

    Понимаю. Писал по примерам. Тридцать раз его проверил и подобные.
    Управляется через MQTT_BOARD с мобилы. Банально включение через переменную run_1 - пишется в еепром. Равна либо 0, либо1. Задаются переменные гистерезисов Gist_1 & Gist_2. Если температура окружающего воздуха <= Gist_1 происходит включение. Доходит до Gist_2 - выключается. Защита есть от коллизии Gist_1 всегда может сохраняться только если он меньше Gist_2. Топики с сохраненными ГИСТами летят обратно для проверки. Проливка по воздуху.
    Топики с IP и RSSI тоже летят в борду.
    Код, конечно, стоит улучшить и упростить. Но пока задача доработать до независимости от подключения к MQTT серверу. Нужно чтоб при отключении от MQTT код продолжал коптить обогреватель согласно с внесенными в память гистерезисами, продолжая при этом проверку подключения к серверу, быть доступным для перепроливки по локальному wifi. Наверняка все просто.
     
  13. Drunkbarbarian

    Drunkbarbarian Нерд

    это временный вариант с отключением!
     
  14. ИгорьК

    ИгорьК Гуру

    Ну так присмотритесь к скриншоту, если все остальное в работе вас устраивает.

    За одно подумайте, что должно произойти если wifi не будет неделю.
     
  15. Drunkbarbarian

    Drunkbarbarian Нерд

    Я на него уже два дня смотрю и решил вот спросить как лучше сделать.
    Через millis() подключение сконфигурить? Как?
     
  16. ИгорьК

    ИгорьК Гуру

    На скриншоте второй строкой вы выключаете реле по потере соединения. Закомментируйте её и реле перестанет выключаться.

    Использовать delay в реальных устройствах не рекомендуется - вы останавливаете его работу.

    Через миллис просто: запомните в переменную время и в лупе вычитайте из текущего. Если прошло больше необходимого запускайте то что вам надо.
     
  17. Drunkbarbarian

    Drunkbarbarian Нерд

    буду пробовать. Спасибо.
     
  18. Drunkbarbarian

    Drunkbarbarian Нерд


    Ввел переменную unsigned long interval_time.
    Потом:
    Код (C++):
     if (!client.connected())
    {
    if (millis() - interval_time > 30000)
    {
    reconnect() ;
    }
    }
    Так?? reconnect() больше не должен подвешивать ESP?
     
    Последнее редактирование: 6 сен 2020
  19. SergeiL

    SergeiL Оракул Модератор

    Если просто закомментировать - не поможет.
    Там еще в reconnect есть while из которого не выйти, пока по mqtt не подключится.
     
    b707 нравится это.
  20. Drunkbarbarian

    Drunkbarbarian Нерд

    А еси упростить?
    Код (C++):
    void reconnect()
    {
      // Loop until we're reconnected
      //while (!client.connected())
      if (!client.connected())
      {
        Serial.print("Attempting CloudMQTT connection...");
        String clientId = "OBOGREV_1";//обязательно задан клиент ID
        Serial.print("Client Id:  ");
        Serial.println(clientId);
        if ( client.connect(clientId.c_str(), user_name, mqtt_pswd) )
        {
          Serial.println("connected");

          client.subscribe("load1O");
          client.subscribe("GISTER_11");
          client.subscribe("GISTER_12");
       
        }
        else
        {
          Serial.print("failed, rc=");
          Serial.print(client.state());
          Serial.println(" try again in 5 seconds");
          // Wait 5 seconds before retrying
          //delay(5000);
        }
      }
    }