Система интеллектуального освещения на основе esp поверх Alexa работает со сбоями

Я сделал систему домашней автоматизации, используя esp 32 и 8-канальное реле, но в течение 2 или 3 месяцев мое реле автоматически отключается после отправки сигнала через esp32, но если я подключаюсь напрямую без esp32, оно работает абсолютно нормально. это означает, что с моим реле все в порядке, но что должно быть возможной причиной его неисправности. это мой код

#include <ESP8266WiFi.h>
#include <Espalexa.h>
Espalexa espalexa;


// определяем GPIO, связанный с реле и переключателями
#define RelayPin1 5  //D23
#define RelayPin2 4  //D22
#define RelayPin3 0  //D21
#define RelayPin4 2  //D19
#define RelayPin5 14  //D18
#define RelayPin6 12  //D5
#define RelayPin7 13  //D25
#define RelayPin8 15  //D26

#define SwitchPin1 3  //D13
#define SwitchPin2 1  //D12
#define SwitchPin3 10  //D14
#define SwitchPin4 9  //D27
#define SwitchPin5 8  //D33
#define SwitchPin6 11  //D32
#define SwitchPin7 7  //D15
#define SwitchPin8 6   //D4

bool oldStateSwitch_1;
bool oldStateSwitch_2;
bool oldStateSwitch_3;
bool oldStateSwitch_4;
bool oldStateSwitch_5;
bool oldStateSwitch_6;
bool oldStateSwitch_7;
bool oldStateSwitch_8;


#define wifiLed    16   //D2

// Учетные данные Wi-Fi
const char* ssid = "akkikisu";
const char* password = "anirudh@123";

// имена устройств
String Device_1_Name = "a1";
String Device_2_Name = "a2";
String Device_3_Name = "a3";
String Device_4_Name = "a4";
String Device_5_Name = "a5";
String Device_6_Name = "a6";
String Device_7_Name = "a7";
String Device_8_Name = "a8";

// прототипы
boolean connectWifi();

//функции обратного вызова
void firstLightChanged(uint8_t brightness);
void secondLightChanged(uint8_t brightness);
void thirdLightChanged(uint8_t brightness);
void fourthLightChanged(uint8_t brightness);
void fifthLightChanged(uint8_t brightness);
void sixthLightChanged(uint8_t brightness);
void senventhLightChanged(uint8_t brightness);
void eighthLightChanged(uint8_t brightness);

boolean wifiConnected = false;

//наши функции обратного вызова
void firstLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin1, LOW);
      Serial.println("Device1 ON");
    }
  else
  {
    digitalWrite(RelayPin1, HIGH);
    Serial.println("Device1 OFF");
  }
}

void secondLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin2, LOW);
      Serial.println("Device2 ON");
    }
  else
  {
    digitalWrite(RelayPin2, HIGH);
    Serial.println("Device2 OFF");
  }
}

void thirdLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin3, LOW);
      Serial.println("Device3 ON");
    }
  else
  {
    digitalWrite(RelayPin3, HIGH);
    Serial.println("Device3 OFF");
  }
}

void fourthLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin4, LOW);
      Serial.println("Device4 ON");
    }
  else
  {
    digitalWrite(RelayPin4, HIGH);
    Serial.println("Device4 OFF");
  }
}

void fifthLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin5, LOW);
      Serial.println("Device5 ON");
    }
  else
  {
    digitalWrite(RelayPin5, HIGH);
    Serial.println("Device1 OFF");
  }
}

void sixthLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin6, LOW);
      Serial.println("Device6 ON");
    }
  else
  {
    digitalWrite(RelayPin6, HIGH);
    Serial.println("Device6 OFF");
  }
}

void seventhLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin7, LOW);
      Serial.println("Device7 ON");
    }
  else
  {
    digitalWrite(RelayPin7, HIGH);
    Serial.println("Device7 OFF");
  }
}

void eighthLightChanged(uint8_t brightness)
{
  //Управляем устройством
  if (brightness == 255)
    {
      digitalWrite(RelayPin8, LOW);
      Serial.println("Device8 ON");
    }
  else
  {
    digitalWrite(RelayPin8, HIGH);
    Serial.println("Device8 OFF");
  }
}

// подключение к Wi-Fi — возвращает true в случае успеха или false в противном случае
boolean connectWifi()
{
  boolean state = true;
  int i = 0;

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  // Ждем подключения
  Serial.print("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (i > 20) {
      state = false; break;
    }
    i++;
  }
  Serial.println("");
  if (state) {
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {
    Serial.println("Connection failed.");
  }
  return state;
}

void addDevices(){
  // Определите здесь свои устройства.
  espalexa.addDevice(Device_1_Name, firstLightChanged); //самое простое определение, состояние по умолчанию выключено
  espalexa.addDevice(Device_2_Name, secondLightChanged);
  espalexa.addDevice(Device_3_Name, thirdLightChanged);
  espalexa.addDevice(Device_4_Name, fourthLightChanged);
  espalexa.addDevice(Device_5_Name, fifthLightChanged); 
  espalexa.addDevice(Device_6_Name, sixthLightChanged);
  espalexa.addDevice(Device_7_Name, seventhLightChanged);
  espalexa.addDevice(Device_8_Name, eighthLightChanged);

  espalexa.begin();
}

void setup()
{
  Serial.begin(115200);

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(RelayPin5, OUTPUT);
  pinMode(RelayPin6, OUTPUT);
  pinMode(RelayPin7, OUTPUT);
  pinMode(RelayPin8, OUTPUT);

  pinMode(wifiLed, OUTPUT);

  pinMode(SwitchPin1, INPUT_PULLUP);
  pinMode(SwitchPin2, INPUT_PULLUP);
  pinMode(SwitchPin3, INPUT_PULLUP);
  pinMode(SwitchPin4, INPUT_PULLUP);
  pinMode(SwitchPin5, INPUT_PULLUP);
  pinMode(SwitchPin6, INPUT_PULLUP);
  pinMode(SwitchPin7, INPUT_PULLUP);
  pinMode(SwitchPin8, INPUT_PULLUP);

  //Во время запуска все реле должны ВЫКЛЮЧАТЬСЯ
  digitalWrite(RelayPin1, HIGH);
  digitalWrite(RelayPin2, HIGH);
  digitalWrite(RelayPin3, HIGH);
  digitalWrite(RelayPin4, HIGH);
  digitalWrite(RelayPin5, HIGH);
  digitalWrite(RelayPin6, HIGH);
  digitalWrite(RelayPin7, HIGH);
  digitalWrite(RelayPin8, HIGH);

  oldStateSwitch_1 = ! digitalRead( SwitchPin1 ) ;  // нота перевернута
  oldStateSwitch_2 = ! digitalRead( SwitchPin2 ) ;  // нота перевернута
  oldStateSwitch_3 = ! digitalRead( SwitchPin3 ) ;  // нота перевернута
  oldStateSwitch_4 = ! digitalRead( SwitchPin4 ) ;  // нота перевернута
  oldStateSwitch_5 = ! digitalRead( SwitchPin5 ) ;  // нота перевернута
  oldStateSwitch_6 = ! digitalRead( SwitchPin6 ) ;  // нота перевернута
  oldStateSwitch_7 = ! digitalRead( SwitchPin7 ) ;  // нота перевернута
  oldStateSwitch_8 = ! digitalRead( SwitchPin8 ) ;  // нота перевернута
    



    // повторить для выбранных от 2 до 8
  
    


  // Инициализировать Wi-Fi соединение
  wifiConnected = connectWifi();

  if (wifiConnected)
  {
    addDevices();
  }
  else
  {
    Serial.println("Cannot connect to WiFi. So in Manual Mode");
    delay(1000);
  }
}

void loop()
{
   if (WiFi.status() != WL_CONNECTED)
  {
    //Serial.print("Wi-Fi не подключен");
    digitalWrite(wifiLed, LOW); //Выключаем индикатор WiFi
  }
  else
  {
    //Serial.print("Wi-Fi подключен");
    digitalWrite(wifiLed, HIGH);
    // Ручное управление переключателем
    //Управление Wi-Fi
    if (wifiConnected){
      espalexa.loop();
      delay(1);
    }
    else {
      wifiConnected = connectWifi(); // Инициализировать Wi-Fi соединение
      if(wifiConnected){
      addDevices();
      }
    }
  }


// основной код

static uint32_t lastSwitchTest = 0 ;  // статическая инициализация только один раз

      if ( millis() - lastSwitchTest > 250 ) {  // каждые 250 мс
      lastSwitchTest = millis() ;

      // переключатель 1

      bool stateSwitch_1 = digitalRead( SwitchPin1 ) ;
      if (  oldStateSwitch_1 != stateSwitch_1 ) {
         oldStateSwitch_1 = stateSwitch_1 ;
         Serial.println("Switch 1 changed");
         EspalexaDevice* d1 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_1 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d1->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin1, HIGH);
         }
         else { // включаем
            Serial.println("Switch 1 on");
            d1->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin1, LOW);
         }
      }

      // переключатель 2

      bool stateSwitch_2 = digitalRead( SwitchPin2 ) ;
      if ( oldStateSwitch_2 != stateSwitch_2 ) {
         oldStateSwitch_2 = stateSwitch_2 ;
         Serial.println("Switch 2 changed");
         EspalexaDevice* d2 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_2 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 2 off");
            d2->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin2, HIGH);
         }
         else { // включаем
            Serial.println("Switch 2 on");
            d2->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin2, LOW);
         }
      }
 
      // переключатель 3

      bool stateSwitch_3 = digitalRead( SwitchPin3 ) ;
      if ( oldStateSwitch_3 != stateSwitch_3 ) {
         oldStateSwitch_3 = stateSwitch_3 ;
         Serial.println("Switch 3 changed");
         EspalexaDevice* d3 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_3 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d3->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin3, HIGH);
         }
         else { // включаем
            Serial.println("Switch 3 on");
            d3->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin3, LOW);
         }
      }
      // переключатель 4

      bool stateSwitch_4 = digitalRead( SwitchPin4 ) ;
      if ( oldStateSwitch_4 != stateSwitch_4 ) {
         oldStateSwitch_4 = stateSwitch_4 ;
         Serial.println("Switch 4 changed");
         EspalexaDevice* d4 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_4 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d4->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin4, HIGH);
         }
         else { // включаем
            Serial.println("Switch 4 on");
            d4->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin4, LOW);
         }
      }
      // переключатель 5

      bool stateSwitch_5 = digitalRead( SwitchPin5 ) ;
      if ( oldStateSwitch_5 != stateSwitch_5 ) {
         oldStateSwitch_5 = stateSwitch_5 ;
         Serial.println("Switch 5 changed");
         EspalexaDevice* d5 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_5 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d5->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin5, HIGH);
         }
         else { // включаем
            Serial.println("Switch 5 on");
            d5->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin5, LOW);
         }
      }
      // переключатель 6

      bool stateSwitch_6 = digitalRead( SwitchPin6 ) ;
      if ( oldStateSwitch_6 != stateSwitch_6 ) {
         oldStateSwitch_6 = stateSwitch_6 ;
         Serial.println("Switch 6 changed");
         EspalexaDevice* d6 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_6 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d6->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin6, HIGH);
         }
         else { // включаем
            Serial.println("Switch 6 on");
            d6->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin6, LOW);
         }
      }
      // переключатель 7

      bool stateSwitch_7 = digitalRead( SwitchPin7 ) ;
      if ( oldStateSwitch_7 != stateSwitch_7 ) {
         oldStateSwitch_7 = stateSwitch_7 ;
         Serial.println("Switch 7 changed");
         EspalexaDevice* d7 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_7 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d7->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin7, HIGH);
         }
         else { // включаем
            Serial.println("Switch 7 on");
            d7->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin7, LOW);
         }
      }
      // переключатель 8

      bool stateSwitch_8 = digitalRead( SwitchPin8 ) ;
      if ( oldStateSwitch_8 != stateSwitch_8 ) {
         oldStateSwitch_8 = stateSwitch_8 ;
         Serial.println("Switch 8 changed");
         EspalexaDevice* d8 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_8 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d8->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin8, HIGH);
         }
         else { // включаем
            Serial.println("Switch 8 on");
            d8->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin8, LOW);
         }
      }


  
      
      // переключаем 2 на 8
      // просто скопируйте/вставьте/настройте, используя переключатель 1 в качестве шаблона


    } // если ( миллисекунды
} // петля()

, 👍1

Обсуждение

Каждые 2 или 3 месяца вы получаете ложное срабатывание вашего релейного модуля, которое вы приписываете программной проблеме на esp32. Это верно? Если это так, это может быть плохой обработкой ролловера millis() где-то в вашем коде или библиотеке. Этот переход происходит каждые 49 дней., @6v6gt

@ 6v6gt и как я могу исправить свою проблему, @Rathore Brothers

Я подозреваю, что библиотека кнопок acebutton.h . Похоже, что он использует 16-битные типы данных для хранения таймингов, вероятно, производных от millis(), для устранения дребезга кнопок и т. д. 32-битные целые числа были бы более подходящими. Использование другой библиотеки может решить эту проблему. Но вы должны провести долгосрочный тест., @6v6gt

какую библиотеку я могу использовать. и не могли бы вы сказать мне соответствующий код для этого, @Rathore Brothers

Прежде чем углубляться в поиск решения, давайте опишем проблему. Когда вы говорите, что он работает без ESP32, вы имеете в виду, что можете подключить 8-канальный релейный модуль напрямую к Alexa? Вы сказали, что это ложное поведение происходит в течение 2 или 3 месяцев. Возможно ли, чтобы это происходило регулярно каждые 49 дней? Используете ли вы кнопки или тумблеры для ручного управления реле? Это так, что вы узнаете, что у вас есть рабочее решение, только после тестирования в течение 2-3 месяцев?, @6v6gt

https://iotcircuithub.com/esp32-alexa-home-automation-system/ так что здесь вы можете найти все детали, @Rathore Brothers

ХОРОШО. Из ссылки на проект видно, что кнопки на самом деле являются тумблерами. Пожалуйста, ответьте на оставшиеся вопросы, которые я задавал ранее. Кроме того, если вы нажмете кнопку сброса на ESP32, вы получите тот же эффект, который, как вы говорите, появляется через 2-3 месяца, то есть ложное переключение реле? Библиотека кнопок добавляет ненужную сложность, и код можно изменить, чтобы устранить ее. Хотя не факт, что это решит проблему. Утечка памяти также может дать аналогичные эффекты., @6v6gt

да, после нажатия кнопки сброса я столкнулся с той же проблемой. и да, я думаю, что это может произойти в течение 49 дней, и еще одна большая проблема заключается в том, что я могу перепрограммировать свою плату, так как я сломал штырек micro usb., @Rathore Brothers


1 ответ


1

В качестве базы кода вы используете следующий проект: https://iotcircuithub.com/esp32-alexa. -система домашней автоматизации/

Похоже, вы подтвердили, что те же симптомы проблемы появляются при сбросе ESP32, то есть некоторые индикаторы находятся в неправильном состоянии при запуске системы. Сброс может быть вызван такими причинами, как сброс системы после отключения электроэнергии, сбоя или простого нажатия кнопки сброса на устройстве.

Вы используете библиотеку обработки кнопок AceButton.h в сочетании с переключателями с фиксацией. Проблема здесь в том, что библиотека управления кнопками предназначена для кнопок мгновенного нажатия и предполагает, что переключатель находится в состоянии «не нажат». состояние при запуске системы. Это может не отражать положение переключателей с фиксацией, где одни могут находиться во включенном положении, а другие в выключенном. Это может привести к пропущенным событиям при запуске системы.

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

В setup() вы должны прочитать каждый переключатель и сохранить инверсию его текущего состояния в переменной, скажем, oldStateSwitch_1. Необходимо сохранить обратное состояние, чтобы вызвать действие изменения состояния при первом переключении в цикле().

Что-то вроде . . .

void setup() {
    . . .
    
    oldStateSwitch_1 = ! digitalRead( switchPin1 ) ;  // нота перевернута
    // повторить для выбранных от 2 до 8
    . . . 
    
}

В цикле() вы должны сделать что-то вроде . . .

void loop() {

. . .
. . .

    static uint32_t lastSwitchTest = 0 ;  // статическая инициализация только один раз

    if ( millis() - lastSwitchTest > 250 ) {  // каждые 250 мс
      lastSwitchTest = millis() ;

      // переключатель 1

      bool stateSwitch_1 = digitalRead( switchPin1 ) ;
      if ( oldStateSwitch_1 != stateSwitch_1 ) {
         oldStateSwitch_1 = stateSwitch_1 ;
         Serial.println("Switch 1 changed");
         EspalexaDevice* d1 = espalexa.getDevice(0); // это будет "первое устройство", индекс отсчитывается от нуля
         if ( stateSwitch_1 == HIGH )  {  // HIGH = выключено
            Serial.println("Switch 1 off");
            d1->setPercent(0); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin1, HIGH);
         }
         else { // включаем
            Serial.println("Switch 1 on");
            d1->setPercent(100); // устанавливаем значение "яркость" в процентах
            digitalWrite(RelayPin1, LOW);
         }
      }
      
      // переключаем 2 на 8
      // просто скопируйте/вставьте/настройте, используя переключатель 1 в качестве шаблона


    } // если ( миллисекунды
} // петля()

Весь код AceButton должен быть удален.

,

теперь снова происходит то же самое, но на этот раз переключатели автоматически выключаются, а через некоторое время включаются, если горит синий индикатор на плате, но иногда этот синий индикатор гаснет, и плата не может подключиться к Wi-Fi. я решаю это, @Rathore Brothers

@RathoreBrothers Общеизвестно, что ложный сброс микроконтроллера и проблемы с подключением к WiFi трудно расследовать. Что происходит, когда система работает нормально и (проверка а) вы нажимаете кнопку сброса на esp32 и (проверка б) выключаете маршрутизатор WiFi? Есть ли у вас симптомы, похожие на те, которые вы описали?, @6v6gt

когда я нажимаю сброс, платы обычно сбрасываются, и я могу получить доступ к свету, и когда я выключаю Wi-Fi, я также могу получить доступ через переключатели, но не через Alexa, но дело в том, что через некоторое время свет гаснет и через некоторое время, @Rathore Brothers

не могли бы вы ответить, @Rathore Brothers

@RathoreBrothers Если вы нажмете сброс на esp32, вернутся ли огни в состояние, в котором они были до сброса? Являются ли переключатели того же типа, что и в проекте, т. е. они фиксируют положение «ВКЛ.» или «ВЫКЛ.», или вы используете нажимные кнопки? Если код, который вы используете, не совпадает с исходным вопросом, обновите вопрос, указав новый код. Вы просмотрели комментарии в проекте и видео, чтобы узнать, есть ли у других людей такая же проблема?, @6v6gt

да фары возвращаются в исходное состояние. нет, я не использую кнопки. код такой же, как вы предложили мне ранее, и нет, я не мог найти людей с проблемой, возможно, никто не пробовал в этом масштабе., @Rathore Brothers

@RathoreBrothers, если вы вставите полный код в вопрос, я могу проверить, нет ли основных ошибок в интерпретации того, что я предложил, но я не могу это проверить, потому что я не использую Alexa. Существует более 100 открытых проблем с этой библиотекой espalexa, поэтому открытие проблемы в ее репозитории github может не принести быстрого решения. Ухудшил ли новый код ситуацию?, @6v6gt

новый код немного усугубил ситуацию, так как свет часто выключается, но снова включается автоматически, @Rathore Brothers

не могли бы вы ответить, @Rathore Brothers

@RathoreBrothers, если вы вставите полный код в вопрос, я могу проверить, нет ли основных ошибок в интерпретации того, что я предложил, но я не могу это проверить, потому что я не использую Alexa. Вставьте его после исходного кода., @6v6gt

вот, я разместил свой обновленный код, @Rathore Brothers