• Система автоматизации с открытым исходным кодом на базе 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 обойдется дешевле.
 
Сверху Снизу