Ардуино задержка не точная - PullRequest
0 голосов
/ 04 октября 2019

Я новичок в Arduino, я строю простую схему датчика, используя DHT22 и модуль Thark Dev SparkFun ESP8266, который программируется с помощью Arduino.

В моем коде цикла я хочу, чтобы мое устройство ожидало5 минут, поэтому я поставил в конце delay(300000). Проблема заключается в том, что, когда я просматриваю в своей базе данных временную метку, когда данные собираются датчиком, иногда он ждет 2 минуты, иногда 1 и т. Д.

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

Я уверен, что с моим кодом должно быть что-то не так, но я впервые пытаюсь использовать C ++ и Arduino, поэтому не смог разобратьсячто только пока. Любая помощь?

Это мой код:


#include <DHT.h>

#include <ESP8266WiFi.h>

#include <DNSServer.h>            
#include <ESP8266WebServer.h>     
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic

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

// here I declare the variable of humidity and temperature. 
// every time it loops, it should get data from the sensor into 
// temp1 and hum1, then check it against temp and hum if there 
// are any changes in the values 
float temp;
float hum;
float temp1;
float hum1;

int red_light_pin = 16;
int green_light_pin = 12;
int blue_light_pin = 13;

// Server, file, and port
const char hostname[] = "laundryireland.tk";
const String uri = "/write_data?";
const String arguments[3] = {"serial=","&temp=","&hum="};
const int port = 80;

String serialNumber;

WiFiClient client;


void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
 {
  analogWrite(red_light_pin, red_light_value);
  analogWrite(green_light_pin, green_light_value);
  analogWrite(blue_light_pin, blue_light_value);
}

void setup() {

  pinMode(red_light_pin,OUTPUT);
  pinMode(green_light_pin,OUTPUT);
  pinMode(blue_light_pin,OUTPUT);
  RGB_color(0,0,255);

  WiFi.persistent(false);
  WiFiManager wifiManager;

  //Initialize Serial
  Serial.begin(9600);
  dht.begin();
  delay(100);

  //Connect to WiFi
  Serial.println("Connecting...");
  wifiManager.autoConnect();
  while (WiFi.status() != WL_CONNECTED ) {

    delay(500);
    Serial.print(".");
  }


  //Show that we are connected
  Serial.println("Connected!");
  Serial.println(WiFi.localIP());

  serialNumber = WiFi.macAddress();

}

void loop() {
  delay(2000);
  temp1 = dht.readTemperature();
  hum1 = dht.readHumidity();
  while (temp1 == NULL || hum1 == NULL){
      RGB_color(255,0,0);
      delay(5000);
      temp1 = dht.readTemperature();
      hum1 = dht.readHumidity();
    }

// THIS IS MY IF STATEMENT TO CHECK FOR
// CHANGES IN TEMP OR HUM

  if (temp > temp1+1 || temp < temp1-1 || hum > hum1+1 || hum < hum1-1){
    temp = temp1;
    hum = hum1;

    RGB_color(0,255,0);
    Serial.print("Temperature: ");
    Serial.println(temp);
    Serial.print("Humidity: ");
    Serial.println(hum);

    Serial.println("Testing flask ");
    if ( client.connect(hostname,port) == 0 ) {
      Serial.println("Flask Test Failed!");
    } else {
      Serial.println("Flask Test Success!");
      client.print("GET " + uri + arguments[0] + serialNumber +
                    arguments[1] + temp +
                    arguments[2] + hum +
                    " HTTP/1.1\r\n" +
                    "Host: " + hostname + "\r\n" +
                    "Connection: close\r\n" +
                    "\r\n");
      delay(500);

      while (client.available()){
        String ln = client.readStringUntil('\r');
        Serial.print(ln);
      }
    }

    client.stop();
    Serial.println();
    Serial.println("Connection closed");

  } else {
    Serial.println("temp or hum not changed");
    RGB_color(255,255,0);
  }

// THIS SHOULD WAIT 5min BEFORE NEXT CHECK

  delay(300000);
}

Вот так выглядит моя база данных:

database


Решение

Указано комментаторами и хорошо описано в принятом ответе, использование mills () вместо delay () решает проблему с помощью «fake»время задержки.

Кроме того, проблема передачи данных, даже если разница между предыдущим обновлением и текущим была меньше 1;была просто логическая проблема с моим оператором if-else. Я решил с этим кодом:

 int deltaT = abs(temp-temp1);
    int deltaH = abs(hum-hum1);

    if (deltaT >= 1 || deltaH >= 1){
    // code here

1 Ответ

2 голосов
/ 04 октября 2019

Функция цикла будет вызвана снова через 300000 мсек ПОСЛЕ окончания цикла. Таким образом, время до следующей записи - это все время обработки * 2000 в начале * времена для функций dht.readTempera () и dht.readHumidity ();* время отправки байтов на последовательный выход * время client.connect и время передачи по сети ... * и 300000 в конце

Лучший подход - получить текущий миллис () изсистема для проверки на 300000 мсек с момента последнего чтения. Затем рассчитайте следующий раз для измерения и затем выполните обработку

. Вы можете использовать статическую переменную для этого, чтобы сохранить код:

void loop() {
  static unsigned long next = 0;
  unsigned long now = millis();

  if (now > next) {
    … do processing
    next = now + 300000;
  } // if
} // loop()
...