Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

Задержки передачи данных

Тема в разделе "ESP32 - все о железе", создана пользователем koldybins, 1 апр 2019.

  1. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Подскажите, кто знает. Мне надо сделать простой но надежный мост UART <-> WiFi. У меня есть DevKit v1 ESP32. Он сконфигурирован как Клиент и связывается по WiFi с ноутбуком. Программку сделал в ардуино. Делаю такой тест: На DevKit каждую секунду прилетают 20 Байт с порядковым номером. Он их пересылает на ноут и ноут сразу же обратно. Первые минут 10-15 каждый ответ приходит с задержкой 200-300 миллисекунд. Но потом появляются задержки до полутора минут. Потерь данных вроде нету, после задержки все пакеты сыпятся один за другим без потерь. Но как убрать или хотя бы сократить задержки? Может надо какой-нибудь приоритет где-нибудь повысить?

    Код (Text):
    1. void loop()
    2. {
    3. if(connection_status==connected_to_server)
    4.     {
    5.     //WiFi to UART Bridge
    6.     while (SCCclient.available() || Serial.available())
    7.         {  
    8.         if(SCCclient.available())
    9.             {
    10.             char rx = SCCclient.read();
    11.             Serial.write(rx);
    12.             }
    13.         if(Serial.available())
    14.             {
    15.             char tx = Serial.read();      
    16.             SCCclient.write(tx);
    17.             }
    18.         }
    19.     }
    20. }
     
  2. nikolz

    nikolz Гуру

    Сообщения:
    3.668
    Симпатии:
    399
    это может быль причиной
    Алгоритм Нейгла — Википедия
     
    koldybins нравится это.
  3. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Спасибо за ответ. Но если это действительно виноват алгоритм нейгла, почему это случается только иногда? И задержки могут быть разные от трех до ста секунд. Такое впечатление, что когда требуются ресурсы для других более важных процессов, передача данных останавливается. Может такое быть?
    Я только начал разбираться с esp32. Нет ли у него тонких настроек типа QoS?
    QoS — Википедия
     
  4. nikolz

    nikolz Гуру

    Сообщения:
    3.668
    Симпатии:
    399
    алгоритм нейгла у вас влияет со стороны компа обычно это задержки порядка 200 ms. Но вы можете их убрать в настройках.
    Более длительные задержки могут быть по иным причинам.
    Но маловероятно что по нехватке ресурсов. Скорее это какие-то зависания или засыпания.
    но угадать что у вас не так никто не может, телепатов нет.
     
    koldybins нравится это.
  5. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    :) завтра код в порядок приведу и тогда спрошу конкретнее.
    Все равно спасибо;)
     
  6. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Вот, посмотрите свежим взглядом. Может что-нибудь посоветуете:
    Код (Text):
    1. #include <WiFi.h>
    2. #include <Preferences.h>   // this library is used to get access to Non-volatile storage (NVS) of ESP32
    3.  
    4. //Digital INs/OUTs
    5. #define BTN_AP_en           12   // digital input
    6. #define PIN_LED_YELLOW      25    // digital input
    7. #define PIN_LED_GREEN         26    // digital output
    8. #define PIN_LED_RED           27    // digital input
    9.  
    10. //Version-Date
    11. #define Date                  2
    12. #define Month                  4
    13. #define Year                  19
    14.  
    15. #define NetworkConnection_successfully      20
    16. #define NetworkConnection_unsuccessfully      21
    17. #define AP_modus_on                          22
    18. #define hfm_connected_to_server             23
    19.  
    20. //****************************************************************************//
    21. //*  global variables
    22. //****************************************************************************//
    23. int status = WL_IDLE_STATUS;
    24. int connection_status=0;
    25.  
    26. //****************************************************************************//
    27. //*  global objects of the classes
    28. //****************************************************************************//
    29. WiFiClient SCCclient;       // generate object of the class WiFiClient for SCC-Server
    30. Preferences preferences;   // generate object of the class preference (Non-volatile storage)
    31.  
    32. //****************************************************************************//
    33. //*  FUNCTION int WiFi_NetworkConnect(char* ch_SSID, char* ch_Password)
    34. //*  Connect to network and return 1 (success) or -1 (no success)
    35. //****************************************************************************//
    36. int WiFi_NetworkConnect(char* ch_SSID, char* ch_Password)
    37. {
    38. Serial.println("Function WiFi_NetworkConnect()");
    39. int success;
    40.  
    41. //connect to WiFi network see https://www.arduino.cc/en/Reference/WiFiBegin
    42. WiFi.begin(ch_SSID, ch_Password);
    43.  
    44. //wait until connection is established or 10 seconds are gone
    45. char WiFiConnectTimeOut = 0;
    46. while ((WiFi.status() != WL_CONNECTED) && (WiFiConnectTimeOut < 100))
    47.     {
    48.     if(WiFiConnectTimeOut & 1)
    49.         {
    50.         digitalWrite(PIN_LED_RED, LOW);
    51.         digitalWrite(PIN_LED_GREEN, HIGH);
    52.         }
    53.     else
    54.         {
    55.         digitalWrite(PIN_LED_RED, HIGH);
    56.         digitalWrite(PIN_LED_GREEN, LOW);
    57.         }
    58.     if(WiFiConnectTimeOut & 2)Serial.print(".");
    59.     delay(100);
    60.     WiFiConnectTimeOut++;
    61.     }
    62.  
    63. // not connected
    64. if (WiFi.status() != WL_CONNECTED)
    65.     {
    66.     success = -1;
    67.     }
    68. else
    69.     {
    70.     success = 1;
    71.     }
    72.  
    73. return success;
    74. }
    75.  
    76. //****************************************************************************//
    77. //*  FUNCTION void SwitchLED(void)
    78. // Switch LEDs
    79. // LED Color must be LED_GREEN, LED_RED, LED_YELLOW or LED_OFF
    80. //****************************************************************************//
    81. void SwitchLED(void)
    82. {
    83. if(connection_status==hfm_connected_to_server)
    84.     {
    85.     digitalWrite(PIN_LED_RED, HIGH);
    86.     digitalWrite(PIN_LED_GREEN, LOW);
    87.     digitalWrite(PIN_LED_YELLOW, HIGH);
    88.     }
    89. else if(connection_status==NetworkConnection_successfully)
    90.     {
    91.     digitalWrite(PIN_LED_RED, HIGH);
    92.     digitalWrite(PIN_LED_GREEN, HIGH);
    93.     digitalWrite(PIN_LED_YELLOW, LOW);
    94.     }
    95. else
    96.     {
    97.     digitalWrite(PIN_LED_RED, HIGH);
    98.     digitalWrite(PIN_LED_GREEN, HIGH);
    99.     digitalWrite(PIN_LED_YELLOW, HIGH);
    100.     }
    101. }
    102.  
    103.  
    104. //****************************************************************************//
    105. //*  FUNCTION void connect_to_server()
    106. //****************************************************************************//
    107. void connect_to_server(void)
    108. {
    109. // Open Preferences with WLAN_Config namespace. Each application module, library, etc
    110. // has to use a namespace name to prevent key name collisions. We will open storage in
    111. // RW-mode (second parameter has to be false). Note: Namespace name is limited to 15 chars.
    112. // see https://github.com/espressif/arduino-esp32/blob/master/libraries/Preferences/examples/StartCounter/StartCounter.ino
    113. preferences.begin("WLAN_Config", false);
    114. // takeout WLAN_Config Strings out of the Non-volatile storage
    115. String eeprom_SSID = preferences.getString("SSID", "");
    116. String eeprom_Password = preferences.getString("Password", "");
    117. String eeprom_Server_IP = preferences.getString("Server_IP", "");
    118. String eeprom_Server_Port = preferences.getString("Server_Port", "");
    119.  
    120. // convert String to char*, see https://coderwall.com/p/zfmwsg/arduino-string-to-char
    121. char* ch_SSID = const_cast<char*>(eeprom_SSID.c_str());
    122. char* ch_Password = const_cast<char*>(eeprom_Password.c_str());
    123. char* ch_Server_IP = const_cast<char*>(eeprom_Server_IP.c_str());
    124.  
    125. Serial.println("Attempting to connect to WPA network...");  //
    126. Serial.print("SSID: ");
    127. Serial.println(eeprom_SSID);
    128. Serial.print("Pass: ");
    129. Serial.println(eeprom_Password);
    130. Serial.print("Server_IP: ");
    131. Serial.println(eeprom_Server_IP);
    132. Serial.print("Server_Port: ");
    133. Serial.println(eeprom_Server_Port);
    134.  
    135. // Connect to network
    136. if(WiFi_NetworkConnect(ch_SSID, ch_Password)==1)    //NetworkConnection is successfully
    137.     {
    138.     connection_status=NetworkConnection_successfully;
    139.     SwitchLED();
    140.     Serial.println("Connected to wifi");
    141.     Serial.print("IP address: ");
    142.     Serial.println(WiFi.localIP());
    143.     // Connect to Server
    144.     Serial.println("Starting connection to server...");
    145.     SCCclient.connect(ch_Server_IP,eeprom_Server_Port.toInt());
    146.     Serial.print("Status Connection: ");
    147.     if (SCCclient.connected())   //Connection to Server open
    148.         {
    149.         connection_status=hfm_connected_to_server;
    150.         Serial.println("connected to server");
    151.         }
    152.     else   // Connection to Server closed
    153.         {
    154.         Serial.println("Couldn't get a Server connection");
    155.         Serial.println("Restarting");
    156.         ESP.restart();
    157.         }
    158.     }
    159. else    //NetworkConnection is unsuccessfully
    160.     {
    161.     connection_status=NetworkConnection_unsuccessfully;
    162.     Serial.println("Couldn't get a wifi connection");
    163.     Serial.println("Restarting");
    164.     ESP.restart();
    165.     }
    166. }
    167.  
    168.  
    169. //****************************************************************************//
    170. //*  FUNCTION void setup()
    171. //****************************************************************************//
    172. void setup()
    173. {
    174. Serial.begin(115200);
    175. Serial.println("Version 0.0.0");
    176.  
    177. //Digital INs/OUTs config
    178. pinMode(PIN_LED_YELLOW, OUTPUT);
    179. pinMode(PIN_LED_RED, OUTPUT);
    180. pinMode(PIN_LED_GREEN, OUTPUT);
    181. pinMode(BTN_AP_en, INPUT_PULLUP);
    182. //attachInterrupt(digitalPinToInterrupt(BTN_AP_en), set_flag_check_btn_AP, FALLING);
    183. SwitchLED();
    184.  
    185. connect_to_server();
    186. }
    187.  
    188. //****************************************************************************//
    189. //*  FUNCTION void loop()
    190. //****************************************************************************//
    191. void loop()
    192. {
    193. //WiFi to UART Bridge
    194. if(connection_status==hfm_connected_to_server)
    195.     {
    196.     while (SCCclient.available() || Serial.available())
    197.         {  
    198.         if(SCCclient.available())
    199.             {
    200.             char rx = SCCclient.read();
    201.             Serial.write(rx);
    202.             }
    203.         if(Serial.available())
    204.             {
    205.             char tx = Serial.read();      
    206.             SCCclient.write(tx);
    207.             }
    208.         }
    209.     }
    210. }
    211.  
     
  7. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Выставил Debug-Level на "Verbose", получаю иногда такую ошибку:
    [E][WiFiClient.cpp:364] write(): 104
    Но после этой ошибки данные больше не проходят. Никто с такой ошибкой не сталкивался?
     
  8. nikolz

    nikolz Гуру

    Сообщения:
    3.668
    Симпатии:
    399
    посмотрите это
    WiFi Client Socket disconnecting · Issue #307 · espressif/arduino-esp32
     
    koldybins нравится это.
  9. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Спасибо за ссылку. Там правда ESP32 в режиме Access Point, но проблема похожа на мою. Решения проблемы так и не нашли. Очень жаль.
     
  10. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Получается никто на форуме не использует ESP32 для постоянного (24 часа в сутки) соединения? Если есть такие, бывают ли у вас обрывы соединения, задержки и потеря данных? И как вы с этим боретесь?
     
  11. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.253
    Симпатии:
    1.263
    С WiFi это сделать непросто, т.к. надо правильно настроить всё внешнее оборудование и саму ESP32.
    Самый простой путь - 'реконнектом' соединения через время или по любой ошибке.
    По вашему описанию, если гадать, то скорее всего включается какой-то спящий режим у WiFi. Если он не отключен в настройках принудительно, то обычно включается автоматически по условию: если за время DTIM проходит менее N пакетов...
     
    koldybins нравится это.
  12. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Похоже задержки были из-за сети. Сама ESP32 не причем. Взял отдельный роутер без выхода в интернет, повесил на него ESP32 как клиент и ноутбук как сервер, задержки ушли. Обрывы правда есть каждые 3 часа 20 минут, подозрительно периодично, поэтому наверняка из-за роутера. Но это не страшно, обрывы будут по-любому рано или поздно. Пока делал так. Если подтверждение пакета не пришло 5 раз, перестартовываю ESP32командой ESP.restart(); Рестарт на удивление проходит быстро, 1-2 секунды. Вы предлагаете реконнект, но у меня почему-то после него соединение не восстанавливалось. Можно пожалуйста простой пример реконнекта привести?
    Подскажите пожалуйста как именно, или где про это почитать.

    Благодарю
     
  13. koldybins

    koldybins Новичок

    Сообщения:
    9
    Симпатии:
    0
    Не подскажите, как включить управление потоком RTS CTS на UART0?
     
  14. pvvx

    pvvx Активный участник сообщества

    Сообщения:
    8.253
    Симпатии:
    1.263
    (3*60+20)*60=12000 сек.
    Посмотрите в настройках роутера,
    в DHCP: upload_2019-4-12_17-46-1.png
    в WiFi: upload_2019-4-12_17-46-34.png

    И если оно в "ротации сетевых ключей" то для Arduino подсказать что изменить на модуле будет сложно... Это уже кривость дров WiFi в ESP от её писателей.
    DHCP запросто обходится фиксированным IP на модуле...
     
    koldybins нравится это.

Поделиться этой страницей