Arduino простой таймер l oop без задержки () - миллис () не работает? - PullRequest
0 голосов
/ 20 апреля 2020

Есть некоторый код Arduino для временных регистраторов, который ОЧЕНЬ РАБОТАЕТ ....!

Я создал процедуру OTA, чтобы я мог обновлять их удаленно, однако delay () l oop I Я должен был гарантировать, что только зарегистрированные температуры каждые 15 минут в настоящее время вызывают проблемы, поскольку он эффективно замораживает arduino за 15 минут, а это означает, что OTA не будет работать, пока он находится в этом состоянии.

Некоторые предложения говорят, что просто перевернуть вместо этого в millis (), но я не могу заставить это работать, и в данный момент он регистрирует ~ 20 записей каждую секунду.

В идеале я просто хочу, чтобы delay_counter считывал значение в DELAY_TIME, а затем запускал остальной код и сброс счетчика.

Может кто-нибудь помочь мне и указать, что я делаю глупо в моем коде ???


// v2 Temp sensor
// Connecting to Home NAS

#include <DHT.h>
#include <DHT_U.h>


#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <InfluxDbClient.h>



#define SSID "xxx" //your network name
#define PASS "xxx" //your network password
#define VersionID "v3"


#define SensorName "ServerUnit" //name of sensor used for InfluxDB and Home Assistant
// Temp Sensor 1 - GardenTropical
// Temp Sensor 2 - GardenRoom
// Temp Sensor 3 - Greenhouse
// Temp Sensor 4 - OutsideGreenhouse
// Temp Sensor 5 - ServerUnit

// Connection Parameters for Jupiter InfluxDB
#define INFLUXDB_URL "http://192.168.1.5:8086"
#define INFLUXDB_DB_NAME "home_assistant"
#define INFLUXDB_USER "xxx"
#define INFLUXDB_PASSWORD "xxx"


// Single InfluxDB instance
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);
// Define data point with measurement name 'DaveTest`
Point sensor("BrynyneuaddSensors");


#define PORT 80
#define DHTPIN 4     // what pin the DHT sensor is connected to
#define DHTTYPE DHT22   // Change to DHT22 if that's what you have
#define BAUD_RATE 115200 //Another common value is 9600
#define DELAY_TIME 900000 //time in ms between posting data to Home Server
unsigned long delay_counter = 0;

DHT dht(DHTPIN, DHTTYPE);


//this runs once
void setup()
{
  Serial.begin(BAUD_RATE);

  // Connect to WIFI
  WiFi.begin(SSID, PASS);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print("*");
  }

  // Initialise OTA Routine
   ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());



  //initalize DHT sensor
  dht.begin();

  // set InfluxDB database connection parameters
  client.setConnectionParamsV1(INFLUXDB_URL, INFLUXDB_DB_NAME, INFLUXDB_USER, INFLUXDB_PASSWORD);

  // Add constant tags - only once
  sensor.addTag("device", SensorName);

  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
    Serial.println(client.getServerUrl());
    Serial.println("Exiting DB Connection");

  }

}

//this runs over and over
void loop() {
  ArduinoOTA.handle();


  float h = dht.readHumidity();
  Serial.print("Humidity: ");
  Serial.println(h);
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float c = dht.readTemperature();
  Serial.print("Temperature: ");
  Serial.println(c);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(c)) {
    Serial.println("Reading DHT22 Failed, exiting");
    return;
  }

  //update Influx DB channel with new values
  updateTemp(c, h);

  Serial.print("Writing to InfluxDB: ");


  //INFLUXDB - clear temp data so it doesn't repeat
  sensor.clearFields();

  // Update Influx DB
  sensor.addField("Temperature", c);
  sensor.addField("Humidity", h);

  Serial.println(sensor.toLineProtocol());
  // Write data
  client.writePoint(sensor);

  //wait for delay time before attempting to post again
  if(millis() >= DELAY_TIME){
        delay_counter += 0;
        }

    //Increment Delay Counter
    delay_counter++;
}


bool updateTemp(float tempC, float humid) {

  WiFiClient client;    // Create a WiFiClient to for TCP connection


  Serial.println("Receiving HTTP response");
  while (client.available()) {
    char ch = static_cast<char>(client.read());
    Serial.print(ch);
  }
  Serial.println();


  Serial.println("Closing TCP connection");
  client.stop();
  return true;
}

Ответы [ 3 ]

3 голосов
/ 20 апреля 2020

Установите TimerObject. это , похоже, то, что вам нужно.

  1. Загрузите код Arduino TimerObject с github и следуйте инструкциям по установке
  2. #include "TimerObject.h"
  3. Создание функции обратного вызова
  4. Создание TimerObject
  5. Настройка TimerObject и периодический вызов update() в вашем loop():
// make sure to include the header
#include "TimerObject.h"

...

// setup your TimerObject
TimerObject* sensor_timer = new TimerObject(15 * 60 * 1000); // milliseconds

...

// define the stuff you want to do every 15 minutes and
// stick it in a function
// not sure what from your loop() needs to go in here
void doSensor()
{
  float h = dht.readHumidity();
  Serial.print("Humidity: ");
  Serial.println(h);
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float c = dht.readTemperature();
  Serial.print("Temperature: ");
  Serial.println(c);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(c)) {
    Serial.println("Reading DHT22 Failed, exiting");
    return;
  }

  //update Influx DB channel with new values
  updateTemp(c, h);

  Serial.print("Writing to InfluxDB: ");


  //INFLUXDB - clear temp data so it doesn't repeat
  sensor.clearFields();

  // Update Influx DB
  sensor.addField("Temperature", c);
  sensor.addField("Humidity", h);

  Serial.println(sensor.toLineProtocol());
  // Write data
  client.writePoint(sensor);
}

...

// add the timer setup to your setup()
// probably at the end is a good place
void setup()
{
    ...
    // lots of stuff above here
    sensor_timer->setOnTimer(&doSensor);
    sensor_timer->Start();
}

// modify your loop() to check the timer on every pass
void loop()
{
    ArduinoOTA.handle();

    sensor_timer->Update();
}

Если вы не хотите ждать 15 минут для первого вызова doSensor, вы можете явно вызвать его в конце вашей функции setup() перед запуском таймера.

1 голос
/ 20 апреля 2020

Сделай симоле и используй легкий код:

const unsigned long timeIntervall = 15*60*1000; // 15 minutes
unsigned long timeStamp = 0;

void setup(){....}

void loop() {
  ArduinoOTA.handle(); // is running all the time

  // Code in this section only runs every timeIntervall - rollover safe
  if(millis() - timeStamp > timeIntervall ){

  float h = dht.readHumidity();
 ......
  // Write data
  client.writePoint(sensor);

  timeStamp = millis();  // reset the timer
   }
}
1 голос
/ 20 апреля 2020

Вот простой пример использования millis ()


int last_report = -777;//dummy value

int REPORT_INTERVAL = 15 *60 ; // 15 minutes

void loop() {

  ArduinoOTA.handle();

  int interval = millis() / 1000 - last_report;

  if (interval < REPORT_INTERVAL) {
    return;
  }

  last_report = millis() / 1000;

  //do some important stuff

}

...