Продолжаю мучать машинку-управляемую через MQTT. Есть проблема: вис системы - если стучать по всем клавишам подряд

mu_ssina
Offline
Зарегистрирован: 30.08.2013

Всем доброго, друзья!

Может кто подскажет: мучаю свою многострадальную машинку-управляемую с сайта через MQТТ-брокер (веб интерфейс шлет сообщения на брокер-откуда их забирает и исполняет машинка).

Веб интерфейс проверен-всё ок. С брокером тоже всё ок-все работает отлично. Где то косяк на этапе принятия сообщения и его дальнейшей обработки(я так подозреваю).

В чем косяк: в целом всё работает ок. Но, в какой то момент-машинка "зависает" с включенными колесами или наоборот-выключенными. На команды с сайта не реагирует. Машинка построена на ESP32 (я уже выкладывал ее). С батареей всё ок.

Вот так вылглядит код. Может кто подскажет, где теоретически может теряться принятое сообщение, чтобы машинка "зависла" в неопределенном состоянии?

Из кода вырезал: 1) код выравнивания скоростей колес-с помощью прерываний и PID-регулятора (чтобы машинка ехала строго вперед); 2) замер напряжения батареи 18650.  Так как особого отношения к делу он не имеет.

Основной код:

 

#include <WiFi.h>
#include <PubSubClient.h>
#include <Pangodream_18650_CL.h>
//#include <GyverPID.h>

//---------------Замер напряжения батареи-----------------
//#define ADC_PIN 34
//#define CONV_FACTOR 1.7
//#define READS 20

Pangodream_18650_CL BL;
/**
 * If you need to change default values you can use it as
 * Pangodream_18650_CL BL(ADC_PIN, CONV_FACTOR, READS);
 */

  volatile uint32_t charge_test = 0; // время последней проверки уровня заряда батареи
 
//--------------------------------------------------------



// вставляем ниже SSID и пароль для своей WiFi-сети:
const char* ssid = "сюда название WIFI сети";
const char* password = "пароль  WIFI сети";
const char* mqtt_server = "адрес mqtt-брокера";
#define mqtt_port 1883
#define MQTT_USER "" //сюда имя пользователя MQTT, если система должна иметь пользователя и пароль
#define MQTT_PASSWORD "" //сюда пароль пользователя MQTT, если система должна иметь пользователя и пароль
#define MQTT_SERIAL_PUBLISH_CH "vasyapupgen|moshino"
#define MQTT_SERIAL_RECEIVER_CH_1 "vasyapupgen/left"
#define MQTT_SERIAL_RECEIVER_CH_2 "vasyapupgen/right"
#define MQTT_SERIAL_RECEIVER_CH_3 "vasyapupgen/forward"
#define MQTT_SERIAL_RECEIVER_CH_4 "vasyapupgen/reverse"
#define MQTT_SERIAL_RECEIVER_CH_5 "vasyapupgen/ctrl"


// переменная для хранения HTTP-запроса:
String header;

// мотор 1:
int motor1Pin1 = 21; 
int motor1Pin2 = 19; 
//int enable1Pin = 14; 

// мотор 2:
int motor2Pin1 = 23; 
int motor2Pin2 = 22; 
//int enable2Pin = 32;

// переменные для свойств широтно-импульсной модуляции (ШИМ) 1-двигателя:
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 0;

// переменные для свойств широтно-импульсной модуляции (ШИМ) 2-двигателя:
const int freq2 = 30000;
const int pwmChannel2 = 1;
const int resolution2 = 8;
int dutyCycle2 = 0;


// переменные для расшифровки HTTP-запроса GET:
String valueString = String(5);
int pos1 = 0;
int pos2 = 0;


 //------------------- Работа с оптическими датчиками --------------------------

  int OnOff = 0; //сюда будет писаться, нажата ли клавиша в данный момент
  boolean CtrlState = false;
  String state = "Stop"; //сюда будет писаться состояние, т.е. куда едет машинка в данный момент
 
  volatile uint32_t lasttime1 = 0;
  volatile uint32_t lasttime2 = 0;

  volatile uint32_t last_check_time = 0; //время последнего вывода экран-результатов замера скорости вращения двигателей

  volatile uint32_t  ONEmotor_speed = 0;  //средняя скорость вращения 1 двигателя
  volatile uint32_t  ONEmotor_speed_last = 0;  //прежняя средняя скорость вращения 1 двигателя
  
  volatile uint32_t TWOmotor_speed = 0;  //средняя скорость вращения 2 двигателя
  volatile uint32_t TWOmotor_speed_last = 0;  //прежняя средняя скорость вращения 2 двигателя

  volatile uint32_t impulse_counter1 = 0; //счетчик импульсов 1 колеса
  volatile uint32_t impulse_counter2 = 0; //счетчик импульсов 2 колеса
  
//  boolean LastInterruptionState = false; //значение последнего прерывания
 
 volatile boolean InterruptionState = false; //значение последнего прерывания
  volatile boolean InterruptionState2 = false; //значение последнего прерывания
  
  String printing = "произошло прерывание1";  
  String printing2 = "произошло прерывание2";    
  
  volatile int PinState;
  
  //Куда подключены оптические датчики энкодера:
  int SensorPin1 = 13;
  int SensorPin2 = 14;


  //-----------------------------------------------------------------------------
  



//----------------------БЛОК РАБОТЫ С MQTT и WIFI --------------------

WiFiClient wifiClient;

PubSubClient client(wifiClient);

void setup_wifi() {
    delay(10);
    // We start by connecting to a WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    randomSeed(micros());
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP32Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(),MQTT_USER,MQTT_PASSWORD)) {
      Serial.println("connected");
      //Once connected, publish an announcement...
      client.publish("/icircuit/presence/ESP32/", "hello world");
      // ... and resubscribe
      client.subscribe(MQTT_SERIAL_RECEIVER_CH_1);
      client.subscribe(MQTT_SERIAL_RECEIVER_CH_2);
      client.subscribe(MQTT_SERIAL_RECEIVER_CH_3);
      client.subscribe(MQTT_SERIAL_RECEIVER_CH_4);
      client.subscribe(MQTT_SERIAL_RECEIVER_CH_5);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void callback(char* topic, byte *payload, unsigned int length) {
   
    char in[length+1]={0};
    memcpy(in,payload,length);  // функция копирует массв в другой - in. Это нужно, чтобы потом проще передавать этот массив, без указания его длины length

//   if (!Charge_Level)//выполняем, если только батарея не разряжена
//   {
    Motors (topic, in);
//   }
//   else
//   {
//    Serial.println("Батарея разряжена-замените батарею!");
//   }

//    Serial.println("-------new message from broker-----");
//    Serial.print("channel:");
//    Serial.println(topic);
//    Serial.print("data:");  
//    Serial.write(payload, length);
//    Serial.println();

}

//---------- Скорее всего - лишняя функция, ее можно вырубить --------------
void publishSerialData(char *serialData){
  if (!client.connected()) {
    reconnect();
  }
  client.publish(MQTT_SERIAL_PUBLISH_CH, serialData);
}

//--------------------------------------------------------------------



//--------------------------------------------------------------------



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

  Serial.setTimeout(500);// Set time out for 
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  reconnect();
  

  // переключаем контакты моторов в режим «OUTPUT»:
     pinMode(motor1Pin1, OUTPUT);
     pinMode(motor1Pin2, OUTPUT);
     pinMode(motor2Pin1, OUTPUT);
     pinMode(motor2Pin2, OUTPUT);


  // подключаем контакты оптических датчиков к пину, в режим «INPUT»:
     pinMode (SensorPin1, INPUT);
     pinMode (SensorPin2, INPUT);

  
  // подключаем реакцию на прерывания - к пинам датчиков:
     attachInterrupt(digitalPinToInterrupt(SensorPin1), sensor_test, HIGH);   
     attachInterrupt(digitalPinToInterrupt(SensorPin2), sensor_test2, HIGH);       


  // задаем настройки ШИМ-канала каждого из 2 двигателей:
     ledcSetup(pwmChannel, freq, resolution); // первый двигатель
     ledcSetup(pwmChannel2, freq2, resolution2); // второй двигатель
  
  // подключаем ШИМ-канал, к контактам для управления скоростью вращения каждого из 2 моторов:
     ledcAttachPin(motor1Pin1, pwmChannel); // первый двигатель
     ledcAttachPin(motor2Pin1, pwmChannel2); // второй двигатель
 
  // подаем на контакты ШИМ-сигнал с коэффициентом заполнения «0»:
     ledcWrite(pwmChannel, dutyCycle);
     ledcWrite(pwmChannel2, dutyCycle2);


  
}//setup

  
 


void loop(){

   client.loop();

   //-------- читаем уровень заряда батареи---------
//      Charge_Level ();
   //----------------------------------------------- 

   //--------- выводим скорости двигателей ---------
//      SpeedCheck3 ();
//        MotorTester ();
   //-----------------------------------------------
//Motors_controller ();
   
   if (Serial.available() > 0) {
     char mun[501];
     memset(mun,0, 501);
     Serial.readBytesUntil( '\n',mun,500);
     publishSerialData(mun);
   }
    
}


А вот функция, для управления двигателями(ниже):

// Функция, управляющая двигателями

  void Motors (char* topic, char ch [])
    {
              String s = topic;
              char temp;
              // выясняем, команда на вкл или выкл мотора
              if(ch[0]=='0')
              { 
//                Serial.println("команда: выключить двигатель");
                temp = '0'; // отключить мотор 
              } else if (ch[0]=='1')
              {
//                Serial.println("команда: включить двигатель");
                temp = '1'; // включить мотор
              }
               
//    volatile uint32_t stright_moving_time = 0; 
 
      volatile uint32_t turning_time = 0;  //сюда пишется время, как долго нажата клавиша поворота, во время езды вперед или назад

      int speed_temp_forward = 200; // переменная для ШИМ, при подруливании-во время движения вперед

  
  if ((s.indexOf("ctrl")>0)&&(temp=='1')) 
    {
      CtrlState =true;
      Serial.println("Нажат Ctrl");  
    }
  else if ((s.indexOf("ctrl")>0)&&(temp=='0'))
    {
      CtrlState =false;
      Serial.println("Ctrl отпущен");      
    }
  else if ((s.indexOf("left")>0)&&(temp=='1')) //ПОВОРОТ ВЛЕВО
    {

      if (state.equals ("Stop"))  //выполняем поворот, только если кнопка какого-либо движения отпущена. Это нужно для подруливания-иначе не получится
      {
          if (CtrlState) //если нажат Ctrl-поворачиваемся медленно
          {
              Serial.println("LeftSlow");  //  "Влево медленно"
              state = "LeftSlow";
                       
              ledcWrite(pwmChannel, 20);
              ledcWrite(pwmChannel2, 235);                
              digitalWrite(motor1Pin1, HIGH); 
              digitalWrite(motor1Pin2, LOW); 
              digitalWrite(motor2Pin1, LOW);
              digitalWrite(motor2Pin2, HIGH);    
          }
          else
          {
              Serial.println("Left");  //  "Влево"
              state = "Left";
                       
              ledcWrite(pwmChannel, 255);
              ledcWrite(pwmChannel2, 0);                
              digitalWrite(motor1Pin1, HIGH); 
              digitalWrite(motor1Pin2, LOW); 
              digitalWrite(motor2Pin1, LOW);
              digitalWrite(motor2Pin2, HIGH);         
          }        
      }
      else if (state.equals ("Forward")) // ПОДРУЛИВАНИЕ ВЛЕВО
         {
            Serial.println("Подруливание влево");  
            state = "Left_Correction";

          //-------подруливание происходит торможением левого двигателя, а правый крутится как и должен -----------

            ledcWrite(pwmChannel, 0);
//            ledcWrite(pwmChannel2, 0);
            digitalWrite(motor1Pin1, LOW); 
            digitalWrite(motor1Pin2, LOW); 
//            digitalWrite(motor2Pin1, LOW);
//            digitalWrite(motor2Pin2, LOW); 
                  
         }
        
    }
  else if ((s.indexOf("right")>0)&&(temp=='1')) // ПОВОРОТ ВПРАВО
    {
      if (state.equals ("Stop"))  //выполняем поворот, только если кнопка какого-либо движения отпущена. Это нужно для подруливания-иначе не получится
      {
          if (CtrlState) //если нажат Ctrl-поворачиваемся медленно
          {
              Serial.println("RightSlow");  //  "Вправо медленно"
              state = "RightSlow";
                     
              ledcWrite(pwmChannel, 235);
              ledcWrite(pwmChannel2, 20);
              digitalWrite(motor1Pin1, LOW); 
              digitalWrite(motor1Pin2, HIGH); 
              digitalWrite(motor2Pin1, HIGH);
              digitalWrite(motor2Pin2, LOW);    
          }
          else
          {
              Serial.println("Right");  //  "Вправо"
              state = "Right";
                     
              ledcWrite(pwmChannel, 0);
              ledcWrite(pwmChannel2, 255);
              digitalWrite(motor1Pin1, LOW); 
              digitalWrite(motor1Pin2, HIGH); 
              digitalWrite(motor2Pin1, HIGH);
              digitalWrite(motor2Pin2, LOW);    
          }              
      }
      else if (state.equals ("Forward")) // ПОДРУЛИВАНИЕ ВПРАВО
         {
            Serial.println("Подруливание вправо");  
            state = "Right_Correction";

          //-------подруливание происходит торможением правого двигателя, а левый крутится как и должен -----------

//            ledcWrite(pwmChannel, 0);
            ledcWrite(pwmChannel2, 0);
//            digitalWrite(motor1Pin1, LOW); 
//            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW); 
                  
         }      
      

    }
  else if ((s.indexOf("forward")>0)&&(temp=='1')) // ДВИЖЕНИЕ ВПЕРЕД
    {
      if (state.equals ("Stop"))  //выполняем поворот, только если кнопка какого-либо движения отпущена. Это нужно для подруливания-иначе не получится
      {
              Serial.println("Forward");  //  "Вперед"
              state = "Forward";
        
              ledcWrite(pwmChannel, 200); //0 - максимум оборотов 
              ledcWrite(pwmChannel2, 200); //0 - максимум оборотов
                                           
                     
              digitalWrite(motor1Pin1, LOW);
              digitalWrite(motor1Pin2, HIGH); 
              digitalWrite(motor2Pin1, LOW);
              digitalWrite(motor2Pin2, HIGH);              
      }
   
     }

//
////          //подруливание осуществляется так: начинаем замедлять один из двигателей
////
////          while ( !(temp=='0') )
////          {
////            turning_time = millis (); // время, когда началось отклонение. Это нужно, для того, чтобы построить "дугу" поворота влево
////
////            while (millis() - turning_time<=50)
////            {
////              ledcWrite(pwmChannel, speed_temp_forward); //0 - максимум оборотов
////            }
////
////              speed_temp_forward = speed_temp_forward+5;
////
////              if (speed_temp_forward >=255) //не даем установить больше максимума- который поддерживает ШИМ. Принудительно ограничиваем
////
////              {
////                speed_temp_forward = 255;
////              }
//              
////          }
//   
//     }
//  else if ((s.length()==0)&&(state.equals("Left_Correction"))) // ПОДРУЛИВАНИЕ ВЛЕВО-ЕСЛИ ОНО ТОЛЬКО НАЧАЛОСЬ
//      {
//          Serial.println("Подруливание влево");  
//          state = "Left_Correction";
////          uint32_t CorrectionStartTime = millis(); // время, когда началось отклонение. Это нужно, для того, чтобы построить "дугу" поворота влево
//
//          //пробуем медленный поворот влево
//          ledcWrite(pwmChannel, 55);
//          ledcWrite(pwmChannel2, 195);                
//          digitalWrite(motor1Pin1, HIGH); 
//          digitalWrite(motor1Pin2, LOW); 
//          digitalWrite(motor2Pin1, LOW);
//          digitalWrite(motor2Pin2, HIGH);
//   
//     }
  else if ((s.indexOf("reverse")>0)&&(temp=='1')) // ДВИЖЕНИЕ НАЗАД
    {
      if (state.equals ("Stop"))  //выполняем поворот, только если кнопка какого-либо движения отпущена. Это нужно для подруливания-иначе не получится
      {
            Serial.println("Reverse");  //  "Назад"
            state = "Reverse";
                    
            ledcWrite(pwmChannel, 55); //255 - максимум оборотов (Sensor 2)
            ledcWrite(pwmChannel2, 55); //255 - максимум оборотов (Sensor 1)
             
            digitalWrite(motor1Pin1, HIGH);
            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, HIGH);
            digitalWrite(motor2Pin2, LOW);                
      }
        
    }

  else if ( (state.equals ("Forward"))&&((s.indexOf("forward")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ДВИЖЕНИИ ВПЕРЕД
    {
            Serial.println("Forward stop");  //  "Стоп"
            state = "Stop";
                    
            ledcWrite(pwmChannel, 0);
            ledcWrite(pwmChannel2, 0);
            digitalWrite(motor1Pin1, LOW); 
            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW);  
    }
  else if ( (state.equals ("Reverse"))&&((s.indexOf("reverse")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ДВИЖЕНИИ НАЗАД
    {
            Serial.println("Reverse Stop");  //  "Стоп"
            state = "Stop";
                    
            ledcWrite(pwmChannel, 0);
            ledcWrite(pwmChannel2, 0);
            digitalWrite(motor1Pin1, LOW); 
            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW);  
    }
  else if ( ( (state.equals ("LeftSlow"))||(state.equals ("Left")) ) &&((s.indexOf("left")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ПОВОРОТЕ ВЛЕВО
    {
            Serial.println("Left Stop");  //  "Стоп"
            state = "Stop";
                    
            ledcWrite(pwmChannel, 0);
            ledcWrite(pwmChannel2, 0);
            digitalWrite(motor1Pin1, LOW); 
            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW);  
    }    
  else if ( ( (state.equals ("RightSlow"))||(state.equals ("Right")) ) &&((s.indexOf("right")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ПОВОРОТЕ ВПРАВО
    {
            Serial.println("Right Stop");  //  "Стоп"
            state = "Stop";
                    
            ledcWrite(pwmChannel, 0);
            ledcWrite(pwmChannel2, 0);
            digitalWrite(motor1Pin1, LOW); 
            digitalWrite(motor1Pin2, LOW); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW);  
    }
  else if (( state.equals ("Left_Correction")) &&((s.indexOf("left")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ПОВОРОТЕ ВЛЕВО
    {
            Serial.println("Left Correction Stop");  //  "Стоп"
            state = "Forward";
        
            ledcWrite(pwmChannel, 200); //0 - максимум оборотов 
            ledcWrite(pwmChannel2, 200); //0 - максимум оборотов
                    
            digitalWrite(motor1Pin1, LOW);
            digitalWrite(motor1Pin2, HIGH); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, HIGH);  
    }
  else if (( state.equals ("Right_Correction")) &&((s.indexOf("right")>0)&&(temp=='0')) )// ОСТАНОВКА ПРИ ПОВОРОТЕ ВЛЕВО
    {
            Serial.println("Right Correction Stop");  //  "Стоп"
            state = "Forward";
        
            ledcWrite(pwmChannel, 200); //0 - максимум оборотов 
            ledcWrite(pwmChannel2, 200); //0 - максимум оборотов
                    
            digitalWrite(motor1Pin1, LOW);
            digitalWrite(motor1Pin2, HIGH); 
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, HIGH);  
    }                    
         
//  else if (  ((s.indexOf("right")>0)&&(temp=='0'))||((s.indexOf("left")>0)&&(temp=='0'))||((s.indexOf("forward")>0)&&(temp=='0'))||((s.indexOf("reverse")>0)&&(temp=='0'))  )// ОСТАНОВКА
//    {
//          Serial.println("Stop");  //  "Стоп"
//          state = "Stop";
//                  
//          ledcWrite(pwmChannel, 0);
//          ledcWrite(pwmChannel2, 0);
//          digitalWrite(motor1Pin1, LOW); 
//          digitalWrite(motor1Pin2, LOW); 
//          digitalWrite(motor2Pin1, LOW);
//          digitalWrite(motor2Pin2, LOW);  
//    }    
          
  
} 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

видимо надо вводить режим защиты от пропадания канала связи

mu_ssina
Offline
Зарегистрирован: 30.08.2013

Да, хорошее замечание. Эту сторону дела я как то упустил!

mu_ssina
Offline
Зарегистрирован: 30.08.2013

Пришла такая мысль:принудительно устанавливать соединие "снизу-вверх"- то есть от esp32-к роутеру. Каким образом: в коде выше -есть кусок, который постит некое сообщение -в некий топик. Сделать так: чтобы каждые 0,3 секунды или чаще- esp32 постила сообщение в топик. Если соединение отсутствует-устанавливала его принудительно.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

mu_ssina пишет:

Пришла такая мысль:принудительно устанавливать соединие "снизу-вверх"- то есть от esp32-к роутеру. Каким образом: в коде выше -есть кусок, который постит некое сообщение -в некий топик. Сделать так: чтобы каждые 0,3 секунды или чаще- esp32 постила сообщение в топик. Если соединение отсутствует-устанавливала его принудительно.

Стесняюсь спросить... А было как ?

mu_ssina
Offline
Зарегистрирован: 30.08.2013

А было как в коде выше ;-)

Установлено соединение с WIFI,  MQTT-а дальше..дальше хрен бы с ними :-))) 

Но, как показывает практика, видимо этого недостаточно. Соединение то ли переходит в режим пониженного энергопотребления или не знаю чего там. И свзяь становится какой то нестабильной. Хотя, может проблема и в питании системы(его недостатке).

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Что конкретно вы имеете в виду говоря - "Если соединение отсутствует-устанавливала его принудительно.". А если сервер выключен, если оборван канал связи ? У вас всегда устанавливается связь снизу-вверх. Низ - клиент, верх - MQTT сервер. Причем  сервер не может вам что то отправить. Вы можете только получить ответ сервера. Сервер - доска на которой можно опубликовать или прочитать. Именно поэтому эту технологию не используют для управления чем либо. Как правило ее используют там где быстрая реакция клиента не нужна - датчики, системы мониторинга и пр.

mu_ssina
Offline
Зарегистрирован: 30.08.2013

brokly пишет:

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

Ага, читал про это. Но в реальности, после множества тестов- могу сказать совершенно ответственно: скорость передачи данных при такой технологии -с лихвой перекрывает все потребности по управлению машинкой. В миллисекундах время прохождения данных не скажу, но субъективно, выглядит как "мгновенно". 

Победить отвал сети(а возможно и просто подвисание системы из за питания от того же источника питания, что и двигатели) и всё - проблем нет.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Отвал сети у вас скорее всего из-за неправильно установленного периода жизни клиента, на самом клиенте или на сервере. Разбирайтесь. 

mu_ssina
Offline
Зарегистрирован: 30.08.2013

пока временно удалось справиться так: при потере соединения с wifi: переподключиться. При потере соединения с mqtt- то же самое.

Правда это мертвому припарки пока что :-B

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

  if (WiFi.status() != WL_CONNECTED)
     {
           Stop (); //при потере подключения-выключаем двигатели, чтобы машинка не уехала куда попало.
           setup_wifi(); //функция реконнекта
;  
     }
   
  if (!client.connected()) 
     {
      Stop (); //при потере подключения-выключаем двигатели, чтобы машинка не уехала куда попало.
      reconnect(); //функция реконнекта
     }

 

mu_ssina
Offline
Зарегистрирован: 30.08.2013

Всё -проблема с отвалом сети решена! Проблема оказалась вовсе не там, где ожидалось. В чем оказалась проблема(если вкратце): приход большого количества сообщений по MQTT внутри каждого из 5 каналов - приводил к окончательному стопору всей системы и вылету.

Как это происходило: веб интерфейс на сайте был настроен так, что пока нажата какая либо из управляющих кнопок на клавиатуре: 

↑↓←→ Ctrl   - шлется непрерывным потоком сообщение в определенный топик MQTT. Несмотря на то, что сообщение короткое (0 или 1), - от прихода сотен сообщений по 5 каналам и их разбора  - система просто умирала :-). Не исключаю, что я рукожоп и мой код кривой, а "риал труъ прогер" бы сделал как надо :-) Вот и нашел зато физические пределы esp32. 

Когда переделали веб интерфейс управления на сайте, чтобы при нажатии на любую управляющую кнопку- слалось только 1 сообщение в соответствующий топик и при отжатии кнопки-тоже только 1 сообщение туда же, - система стала работать супер стабильно. Просто чётко как часы! :-)