• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Постоянная загрузка данных.

ART_HA

Member
Интересная штука потому как есть ADC и не интересная, потому как нет WiFi.
И дело не в самом WiFi, а в том, что с WiFi не нужно приложение, достаточно любого браузера на любом девайсе.
 
погуглите Web Bluetooth API. Если чо, я его пока не использовал, но буду пробовать...
 

ART_HA

Member
Сам процесс подключения к устройству через Web Bluetooth - не для слабонервных.
Во-первых, API в целях безопасности сделано так, что соединение с устройством может быть программно инициировано только как результат клика на что-нибудь в браузере (именно поэтому во всех примерах всегда есть некая html кнопка, при нажатии на которую вызывается функция, содержащая вызов navigator.bluetooth.requestDevice() ).
При вызове requestDevice() Chrome открывает окно с надписью по центру "Совместимые устройства не найдены" (в этом месте нормальный пользователь уже завязал бы с таким сайтом, но мы не нормальный пользователь, верно? ;) Если подождать 10...30 секунд, то с вероятностью процентов 80 в списке начнут появляться обнаруженные устройства (соответственно, с вероятностью процентов 20 не появится ничего, и это не связано с уровнем сигнала или работоспособностью устройств - просто где-то что-то не срослось).
:p
 
Ну что сказать, есть такая буква в этом слове :) Но как я понял дело тут вовсе не в том, что операции чтения аналогового входа занимают много ресурсов, а в том что этот вход для своих целей использует WiFi :)
Фича эта известна еще с 2016 года https://github.com/esp8266/Arduino/issues/1634
Вот пример максимально упрощенного кода демонстрирующего проблему.
Если закомментировать в loop вызов delay(10) на esp8266 то Wifi глохнет.
На esp32 все работает без проблем и с delay и без него.

C:
#ifdef ESP32
 #include <WiFi.h>
 #define PIN 34
#else 
 #include <ESP8266WiFi.h>
 #define PIN A0
#endif
 
WiFiServer server(80);
int curRange=0;
char ssid[] ="ssid";
char pass[]= "pass";

String header_1 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
String html_1 = R"=====(
<!DOCTYPE html>
<html>
<head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
  <meta charset='utf-8'>
  <title>Hello world</title>
  <style>
    html{font-family: arial,sans-serif; font-size:100%}
    .big {font-size: 150%;}
  </style>
</head>
<body>
 <p><span id="rdm" class="big"></span></p>
</body>
<script>
  var host;
  function processReceivedCommand(data)
  {
      var value= parseInt(data);
      document.getElementById('rdm').innerHTML = value;
  }

  function loadData()
  {
    const request = new XMLHttpRequest();
    request.timeout=30000;
    request.open('GET', '/range');
    request.setRequestHeader('Content-Type', 'application/x-www-form-url');
    request.addEventListener('ontimeout', () => {
     setTimeout(loadData, 100);
    }); 
    request.addEventListener('readystatechange', () =>
    {
          if(request.readyState === 4)
          {
            processReceivedCommand(request.responseText);
            setTimeout(loadData, 100);
          }else{
            // console.log("readyState ="+request.readyState);
          }
    });
    request.send();
   }
   window.onload = function(e){
    host = window.location.hostname;
    loadData();
   }
</script>
 </html>
)====="; 


void setup() {
  Serial.begin(115200);
  initWeb(true);
  pinMode (PIN, INPUT);
}

void loop() {
  for(int i=0;i<10;i++)
  {
   int u = analogRead(PIN); 
  }
  #ifndef ESP32
  delay(10);
  #endif
  curRange=millis();
  processWeb();
}


void initWeb( bool softAP) {
  IPAddress local_ip(192,168,1,1);
  IPAddress gateway(192,168,1,1);
  IPAddress subnet(255,255,255,0);
  if(softAP){
   WiFi.softAP("Range", "1234567890");
   delay(500);
   WiFi.softAPConfig(local_ip, gateway, subnet);
   Serial.print(F("[Started] ")); Serial.println(WiFi.softAPIP());
   delay(100);
  }else{
   WiFi.begin(ssid,pass);
   int count = 0;
   while ( (WiFi.status() != WL_CONNECTED) && count < 17) {
      Serial.print(".");  delay(500);  count++;
      }
   if (WiFi.status() != WL_CONNECTED){
     Serial.println("");  Serial.print("Failed to connect to ");  Serial.println(ssid);
     while(1);
     }
     Serial.print(F("[CONNECTED]")); Serial.println(WiFi.localIP());   
  }
  server.begin();
}

void processWeb(){
  String header;
  unsigned long currentTime = millis();
  unsigned long previousTime = 0;
  const long timeoutTime = 2000;

  WiFiClient client = server.available();     // Check if a client has connected
  if (!client)  {  return;  }
  currentTime = millis();
  previousTime = currentTime;
  String currentLine = "";                // make a String to hold incoming data from the client
  while (client.connected() && currentTime - previousTime <= timeoutTime)
  { 
    currentTime = millis();
    if (client.available()) {
      char c = client.read();             // read a byte, then
      header += c;
      if (c == '\n'){   
        if (currentLine.length() == 0)
        {
          if (header.indexOf("GET /range") >= 0){
            client.println(String(curRange));
            client.println();
            break;
          } else if (header.indexOf("GET /") >= 0) {
              client.println( header_1 );
              client.println();
              client.println(html_1);
              client.println();
              break;
          }
        } else {
          currentLine = "";
        }
      } else if (c != '\r') {  currentLine += c;   } 
    }
  }
}
 
Ну очень интересная инфа, спасибо!
ну да, напрашивается новое правило работы с esp8266
если вам нужны GPIO входы и выходы, используйте внешние платки на i2c.

Сам процесс подключения к устройству через Web Bluetooth - не для слабонервных.
как там в комментах написано проблемы в основном у проприентарных девайсов, для самопальных все куда гуманнее.
 

ART_HA

Member
ну да, напрашивается новое правило работы с esp8266
если вам нужны GPIO входы и выходы, используйте внешние платки на i2c.
Если вместо одного корпуса потребуется два, то я предпочту bluepill с подцепленным к нему ESP-01 по uart.
И накаких нафиг лупов с делаями! :)

К счастью, по ходу дела мое тз немного изменилось - по объективным причинам отпала надобность в быстрой работе ацп.
Поэтому z попробовал запихнуть 8 запросов ацп в loop с delay(5) - вывод на экран работает нормально.
То есть в опытный образец пойдет именно этот вариант (в vemos d1 r1 остались незанятыми только 2 порта), посмотрим как
это все будет выглядеть в реале. По крайней мере при частоте вывода на экран 0.5 Гц меня сейчас вполне устроит даже delay(500). ;)

как там в комментах написано проблемы в основном у проприентарных девайсов, для самопальных все куда гуманнее.
Когда-то давно я имел танцы с бубнами с bluetooth, в результате чего у меня о нем остались весьма негативные впечатления.
Судя по приведенной мною выше цитате с тех пор ничего не изменилось. :confused:
 

pvvx

Активный участник сообщества
Сам процесс подключения к устройству через Web Bluetooth - не для слабонервных.
Во-первых, API в целях безопасности сделано так, что соединение с устройством может быть программно инициировано только как результат клика на что-нибудь в браузере (именно поэтому во всех примерах всегда есть некая html кнопка, при нажатии на которую вызывается функция, содержащая вызов navigator.bluetooth.requestDevice() ).
При вызове requestDevice() Chrome открывает окно с надписью по центру "Совместимые устройства не найдены" (в этом месте нормальный пользователь уже завязал бы с таким сайтом, но мы не нормальный пользователь, верно? ;) Если подождать 10...30 секунд, то с вероятностью процентов 80 в списке начнут появляться обнаруженные устройства (соответственно, с вероятностью процентов 20 не появится ничего, и это не связано с уровнем сигнала или работоспособностью устройств - просто где-то что-то не срослось).
:p
Вы наверно не пробовали ничего с BLE.
Время появления в списке устройства зависит от его интервала выдачи рекламы. Если устройство питается от CR2032, то естественно оно не будет гнать в эфир рекламу каждый десяток микросекунд. Экономия она такая - вот и ждите...
С WiFi вообще никто из обычных пользователей не справляется на смарте. Это надо открыть эксплорер, что-то вписать в панель, которая не дается так просто и норовит прыгнуть в поиск.
Потом, если все буквы, цифры и значки вписаны правильно - надеяться что оно соединится. Про подготовительные работы с устройствами WiFi простой обыватель никогда не справится - это надо вызывать "мастера". :p
Итог - BLE = нажать капу и выбрать устройство, WiFi - вызывать "мастера".
 

pvvx

Активный участник сообщества
И это ещё не всё для смарта. После перового обращения, если BLE устройство имеет "связывание", то эксплорер его находит не задумываясь :p
 

pvvx

Активный участник сообщества
Ну что сказать, есть такая буква в этом слове :) Но как я понял дело тут вовсе не в том, что операции чтения аналогового входа занимают много ресурсов, а в том что этот вход для своих целей использует WiFi :)
Фича эта известна еще с 2016 года https://github.com/esp8266/Arduino/issues/1634
Вот пример максимально упрощенного кода демонстрирующего проблему.
Это всё выдумки. Есть флаг в бинарных либах, который отрубает доступ к ADC у дров.
Так-же опрос дровами ADC совершенно не влияет на ваши опросы ADC.
Безусловно это всё не относится к Ардуино.
Общее у ADC в ESP8266 - он кривой и не может правильно работать при включенной части RF WiFi в чипе из-за наводок от неё. Разработка Espressif - что тут ещё сказать :)
Так-же брак в аппаратном PWM и не один.
 

pvvx

Активный участник сообщества
По ADC чип, предположительно, т.к. давно это было и всё не разгребал, определяет нагрев и рубит RF (throttling). Иначе бух и дымок от ESP8266 или стабилизатора питания, как это было в первых версиях SDK.
 

pvvx

Активный участник сообщества
Ну что сказать, есть такая буква в этом слове :) Но как я понял дело тут вовсе не в том, что операции чтения аналогового входа занимают много ресурсов, а в том что этот вход для своих целей использует WiFi :)
Фича эта известна еще с 2016 года https://github.com/esp8266/Arduino/issues/1634
Вот пример максимально упрощенного кода демонстрирующего проблему.
Если закомментировать в loop вызов delay(10) на esp8266 то Wifi глохнет.
На esp32 все работает без проблем и с delay и без него.

C:
#ifdef ESP32
#include <WiFi.h>
#define PIN 34
#else
#include <ESP8266WiFi.h>
#define PIN A0
#endif

WiFiServer server(80);
int curRange=0;
char ssid[] ="ssid";
char pass[]= "pass";

String header_1 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
String html_1 = R"=====(
<!DOCTYPE html>
<html>
<head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
  <meta charset='utf-8'>
  <title>Hello world</title>
  <style>
    html{font-family: arial,sans-serif; font-size:100%}
    .big {font-size: 150%;}
  </style>
</head>
<body>
<p><span id="rdm" class="big"></span></p>
</body>
<script>
  var host;
  function processReceivedCommand(data)
  {
      var value= parseInt(data);
      document.getElementById('rdm').innerHTML = value;
  }

  function loadData()
  {
    const request = new XMLHttpRequest();
    request.timeout=30000;
    request.open('GET', '/range');
    request.setRequestHeader('Content-Type', 'application/x-www-form-url');
    request.addEventListener('ontimeout', () => {
     setTimeout(loadData, 100);
    });
    request.addEventListener('readystatechange', () =>
    {
          if(request.readyState === 4)
          {
            processReceivedCommand(request.responseText);
            setTimeout(loadData, 100);
          }else{
            // console.log("readyState ="+request.readyState);
          }
    });
    request.send();
   }
   window.onload = function(e){
    host = window.location.hostname;
    loadData();
   }
</script>
</html>
)=====";


void setup() {
  Serial.begin(115200);
  initWeb(true);
  pinMode (PIN, INPUT);
}

void loop() {
  for(int i=0;i<10;i++)
  {
   int u = analogRead(PIN);
  }
  #ifndef ESP32
  delay(10);
  #endif
  curRange=millis();
  processWeb();
}


void initWeb( bool softAP) {
  IPAddress local_ip(192,168,1,1);
  IPAddress gateway(192,168,1,1);
  IPAddress subnet(255,255,255,0);
  if(softAP){
   WiFi.softAP("Range", "1234567890");
   delay(500);
   WiFi.softAPConfig(local_ip, gateway, subnet);
   Serial.print(F("[Started] ")); Serial.println(WiFi.softAPIP());
   delay(100);
  }else{
   WiFi.begin(ssid,pass);
   int count = 0;
   while ( (WiFi.status() != WL_CONNECTED) && count < 17) {
      Serial.print(".");  delay(500);  count++;
      }
   if (WiFi.status() != WL_CONNECTED){
     Serial.println("");  Serial.print("Failed to connect to ");  Serial.println(ssid);
     while(1);
     }
     Serial.print(F("[CONNECTED]")); Serial.println(WiFi.localIP());  
  }
  server.begin();
}

void processWeb(){
  String header;
  unsigned long currentTime = millis();
  unsigned long previousTime = 0;
  const long timeoutTime = 2000;

  WiFiClient client = server.available();     // Check if a client has connected
  if (!client)  {  return;  }
  currentTime = millis();
  previousTime = currentTime;
  String currentLine = "";                // make a String to hold incoming data from the client
  while (client.connected() && currentTime - previousTime <= timeoutTime)
  {
    currentTime = millis();
    if (client.available()) {
      char c = client.read();             // read a byte, then
      header += c;
      if (c == '\n'){  
        if (currentLine.length() == 0)
        {
          if (header.indexOf("GET /range") >= 0){
            client.println(String(curRange));
            client.println();
            break;
          } else if (header.indexOf("GET /") >= 0) {
              client.println( header_1 );
              client.println();
              client.println(html_1);
              client.println();
              break;
          }
        } else {
          currentLine = "";
        }
      } else if (c != '\r') {  currentLine += c;   }
    }
  }
}
При сборке вашего “скетча” в Arduino вываливается несколько сотен строк с разными wraning. Целая простыня. Среди них не найти своих ощибок…

1614690005422.png
И выводит какие-то иероглифы:
1614690027321.png
Исправьте – нехорошо это для “популярного среди антикваров продукта”.

Выбрал в меню “Range”, ввел пароль “1234567890”.
Ввел “192.168.1.1” в эксплорере и получил это:
1614690037903.png
Что опять не так с этим WiFi?
 
По ADC чип, предположительно, т.к. давно это было и всё не разгребал, определяет нагрев и рубит RF (throttling).
Ну там примерно так и написано, только народ утверждал что по этому выводу контролируется мощность передатчика.
Исправьте – нехорошо это для “популярного среди антикваров продукта”.
Попробуйте выставить плату "Lolin Wemos D1 R2". У меня ошибок нет. Играясь разными типами плат, можно добиться неработоспособности даже встроенного блинка(это не шутка, когда я впервые с этим столкнулся чуть не поседел :)). Ну и ошибку бы неплохо глянуть...

sshot-1.png

И выводит какие-то иероглифы:
Похоже на слетевшую скорость порта во время загрузки прошивки. Видите в конце [Started] 192.168.1.1 ? Вот тут только и подключился скетч.

Ввел “192.168.1.1” в эксплорере и получил это:
Познакомьтесь это меню вашего роутера. Отключите автоподключение своей домашней точки доступа в настройках телефона. Они все вумные стали, видят что на Range нет интернета и сразу переподключаются на более с их точки зрения правильную.
 

pvvx

Активный участник сообщества
Блин - а как мне подключиться к другой WiFi для Инет, когда в меню выбора WiFi торчит только соединение с этой "Range"?
На смартах аналогично. Как жить без Инет - даже тест прошивки не загрузить.
Ну там примерно так и написано, только народ утверждал что по этому выводу контролируется мощность передатчика.
Оно с ней и завязано, по дизасм.
Попробуйте выставить плату "Lolin Wemos D1 R2". У меня ошибок нет. Играясь разными типами плат, можно добиться неработоспособности даже встроенного блинка(это не шутка, когда я впервые с этим столкнулся чуть не поседел :)). Ну и ошибку бы неплохо глянуть...
Ошибки появятся в кодах самой Arduino - от её горе-писателей, когда включите опцию gcc показывать всю их кривизну.
Похоже на слетевшую скорость порта во время загрузки прошивки. Видите в конце [Started] 192.168.1.1 ? Вот тут только и подключился скетч.
Это кривость ESP8266. Кривизна в кодах ROM от Espressif.
Чип лепили на другой кварц - 40 МГц, но он не потянул (жрет много) и плюется на нестандартной скорости и вывод этого хламу не отключается.
Познакомьтесь это меню вашего роутера. Отключите автоподключение своей домашней точки доступа в настройках телефона. Они все вумные стали, видят что на Range нет интернета и сразу переподключаются на более с их точки зрения правильную.
Это на компе и проводная сеть у меня 192.168.1.1. Никаких "вумных" роутеров в жизнь не видел.

Есть вумные устройства, типа все с Андроид и Windows. На самых дешевых китайский роутерах-репитерах (которые дешевле ESP32+PSRAM) при подключении к их wifi сразу выпадает или меню этого репитера или прямиком в инет в "https://www.msn.com/" (или что там прописано), если у устройства есть связь с инет.
Ардуино на это неспособно уже много лет.
 

Flexstart

New member
Означает ли этот ответ, что альтернативы ESP8266 для моей задачи на сегодняшний день не существует?
 
Блин - а как мне подключиться к другой WiFi для Инет, когда в меню выбора WiFi торчит только соединение с этой "Range"?
Например в
C:
void setup() {
  Serial.begin(115200);
  initWeb(true);
  pinMode (PIN, INPUT);
}
Вместо initWeb(true) вписать initWeb(false) и указать ssid и pass своего роутера. Тогда код вместо создания точки, подключится к уже имеющейся сети.
Это же пример, а не приложение для постоянной работы, я его написал на скорую руку когда словил глюк c пропуском прерывания, для того чтобы исключить взаимосвязь с другими библиотеками. Тут ничего кроме родного wifi.h не используется. А потом еще на скорую руку адаптировал для ART_HA повыкидывав еще половину кода

Ошибки появятся в кодах самой Arduino
Тогда, боюсь, это не проблема моего скетча и не мне ее решать :)

Это кривость ESP8266.
У меня кстати сейчас не плюется. заливаю раз за разом - терминал чистый. Хотя такую красоту я видел. мне она не мешает. в теории можно попробовать поставить скорость заливки скетча=скорости порта.

Это на компе и проводная сеть у меня 192.168.1.1.
Тогда вам надо менять сетку примеру. Например банально закомментировать следующие строки
C:
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
По умолчанию есп-шка сядет на 192.168.4.1 просто мне в моей изначальной задаче это было неудобно.

Никаких "вумных" роутеров в жизнь не видел.
А чей ASUS RT-AX92U мы тогда походу похакали? :)

Ардуино на это неспособно уже много лет.
Я решил что вы с телефона на нее зашли. Мой редми все время с нее соскакивать пытался на домашнюю wifi сетку. А раз вы зашли по локалке, у вас в сети, банальная коллизия случилась, образовались два компа с одним адресом - ардуина и ваш основной роутер. роутер стоял раньше по списку вот вы на него и попали.
 

pvvx

Активный участник сообщества
Я решил что вы с телефона на нее зашли. Мой редми все время с нее соскакивать пытался на домашнюю wifi сетку. А раз вы зашли по локалке, у вас в сети, банальная коллизия случилась, образовались два компа с одним адресом - ардуина и ваш основной роутер. роутер стоял раньше по списку вот вы на него и попали.
И это столько проблем с WiFi чтобы передать 10 байт в сек?
Это всё вместо кнопки "коннект" и выбора устройства в BLE?
Пользователь будет в шоке.
Напишите алгоритм как не свершить колизии по IP адресам (и как оставить пользователю подключенный инет по WiFi).
 

pvvx

Активный участник сообщества
GermanIvanov - В принципе можно не выдумывать – во многих устройствах это решается через BLE. Пользователь выбирает в меню BLE устройство, ему, с согласия пользователя, передается название и пароль местной AP WiFi, к которой подключен смарт. Далее уже WiFi в устройстве соединяется с местной AP.

Но это не катит для носимых устройств. Остается только BLE.
 
Напишите алгоритм как не свершить колизии по IP адресам (и как оставить пользователю подключенный инет по WiFi).
Я же вроде написал? Замените в моем первоначальном примере функцию initWeb на следующую

Код:
void initWeb( bool softAP) {
  WiFi.begin("ssid вашего роутера wifi","пароль к нему");
  int count = 0;
  while ( (WiFi.status() != WL_CONNECTED) && count < 17) {
     Serial.print(".");  delay(500);  count++;
  }
  if (WiFi.status() != WL_CONNECTED){
    Serial.println("");  Serial.print("Failed to connect to ");  Serial.println(ssid);
    while(1);
  }
  server.begin();
}
espшка подключится к вашему роутеру, получит от него какой-то ip и будет там постоянно висеть. получится и интернет есть, и esp в сети.


Но это не катит для носимых устройств. Остается только BLE.
А кто запрещает поднять на роутере выделенную сетку специально для esp-шек? И пароля ей не надо. Как вошел так сразу и законнектился.
 

ART_HA

Member
Ну там примерно так и написано, только народ утверждал что по этому выводу контролируется мощность передатчика.
Не забываем, что это только версии и ничего более. :)
На практике же вывод такой: мы говорим ESP8266, подразумеваем delay.
Можно ли ли обойти это правило?
Наверняка можно, но замена ESP8266 на ESP32 обойдется дешевле.
 
Сверху Снизу