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

Выполнение программы без подключенных клиентов

dimaxa7

New member
Код для основного цикла очень простой:

ArduinoOTA.handle();
server.handleClient();

receiveData();

Однако без подключенных клиентов он не переходит к receiveData(); (эта функция ответственна за данные, получаемые с модуля nRF24l01). Если же добавить Serial.println(), то цикл начинает крутиться и все работает как задумано (принимаем данные с nRF, а если подключаются клиенты, то показываем всю инфу). Serial.println() не является полноценным решением, должно же быть что-то лучше, мб он без клиентов уходит с сон, или просто дальше функции server.handleClient() не идет почему-то?

http://weathertmpbme.ddns.net/ с пустыми логином/паролем - сайт с измеряемыми данными, работает-тестируется когда ничего не делаю. Пока вся система в самом начальном состоянии, будет допиливаться и дополняться как будет свободное время.
 
Последнее редактирование:

dimaxa7

New member
Покажите ваш код.
Что именно? В сетапе подключается к роутеру, поднимается сервер, пара страниц. Все это делалось по примерам из интернета и ничего нового нет. А цикл loop полностью описан и показана проблема, что без клиентов функция, получаются данные, не работает, цикл просто ее пропускает, что ли.

Код:
loop () {
   ArduinoOTA.handle();
   server.handleClient();

   receiveData();
}
 

CodeNameHawk

Moderator
Команда форума
Ошибка в строке N , ах да я не вижу кода, вы что думаете, что в сетапе не сумеете сделать ошибку или тем более в receiveData();
 

dimaxa7

New member
Ошибка в строке N , ах да я не вижу кода, вы что думаете, что в сетапе не сумеете сделать ошибку или тем более в receiveData();
Ошибок в коде нет, Вы, видимо, суть не поняли. Вот так будет вывод в консоль
Код:
void loop(void) {
  ArduinoOTA.handle();
  server.handleClient();

  Serial.println();
  receiveData();
}

void receiveData() {
  char buffRx[30];
  byte pipeNo;

  while (radio.available()) {
    radio.read(&buffRx, sizeof(buffRx));
    Serial.println(buffRx);
  }
}
А вот так - нет.
Код:
void loop(void) {
  ArduinoOTA.handle();
  server.handleClient();

  // Serial.println();
  receiveData();
}

void receiveData() {
  char buffRx[30];
  byte pipeNo;

  while (radio.available()) {
    radio.read(&buffRx, sizeof(buffRx));
    Serial.println(buffRx);
  }
}
Компилируется и выводится все отлично, просто нужна возможность собирать данные все время, а не ждать активного соединения.

Код для сетапа, хотя хз зачем он нужен
Код:
void setup(void) {
  Serial.begin(115200);

  init_nRF24l01();
  init_SPI();

  init_server();

  init_OTA();
  initTMPBMEsheet();

  configTime(timezone * 3600, 0, "pool.ntp.org", "time.nist.gov");
    if (debug) Serial.print("\nWaiting for time");
    while (!time(nullptr)) { if (debug) Serial.print("."); delay(200);} if (debug) Serial.println("");


  //Serial.println(ESP.getFlashChipRealSize());
}

void init_nRF24l01() {
  radio.begin();                                     
  radio.setChannel(0x65);                            
  radio.setDataRate     (RF24_250KBPS);                
  radio.setPALevel      (RF24_PA_HIGH); 
  radio.openReadingPipe (1, 0x1234567890LL);         
  radio.startListening  ();

  radio.printDetails();
}

const char* www_username = "";
const char* www_password = "";
const char* ssid = "ххх";
const char* password = "ххх";

void init_server() {
  WiFi.mode(WIFI_STA); //режим клиент
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(WiFi.localIP());

  server.on("/", handleApi);
  server.on("/xml", handleXML);
  server.on("/reset", []() {                    // Перезагрузка
    if (!server.authenticate(www_username, www_password))
      return server.requestAuthentication();
    server.send(200, "text/plain", "ok");
    ESP.restart();
  });
  server.onNotFound(handleNotFound);          //  Cтраница ошибки

  server.on ("/stock0", handlePageStock0);
  server.on ("/stock1", handlePageStock1);
  server.on ("/stock2", handlePageStock2);
  server.on ("/stock3", handlePageStock3);

  server.on ("/data0.json", processCSV_temp36);
  server.on ("/data1.json", processCSV_tempBME);
  server.on ("/data2.json", processCSV_humBME);
  server.on ("/data3.json", processCSV_presBME);

  server.begin();
}

void init_SPI() {
  SPI.setHwCs(true);
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
}

void init_OTA() {
  ArduinoOTA.setHostname("ESP8266-00001");
  ArduinoOTA.begin();
}

void initTMPBMEsheet() {
  TMPBME[0]._name = "Temperature TMP36";
  TMPBME[0]._unit = "&degC";

  TMPBME[1]._name = "Temperature BME280";
  TMPBME[1]._unit = "&degC";

  TMPBME[2]._name = "Humidity BME280";
  TMPBME[2]._unit = "%";

  TMPBME[3]._name = "Pressure BME280";
  TMPBME[3]._unit = "mBar";
}
и подключение библиотек
Код:
#include <time.h>

#include <ArduinoOTA.h>
#include <WiFiUdp.h>

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>

#include <nRF24L01.h>
#include <RF24.h>

#define debug true
 

Юрий Ботов

Moderator
Команда форума
Ошибок в коде нет,
Когда все работает - значит ошибок нет, а вот если что то не так - значит они есть!

Например,
  • char buffRx[30];
  • byte pipeNo;
  • while (radio.available()) {
  • radio.read(&buffRx, sizeof(buffRx));
  • Serial.println(buffRx);
Вот тут вы объявляете буфер длиной 30, потенциально весь его заполняете и не ставите в конце нуль-символ После чего у println срывает крышу и он печатает в порт всю память пока не нарвется на какой нибудь нолик или просто виснет. Надо как то так:
Код:
char buffRx[31];
byte pipeNo; // видимо это тоже ошибка? нафига он там нужен?

while(radio.available()) {
  int cnt = radio.read(&buffRx, sizeof(buffRx)-1); // посмотрите в описании библиотеки как именно возвращается количество прочтенных байт, я с nRF не работал и пишу "как это обычно бывает"
  buffRx[cnt+1] = 0;
  Serial.println(buffRx);
 

dimaxa7

New member
Когда все работает - значит ошибок нет, а вот если что то не так - значит они есть!

Например,

Вот тут вы объявляете буфер длиной 30, потенциально весь его заполняете и не ставите в конце нуль-символ После чего у println срывает крышу и он печатает в порт всю память пока не нарвется на какой нибудь нолик или просто виснет. Надо как то так:
Код:
char buffRx[31];
byte pipeNo; // видимо это тоже ошибка? нафига он там нужен?

while(radio.available()) {
  int cnt = radio.read(&buffRx, sizeof(buffRx)-1); // посмотрите в описании библиотеки как именно возвращается количество прочтенных байт, я с nRF не работал и пишу "как это обычно бывает"
  buffRx[cnt+1] = 0;
  Serial.println(buffRx);
Если бы он вообще что-то печатал - было бы дело, но, если подробнее и еще раз, то дело обстоит так: открываю порт, тишина. Открываю в браузере сайт - вижу данные в порту и на сайте все работает. Закрываю вкладку - опять данные в порт не идут. Потом дописываю в loop вывод ничего(Serial.println()), и о чудо! всегда данные в порт сыплются с датчика. Насчет окончания - все продумано. Пакет может быть только 30 символов и последний изначально нуль-символ (так уже отправляет датчик-модуль, иначе не отправляет вообще). Это не единственные данные, которые надо принимать. Пакеты предполагаются разных типов: данные с датчика, которые обрабатываются одним путем, служебные данные (об ошибках, состоянии батареи и тд), поэтому их надо ждать всё время, но, увы, до него, почему-то, не доходит, пока не подключиться к серверу. Рассчитывал на ответ из разряда: "да это же так библиотека ESP8266WebServer так работает, пока нет клиентов - усыпляет ESP, допиши вот это вот тут и будет хорошо", но, видимо, не распространенная проблема.

pipeNo используется для определения номера трубы, с которой читаем пришедший пакет, библиотека nRF, но пока такой функционал не нужен. Не мешает и пусть будет.
 

CodeNameHawk

Moderator
Команда форума
Рассчитывал на ответ из разряда: "да это же так библиотека ESP8266WebServer так работает, пока нет клиентов - усыпляет ESP, допиши вот это вот тут и будет хорошо", но, видимо, не распространенная проблема.
Вместо того, чтобы рассказывать сказки
Ошибок в коде нет,
займитесь отладкой.
Раз самая простая (Serial.print ) отпадает, кто мешает поморгать светодиодом? Так вы сможете узнать чем занимается ваша программа, пока вы за ней не наблюдаете..
 

CodeNameHawk

Moderator
Команда форума
Потом дописываю в loop вывод ничего(Serial.println()), и о чудо! всегда данные в порт сыплются с датчика.
Чего тут удивляться,
Код:
  while (radio.available()) {
    radio.read(&buffRx, sizeof(buffRx));
вы сразу, после появления данных, без проверки их количества, читаете весь буфер, а он возможно еще не успел наполниться.
Вот простая задержка (Serial.print) и помогает. Это теория а так только отладкой поймаете ошибку.(Возможно она окажется простой логической ошибкой, а не ошибкой в коде)
 
Сверху Снизу