Не в то время отправляется сообщение

Делаю датчик влажности с выводом данных в Telegram, вроде все работает, НО сообщение с данными о влажности (newMsg) отправляется не сразу при запросе в Telegram, а когда срабатывает цикл loop, т.е. получается так:

  1. я делаю запрос в Telegram
  2. Программа считывает сообщение и ждет, когда loop узнает влажность
  3. Выводится влажность вместе с loop

Как можно исправить?

#define WIFI_SSID "ssid"
#define WIFI_PASS "pass"
#define BOT_TOKEN "token"
    
#include <FastBot.h>
#include <GyverHTU21D.h>
GyverHTU21D htu;
FastBot bot(BOT_TOKEN);

void setup() {
  Serial.begin(115200);
  htu.begin();
  bot.attach(newMsg);
  connectWiFi();
  bot.setChatID("id");
  bot.sendMessage("Hello! Let's check the humidity!");
}
 

  


void loop() {
  bot.tick();
  htu.requestHumidity();                    // Запрашиваем преобразование
  delay(100);
  Serial.println(htu.getHumidity());
  if (htu.getHumidity() < 30){
    bot.sendMessage("Low humidity");
    
  }

  else if (htu.getHumidity() > 60){
    bot.sendMessage("High humidity");
    
    }
    delay(10000);
  }

void newMsg(FB_msg& msg) { 
  // ответить
  htu.requestHumidity();                    // Запрашиваем преобразование
  delay(100);
  if (htu.readHumidity()) {
    Serial.println("Hum");
    Serial.println(htu.getHumidity());
  }
  
} 
void connectWiFi() {
  delay(2000);
  
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    
    if (millis() > 15000) ESP.restart();
  }
  
}

Ответы (1 шт):

Автор решения: Герман Борисов

Если стоит задача на arduino выполнять несколько задач через фиксированные (но отличающиеся для каждой задачи) интервалы времени, то общий подход такой (далее по тексту слово task заменить на название задачи):

Для каждой задачи заводятся переменная unsigned long task_time, содержащая последнее значение времени запуска данной задачи и константа unsigned long task_period, содержащая интервал запуска

Каждое задание желательно оформить в виде отдельной функции task_proc().

В начале цикла loop() в переменную unsigned long current_time сохраняем значение millis() — текущее время в миллисекундах.

Далее для каждого задания в цикле добавляется такой блок

if (current_time - task_time >= task_period)
{
        task_time = current_time;   
        task_proc();
}

Соответственно у вас будет две задачи:

  1. Вывод влажности в Serial раз в 10*1000 миллисекунд (task заменить на, например, serial_task)
  2. Опрос бота раз в 3600 миллисекунд, это число из описания используемой вами библиотеки Гайвера (task заменить на, например, bot_task)

Дополнительно конкретно в вашем проекте я бы сделал следующее:

Вынес бы инициализацию и чтение влажности отдельно, пусть выполняется каждый цикл.

htu.requestHumidity();
delay(100);
htu.readHumidity();

А в обеих функциях выводил бы кэшированное значение htu.getHumidity() без предварительного чтения, так как оно уже подготовлено.

→ Ссылка