• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 удалить из обсуждения... Ну а ответы я, собственно, получил, за что большое спасибо тем, кто реально подсказывал =)
 
Сверху Снизу