Как я могу зациклить свой код? Например, через 30 минут?

esp8266 wifi loop

Итак, у меня есть код, который записывает температуру и влажность с помощью датчика DHT22. После получения значений он отправляет их на веб-страницу с помощью метода PHP $_GET, где они импортируются в БД и по электронной почте (с использованием PHP). Но это происходит только тогда, когда я загружаю код в свой ESP8266; как я могу узнать, что встроенная функция цикла отправляет ее каждые 30 минут или заданное время?

#include <ESP8266WiFi.h>
#include "DHT.h"

const char* ssid     = "bbox2";      // SSID локальной сети
const char* password = "azerty";   // Пароль в сети

WiFiClient client;
char servername[]="lucasdebelder.be";  // удаленный сервер, к которому мы будем подключаться
String result;

float temperature;
float humidity;

#define DHTPIN 14  

#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  dht.begin();
  delay(2000);
  Serial.begin(115200);
  Serial.println("Connecting");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.println("Connected");
  delay(1000);
  readSensor();
  String temperatureString = String(temperature,1);
  String humidityString = String(humidity,1);
  sendDataToServer(temperatureString,humidityString);
}

void loop() {

}

void sendDataToServer(String temperature, String humidity)
{
  if (client.connect(servername, 80)) {  //запускает соединение клиента, проверяет наличие соединения
    Serial.println("connected");
    client.println("GET /send_temperature.php?temperature="+temperature+"&humidity="+humidity+" HTTP/1.1"); //Отправляем данные
    client.println("Host: lucasdebelder.be");
    client.println("Connection: close");  //закрываем постоянное соединение 1.1
    client.println(); //конец запроса на получение
  } 
  else {
    Serial.println("connection failed"); //сообщение об ошибке, если клиент не подключается
    Serial.println();
  }

 while(client.connected() && !client.available()) delay(1); //ждём данных
  while (client.connected() || client.available()) { //подключено или данные доступны
    char c = client.read(); // получает байт из буфера Ethernet
      result = result+c;
    }

  client.stop(); //остановим клиент
  Serial.println(result);

}


void readSensor()
{

  humidity = dht.readHumidity();
  temperature = dht.readTemperature();
  Serial.println("Temperature:");
  Serial.println(temperature);
  Serial.println("Humidity:");
  Serial.println(humidity);

}

, 👍1

Обсуждение

см. пример BlinkWithoutDelay, @Juraj

@Juraj Спасибо за ответ, можете объяснить немного подробнее? Какой код мне смотреть?, @Zanic L3

этот урок и код ... https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay, @jsotola


2 ответа


0

Вы выполняете соответствующую функцию только в функции setup(), которая вызывается один раз при запуске ESP. После этого функция loop() вызывается многократно. Функция setup() предназначена для «настройки» вашего кода для его функциональности, которая затем выполняется в функции loop(). Например, вы начинаете подключение Wi-Fi и подключаетесь к сети там, потому что вам нужна сеть для вашей основной функциональности.

Так что вам нужно поместить код от readSensor() до (включая) sendDataToServer() в функцию loop(). Это выполнит этот код повторно.

Затем вам нужно ввести некоторое понятие времени, иначе ваш код будет выполняться очень быстро, фактически переполняя ваш веб-сервер. Самый простой способ — добавить вызов delay(30000), который задержит код на 30 секунд. Но использование delay не считается хорошим стилем кодирования, поскольку это по сути занятое ожидание, и вы не можете делать ничего другого в это время.

Таким образом, чтобы иметь возможность добавлять другие функции в будущем, вы можете реализовать концепцию времени с помощью неблокирующего кода. Возьмите пример BlinkWithoutDelay из Arduino IDE в качестве примера. Он использует функцию millis(), которая подсчитывает миллисекунды с момента запуска. Вы сохраняете временную метку последнего выполнения вашего кода и ждете, пока разница между текущим временем (заданным millis()) и вашей временной меткой не станет больше 30 с. В это время ESP может делать другие вещи, так как он все еще проходит через функцию loop() без прерывания. Затем после временного интервала вы выполняете код и сбрасываете временную метку на текущее время.

,

Спасибо большое за этот ответ @chrisl, но как мне реализовать что-то подобное в моем коде? Я могу читать и понимать код, но писать для меня это что-то другое. Не могли бы вы попробовать взглянуть на мой код? Спасибо, @Zanic L3

Вы действительно понимаете, что делает код? Первая часть, о которой я говорил, это просто копирование и вставка измерения и отправка кода из setup() в loop(). Вторая часть - это просто пример BlinkWithoutDelay. Вам нужно поместить код, который у вас сейчас есть в loop(), в предложение if(millis() - timestamp > interval). Это описано в [Документации Arduino](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)., @chrisl

Вам действительно нужно понять обе концепции, которые я пытался объяснить, иначе вы не сможете написать свой собственный код. Прочтите документацию. Пройдите начальный курс по Arduino, где объясняются функции setup() и loop(). Мы не можем написать ваш код за вас. Если что-то в моем объяснении непонятно, я постараюсь объяснить это подробнее., @chrisl


1

Как указано в предыдущем ответе. Код, который должен выполняться более одного раза, следует вызывать в цикле. Но в этом случае следующее решение тоже будет работать.

Вы можете завершить настройку вызовом функции deepsleep(time_us), которую можно найти в библиотеке ESP. Это отключит все, кроме встроенных RTC (часов реального времени). Таким образом, схема потребляет очень мало тока (20 мкА). Это может быть очень полезно, если схема питается от батареи.

У RTC есть сигнал на GPIO 16 (D0 на NodeMcu), который будет удерживаться на ВЫСОКОМ уровне, пока заданное время не достигнуто. Если заданное время достигнуто, сигнал будет НИЗКИМ.

Если вы подключите GPIO 16 к выводу RST(сброс), это заставит ESP8266 снова запуститься. И, таким образом, setup() будет выполнен снова.

,