• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Странности в работе при подключении к роутеру

BARS__

New member
Всем привет.
Работаю с ESP8266. Написал простенькую программу в Arduino IDE. Смысл программы - общаться с МК по UART и служить сетевой картой между ним и сетью (а именно пробрасывать MODBUS пакеты). Настройки модуля задаются через html страничку. И с этой частью программы все хорошо. Сложности возникли именно при работе с сетью. Скорее даже, не так. Сложности возникли у роутера при работе с ESP8266. Т.е. я задаю название сети, пароль, IP и порт. Модуль сообщает, что подключение установлено, но вот роутер его в таблице DHCP не отображает. Соответственно, пинг идет очень нестабильно, как будто роутер не может правильно составить маршрут. Такое ощущение, что ESP не выдает свой MAC, в результате чего, роутер не может корректно построить маршруты (по опыту работы с чипами Ethernet, такое поведение маршрутизаторов наблюдается именно в случае отсутствия MAC, но могу ошибаться). Подключаюсь к сети я вот так:

Код:
/**
* Соединение с WiFi
*/
bool ConnectWiFi(const char *ssid, const char *pass, String IP) {
  // Три попытки соединения по WiFi
   
  uint8_t i = 0, j = 0, ip[4];

  i = IP.indexOf('.');
  ip[0] = IP.substring(0, i).toInt();

  j = IP.indexOf('.', i+1);
  ip[1] = IP.substring(i+1, j).toInt();

  i = IP.indexOf('.', j+1);
  ip[2] = IP.substring(j+1, i).toInt();

  j = IP.length();
  ip[3] = IP.substring(i+1, j).toInt();

  IPAddress ip_addr(ip[0], ip[1], ip[2], ip[3]);
  IPAddress ip_gate(ip[0], ip[1], ip[2], 1);
  IPAddress ip_subnet(255, 255, 255, 0);

  WiFi.mode(WIFI_AP_STA);
  WiFi.config(ip_addr, ip_gate, ip_subnet);

  for(int i = 0; i < 3; i++) {
     
    WiFi.begin(ssid, pass);
 
    for(int j = 0; j < 10; j++){

      if(WiFi.status() == WL_CONNECTED){
        wifi_set_sleep_type(NONE_SLEEP_T);

         return true;
      }
     
      UART_Buffer_Tx[0] = 0x2A;
      UART_Buffer_Tx[1] = 0x01;
      UART_Buffer_Tx[2] = WIFI_CONNECTING;
      Serial.write(UART_Buffer_Tx, 3); 

      delay(1000);
    }
  }

    return false;
}
В чем может быть проблема? Может еще какие-то настройки надо задать?
 

nikolz

Well-known member
Всем привет.
Работаю с ESP8266. Написал простенькую программу в Arduino IDE. Смысл программы - общаться с МК по UART и служить сетевой картой между ним и сетью (а именно пробрасывать MODBUS пакеты). Настройки модуля задаются через html страничку. И с этой частью программы все хорошо. Сложности возникли именно при работе с сетью. Скорее даже, не так. Сложности возникли у роутера при работе с ESP8266. Т.е. я задаю название сети, пароль, IP и порт. Модуль сообщает, что подключение установлено, но вот роутер его в таблице DHCP не отображает. Соответственно, пинг идет очень нестабильно, как будто роутер не может правильно составить маршрут. Такое ощущение, что ESP не выдает свой MAC, в результате чего, роутер не может корректно построить маршруты (по опыту работы с чипами Ethernet, такое поведение маршрутизаторов наблюдается именно в случае отсутствия MAC, но могу ошибаться). Подключаюсь к сети я вот так:
В чем может быть проблема? Может еще какие-то настройки надо задать?
Вы не полностью настроили WiFi ESP
например не установили автоматическое восстановление соединения и др
посмотрите документацию по SDK там все есть и примеры в каталоге SDK.
------------------
если пишите на дурине то смотрите соответствующие функции и примеры в инете
 

Юрий Ботов

Moderator
Команда форума
А вы уверены что вам нужно именно "WiFi.mode(WIFI_AP_STA);"? Может "WiFi.mode(WIFI_STA);"? А то вы создаете "дубликат" роутера отчего у всей сети потихоньку едет крыша.
 

BARS__

New member
Вы не полностью настроили WiFi ESP
В начале программы запрещаю сон wifi_set_sleep_type(NONE_SLEEP_T); Что-то больше не нашел, что еще требуется настроить. Если не трудно, киньте в меня ссылкой на апнот по настройке...

Может "WiFi.mode(WIFI_STA);"?
Да, почему-то забыл поменять. Но погоды это не сделало. ESP все так же не виден в таблице DHCP роутера. Пробовал даже MAC вручную задать через wifi_set_macaddr(), но это тоже ничего не меняет. Заметил странную особенность, модуль временами (если несколько раз его выкл-вкл) начинает работать стабильно и пинг не превышает 20мс, в остальное время он работает так:
upload_2019-2-4_23-3-9.png

При этом другие участники сети пингуются стабильно. Та же Wi-Fi розетка:
upload_2019-2-4_23-4-53.png

Я вообще не могу понять, почему роутер не видит ESP. На мой взгляд именно в этом кроется причина кривой работы модуля. Какие есть мысли по этому поводу?
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@BARS__ весь код давайте. Или, если секрет, то прошейте примеры и убедитесь , что в примерах работает нормально.
 

BARS__

New member
Код не секрет, ничего там такого сложного нет, чтобы он секретом стал =)
Код:
String content, st;
String STA_SSID;
String STA_PASS;
String STA_IP;
String STA_PORT;

#define WIFI_CONNECTED 2
#define WIFI_DISCONNECTED 0
#define WIFI_CONNECTING 1

uint32_t IP[4];

ESP8266WebServer server(80);

IPAddress ip_receiver;
int port_receiver = 0;

int setup_mode, len, packetSize;

unsigned char packetBuffer[255];

uint8_t UART_Buffer_Rx[50], UART_Buffer_Tx[50], UART_Len_Rx = 0, RX_LEN = 1, RX_OK = 0;

const char* AP_SSID = "Amplifier_Network";

String networks[50];
uint8_t networks_count = 0;

WiFiUDP Udp;

void launchWeb();
bool ConnectWiFi(const char *ssid, const char *pass, String IP);

void setup() {
  ESP.eraseConfig(); // Чистим конфиг

  wifi_set_sleep_type(NONE_SLEEP_T); // Запрещаем сон

  Serial.begin(921600); // Настройка скорости UART

  Serial.setTimeout(1000);

  delay(500);

  EEPROM.begin(144); // Инит EEPROM
 
  uint8_t len;

  len = EEPROM.read(0); // Читаем имя сети из памяти

  if(len > 0 && len < 35){
   
    STA_SSID = "";
 
    for (int i = 1; i < len+1; ++i){
      STA_SSID += char(EEPROM.read(i));
    }
  }
 
  len = EEPROM.read(34); // Читаем пароль из памяти

  if(len > 4 && len < 35){
    STA_PASS = "";

    for (int i = 35; i < len+35; ++i){
      STA_PASS += char(EEPROM.read(i));
    }
  }
 
  len = EEPROM.read(86); // Читаем статический IP из памяти

  if(len > 8 && len < 17){
    STA_IP = "";

    for (int i = 87; i < len+87; ++i){
      STA_IP += char(EEPROM.read(i));
    }
   
    uint8_t i = 0, j = 0;
    String temp_ip = "";

    i = STA_IP.indexOf('.');
    IP[0] = STA_IP.substring(0, i).toInt();

    j = STA_IP.indexOf('.', i+1);
    IP[1] = STA_IP.substring(i+1, j).toInt();

    i = STA_IP.indexOf('.', j+1);
    IP[2] = STA_IP.substring(j+1, i).toInt();

    j = STA_IP.length();
    IP[3] = STA_IP.substring(i+1, j).toInt();
  }

  len = EEPROM.read(104); // Читаем порт из памяти

  if(len > 3 && len < 7){
    STA_PORT = "";
 
    for (int i = 105; i < len+105; ++i){
      STA_PORT += char(EEPROM.read(i));
    }
  }

  EEPROM.end();

  setup_mode = false;

  WiFi.scanNetworks(); // Сканируем видимые точки

  if(STA_SSID[0] != 0xFF){
    WiFi.disconnect();
    delay(500);
    WiFi.mode(WIFI_OFF); // Перезапускаем Wi-Fi
    delay(500);

    // Шлем отчет к МК
    UART_Buffer_Tx[0] = 0x2A;
    UART_Buffer_Tx[1] = 0x02;
    Serial.write(UART_Buffer_Tx, 2);
    Serial.println(STA_SSID);

    UART_Buffer_Tx[0] = 0x2A;
    UART_Buffer_Tx[1] = 0x01;
    UART_Buffer_Tx[2] = WIFI_CONNECTING;
    Serial.write(UART_Buffer_Tx, 3); 
 
    if(ConnectWiFi(STA_SSID.c_str(), STA_PASS.c_str(), STA_IP)){ // Коннектимся
       Udp.begin(STA_PORT.toInt()); // Если законнектились, запускаем UDP

       // Шлем отчет в МК
       UART_Buffer_Tx[0] = 0x2A;
       UART_Buffer_Tx[1] = 0x01;
       UART_Buffer_Tx[2] = WIFI_CONNECTED;
       Serial.write(UART_Buffer_Tx, 3); 
       delay(10);                
       UART_Buffer_Tx[0] = 0x2A;
       UART_Buffer_Tx[1] = 0x03;
       Serial.write(UART_Buffer_Tx, 2);
       Serial.println(WiFi.localIP());
       delay(10);
       UART_Buffer_Tx[0] = 0x2A;
       UART_Buffer_Tx[1] = 0x04;
       Serial.write(UART_Buffer_Tx, 2);
       Serial.println(Udp.localPort());
    }else{
       UART_Buffer_Tx[0] = 0x2A;
       UART_Buffer_Tx[1] = 0x01;
       UART_Buffer_Tx[2] = WIFI_DISCONNECTED;
       Serial.write(UART_Buffer_Tx, 3);    
    }
  }else{
       UART_Buffer_Tx[0] = 0x2A;
       UART_Buffer_Tx[1] = 0x01;
       UART_Buffer_Tx[2] = WIFI_DISCONNECTED;
       Serial.write(UART_Buffer_Tx, 3); 
  }
}

void loop() {
  if(setup_mode){ // Запуск собственной сети и web страницы
    server.handleClient();
  }else{    // Прием данных и пересылка их в UART
    packetSize = Udp.parsePacket();
    if(packetSize){
      Udp.read(packetBuffer, packetSize);

      ip_receiver = Udp.remoteIP();
      port_receiver = Udp.remotePort();

      Udp.endPacket();

      Serial.write(packetBuffer, packetSize);
    }
  }

  while(Serial.available() && UART_Len_Rx < RX_LEN){ // Прием данных по UART
    UART_Buffer_Rx[UART_Len_Rx] = Serial.read();
   
    if(UART_Buffer_Rx[0] == 0x2A || UART_Buffer_Rx[0] == 0x2B){
      RX_LEN = 2;
    }else{
      if(UART_Len_Rx < 6){
        RX_LEN = 7;
      }else{
        RX_LEN = 6+UART_Buffer_Rx[5];
      }
    }

     UART_Len_Rx++;
  }
 
  if(UART_Len_Rx >= RX_LEN){ // Анализ принятых по UART данных
      /**/
  }
}

/**
* Соединение с WiFi
*/
bool ConnectWiFi(const char *ssid, const char *pass, String IP) {
    
  uint8_t i = 0, j = 0, ip[4];

  i = IP.indexOf('.');
  ip[0] = IP.substring(0, i).toInt();

  j = IP.indexOf('.', i+1);
  ip[1] = IP.substring(i+1, j).toInt();

  i = IP.indexOf('.', j+1);
  ip[2] = IP.substring(j+1, i).toInt();

  j = IP.length();
  ip[3] = IP.substring(i+1, j).toInt();

  IPAddress ip_addr(ip[0], ip[1], ip[2], ip[3]); // Статический IP
  IPAddress ip_gate(ip[0], ip[1], ip[2], 1); // Шлюз
  IPAddress ip_subnet(255, 255, 255, 0); // Маска подсети

  WiFi.mode(WIFI_STA); // Переводим модуль в режим клиента
  WiFi.config(ip_addr, ip_gate, ip_subnet); // Задаем адреса

  for(int i = 0; i < 3; i++) { // Три попытки соединения по WiFi
     
    WiFi.begin(ssid, pass); // Коннектимся к сети
 
    for(int j = 0; j < 10; j++){ // Ждем 10 секунд

      if(WiFi.status() == WL_CONNECTED){ // Коннект успешен
        wifi_set_sleep_type(NONE_SLEEP_T);
        return true;
      }
     
      UART_Buffer_Tx[0] = 0x2A;
      UART_Buffer_Tx[1] = 0x01;
      UART_Buffer_Tx[2] = WIFI_CONNECTING;
      Serial.write(UART_Buffer_Tx, 3); 

      delay(1000);
    }
  }

    return false;
}
 

BARS__

New member
это вы не перезапускаете а отключаете.
Верно, а потом включаю в нужном режиме. Где-то читал, что это необходимо делать. Попробую убрать.

есть переменная bssid_set
Прочитаю про это.

Поэтому нет надобности это делать в скрипте.
Про какой скрипт вы говорите?

не в обиду будет сказано, но ваш скрипт - это ужас.
изучите примеры которых тысячи в инете и в каталоге SDK
Согласен, ужас. Но я привык писать ПО, имея полный доступ к железу. Ардуйня - это ж кошмар, ничего более убогого еще не встречал, но разобраться в ней быстрее. А по поводу примеров, из них и взята работа с сетью.
 

CodeNameHawk

Moderator
Команда форума
Согласен, ужас. Но я привык писать ПО, имея полный доступ к железу.
Причем тут железо и дурацки написанный код?
Ардуино еще один язык программирования( надстройка если желаете) и на нем красиво кладутся команды.

Вся кривобокость кода от не нежелания читать документацию. Явный пример этого выполнение в цикле команд:
WiFi.begin(ssid, pass);
wifi_set_sleep_type(NONE_SLEEP_T);
Посмотрите примеры в студио, там есть как подключаться по Static IP и другие примеры.

Ну и есть режим отладки, который покажет изменения состояния сети.
 

BARS__

New member
Причем тут железо и дурацки написанный код?
Железо не при чем, зато убогая IDE очень даже.

Ардуино еще один язык программирования
Вот вы пытаетесь умничать, а даже не знаете, что такое ардуйня. Начнем с того, что это программно-аппаратная платформа. И языка программирования по имени "Ардуино" не существует в природе, это обычный С/С++. Ардуйня дает лишь набор кривых библиотек.

Явный пример этого выполнение в цикле команд:
Ну и поясните, в чем же кривизна. На счет этой функции (да, это НЕ команды, это вызов функций!!!) тут лишняя, но WiFi.begin(ssid, pass); явно нет. Да оно и не участвует в работе, подключение происходит еще на первой итерации цикла.

Посмотрите примеры в студио
Что есть "студио"?
 
Последнее редактирование:

nikolz

Well-known member
ардуино нормальная среда и позволяет быстро разрабатывать софт для различных MCU.
Но в силу универсальности, решения как правило не оптимальны.
Поэтому , если жестких требований к софту нет, то можно быстро и на халяву получить нормальное решение для различных чипов.
А с учетом наличия хорошей поддержки - это народная (халявная) среда разработки, которой нет равных.
 

nikolz

Well-known member
Никто. Я ее уже установил и разбираюсь.


О как. Только что вы сказали, что это ЯЗЫК! Ну и крпипастой у вас тоже так себе получается умничать, ибо на сайте по вашей же ссылке сказано:
Arduino is the world’s leading open-source hardware and software ecosystem.
Что написано? Программно-аппаратная экосистема, то бишь комплекс.


Да пока что вы придумываете, ибо в Arduino IDE пишут на С/С++. Не стоит выдергивать предложения из контекста.


Так к я ж и не спорю, код кривой. Я и не утверждал, что он идеален.


Ну вот назвать ее средой даже язык не поворачивается, скорее слабеньким блокнотом, где можно написать код и заслать его компилятору. И софт то она быстро разрабатывает, но кривой и без человеческого доступа к железу.
Есть народная мудрость - Дареному коню в зад(т е в зубы) не смотрят.
Еще есть басня Эзопа - лиса и виноград.
Никто же Вас не заставляет работать в Ардуине.
Я ее не использую, так как пишу все на CИ и на Lua.
Но альтернативы Ардуине, тем более бесплатной, для обучения и для любителей фактически нет.
относительно кривого кода - не соглашусь.
Зависит от танцора.
 

nikolz

Well-known member
В том то все и дело, что железа не больше, как был один проц так один и остался.

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

Оцените в деньгах, заказ на разработку проги такому профи, когда из проца надо выжать все соки и цену железа по мощнее и заказа проги у любителя или составления ее самому.
приведите пример как Вы ESP8266 замените более мощным процессором с таким же железом и потреблением и блоком питания.
-------------------
что же касается денег за разработку. то чудес не бывает.
если это у вас хобби то сами делаете, если это бизнес то считаете.
====================
вот вам конкретный пример
попробуйте заменить
я на ESP8266 собрал спектрометр 200-800нм.
В нем всего три детали - голографическая решетка с плоским полем TCD1304 и ESP8266
при этом выполняется управление TCD на скорости 2 мггц и ввод значений спектра на скорости 400 кгц 12 бит. Данные передаются по wifi спектры могут интегрироваться до 10 сек.
Ваш вариант замены?
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@BARS__ вы бы поспокойнее. В принципе вы оба правы.
Что за язык программирования используется для Arduino?
На официальном сайте пишут: "...is programmed using the Arduino programming language (based on Wiring)".
Фактически — нет никакого особого языка программирования и программы пишутся на C/C++, а компилируются и собираются с помощью широко известного avr-gcc (в версии для Windows — WinAVR).
Все особенности сводятся к тому, что имеется набор библиотек, включающий в себя некоторые функции (вроде pinMode) и объекты (вроде Serial), а при компиляции Вашей программы среда разработки создает временный .cpp файл, в который кроме Вашего кода включается еще несколько строчек, и полученный результат скармливается компилятору а затем линковщику с нужными параметрами.
 

Сергей_Ф

Moderator
Команда форума
@BARS__ посмотрите в сторону Sloeber IDE
Это настроенная "экосистема" Arduino в IDE Eclipse. Возможно вам понравится.
А флуд и оффтоп, с вашего позволения, я бы почистил в теме.
 

BARS__

New member
Это настроенная "экосистема" Arduino в IDE Eclipse.
Спасибо, погляжу и ее. Пока нравится UDK =)

с вашего позволения, я бы почистил в теме.
Полностью согласен, еще бы CodeNameHawk удалить из обсуждения... Ну а ответы я, собственно, получил, за что большое спасибо тем, кто реально подсказывал =)
 
Сверху Снизу