Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By Petervdpol
#37108 Mighty Men and Women; please help a non-programmer out here:

I want to add a DHT22 sensor node to my Openhab setup. IMHO a simple way to do this is by using a ESP8266-01; I have a few around. I use the Arduino 1.6.5 IDE since that is what I have. I am having problems with the timing of the loop: I do not need readings every few seconds, minute or so, 5-10 minutes are more then enough; I do not need that much data. I also want to run the node on batteries in the future so less transmissions is what I want to save power. However, when I use a delay of more then approx. 24000 mils the ESP stops working, lower values are no problem.

I have tried several approaches, none work. Can anyone help me out?

The sketch I use is below, you can see what I tried in the comments:

Code: Select all#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <DHT.h>

const char* ssid = "Yggdrasil";
const char* password = "XXXXXXXXX";
char* topic_t = "openhab/esp8266-1/temp";
char* topic_h = "openhab/esp8266-1/vocht";
char* server = "192.168.X.X";
String clientName = "esp8266-1";

//time peter, idea taken from https://www.safaribooksonline.com/library/view/arduino-cookbook-2nd/9781449321185/ch12.html
const long oneSecond = 1000;  // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long fiveMinutes = oneMinute * 5;
//time peter

#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 11
DHT dht(DHTPIN, DHTTYPE,15);

WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}

void setup() {
Serial.begin(115200);
delay(10);
dht.begin();
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

Serial.print("Connecting to ");
Serial.print(server);
Serial.print(" as ");
Serial.println(clientName);


if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker");
Serial.print("Topic is: ");
Serial.println(topic_t);
Serial.println(topic_h);

}
else {
Serial.println("MQTT connect failed");
Serial.println("Will reset and try again...");
abort();
}
}

void loop()

{

float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}

static int counter = 0;
String payload ;
payload += t;
//payload += ":";
//payload += h;
String payloadh ;
payloadh += h;

if (client.connected()){
Serial.print("Sending payload: ");
Serial.println(payload);

if (client.publish(topic_t, (char*) payload.c_str()))
{
Serial.println("Publish ok");
}
else {
Serial.println("Publish failed");
}

//peter
if (client.connected()){
Serial.print("Sending payload: ");
Serial.println(payloadh);

if (client.publish(topic_h, (char*) payloadh.c_str()))
{
Serial.println("Publish ok");
}
else {
Serial.println("Publish failed");
}}
//peter


}
else {
if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker");
Serial.print("Topic is: ");
Serial.println(topic_t);
Serial.println(topic_h);

}
}
// delay (20000); //WORKS FINE
// delay(5*60*1000); //STOPS AFTER FIRST READING AT STARTUP
delay(fiveMinutes); // STOPS AFTER FIRST READING AT STARTUP
}
User avatar
By DrG
#37162 Hi Petervdpol,

Not sure that I am 'mighty' but I think that I might be able to suggest something to try. Take a look at the reference doc for the ArduinoIDE here https://github.com/esp8266/Arduino/blob ... and-delays. The basic idea that I get from the section on Timing and Delays is that there are a lot of functions on the chip (since it is a System On Chip [SoC]) that need to be addressed at variable times - especially when wireless and TCP are going on. When you sit in a delay loop, you can't get to the tasks and when the delay loop is too long, you crash. In your case, you are finding that out after about 24 seconds.

Try to break up a long delay into shorter delays. When leaving each of those short delays, housekeeping will have a chance to address some matters.

Take a look at this code and give it a try. I have created a function that delays for the number of minutes in the argument. You should have no problem getting delays of 20 min or more - BUT there is no WiFi going on in that fragment, it is just to illustrate the approach. This may help and you may need to adjust the "inside" delay to make it even shorter to keep everything running. I commented out the yield() command, you can put it back in if you want, it might help also.

Code: Select allvoid setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
   Serial.println();
   Serial.print("1 min delay ");
   MinuteDelay(1);
   Serial.println();
   Serial.print("5 min delay ");
   MinuteDelay(5);
   Serial.println();
   Serial.print("10 min delay ");
   MinuteDelay(10);
   Serial.println();
   Serial.print("20 min delay ");
   MinuteDelay(20);
   Serial.println();
}

void MinuteDelay(int number){
  for (int i = 0; i < number; ++i)
    {
     
      // use 6 10 second delays for each minute // with a yield before each
      for(int j=0; j<6 ;j++)
      {
        Serial.print("*");
        // yield();
        delay(10000);
       
      }
    }
  }


The best way of doing what you want, however, may be to put the ESP to sleep so that it uses very little power and then have it wake up after a delay. That is a little more complicated but if you search on this board and elsewhere you will see how this can be done.

Let us know how it turns out,

Cheers,

DrG
User avatar
By martinayotte
#37166 Personally, I prefer handling long delays with millis(), especially if I wish to do something else in the loop(), such as watching for incoming TCP connections. So, so you can trigger tasks with code similar to the following :

Code: Select allvoid loop() {
  if (millis() - previous_millis > 600000) { // trigger tasks every 10 mins
    previous_millis = millis();
    // do some task here, or trigger some flags, etc
  }
  else {
    // do something else here, such as checking for incoming connections
  }
}
User avatar
By GengusKahn
#37171 Hi there, I have modified the sketch to add a loop timer for 15 Seconds and 15 Minutes these are easily adjusted from the declarations.......
Use one of the sleep modes for a time less than the timer value.....This is not verified in the IDE as I have a different setup.......
My complete sketch using this is on this forum......

Code: Select all#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <DHT.h>

const char* ssid = "Yggdrasil";
const char* password = "XXXXXXXXX";
char* topic_t = "openhab/esp8266-1/temp";
char* topic_h = "openhab/esp8266-1/vocht";
char* server = "192.168.X.X";
String clientName = "esp8266-1";

//time peter, idea taken from https://www.safaribooksonline.com/library/view/arduino-cookbook-2nd/9781449321185/ch12.html
const long oneSecond = 1000;  // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long fiveMinutes = oneMinute * 5;
//time peter

// Timer ADDED......
// Set time compare to select post rather than delay.......
unsigned long ulMeasDelta_ms;  // Distance to Tweet Time Timer
unsigned long ulNextMeas_ms;   // Holder for the next Tweet Time Value
int loop_timer = 15;           // Set the delay in Seconds for Thingspeak
int tweet_timer = 60;          // The number of 15 second periods to wait before Tweeting
int tweet_count = 0;           // Loop to count thing posts
//............




#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 11
DHT dht(DHTPIN, DHTTYPE,15);

WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}

void setup() {
  //ADDED................

  ulMeasDelta_ms = ( (unsigned long) loop_timer * 1000);  // Sample Interval X in Seconds placed above in the declarations....
  ulNextMeas_ms = millis()+ulMeasDelta_ms;
 
  //...............
Serial.begin(115200);
delay(10);
dht.begin();
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

Serial.print("Connecting to ");
Serial.print(server);
Serial.print(" as ");
Serial.println(clientName);


if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker");
Serial.print("Topic is: ");
Serial.println(topic_t);
Serial.println(topic_h);

}
else {
Serial.println("MQTT connect failed");
Serial.println("Will reset and try again...");
abort();
}
}

void loop()

{
//  ADDED...............
  // Only progress when timer match occurs................
    if (millis()>=ulNextMeas_ms)
  {                                          // 15 Second loop from the declarations above
    ulNextMeas_ms = millis()+ulMeasDelta_ms;


   tweet_count++;
if (tweet_count==tweet_timer){               // 15 Minute loop from the declarations above
   tweet_count=0;
   

//.............


float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}

static int counter = 0;
String payload ;
payload += t;
//payload += ":";
//payload += h;
String payloadh ;
payloadh += h;

if (client.connected()){
Serial.print("Sending payload: ");
Serial.println(payload);

if (client.publish(topic_t, (char*) payload.c_str()))
{
Serial.println("Publish ok");
}
else {
Serial.println("Publish failed");
}

//peter
if (client.connected()){
Serial.print("Sending payload: ");
Serial.println(payloadh);

if (client.publish(topic_h, (char*) payloadh.c_str()))
{
Serial.println("Publish ok");
}
else {
Serial.println("Publish failed");
}}
//peter


}
else {
if (client.connect((char*) clientName.c_str())) {
Serial.println("Connected to MQTT broker");
Serial.print("Topic is: ");
Serial.println(topic_t);
Serial.println(topic_h);

}
}
// delay (20000); //WORKS FINE
// delay(5*60*1000); //STOPS AFTER FIRST READING AT STARTUP
//delay(fiveMinutes); // STOPS AFTER FIRST READING AT STARTUP
    }// 15 Minute Loop Timer
  }//   15 Second Loop Timer
}


My sketch has been running for some time and only network issues force a reboot.....

https://twitter.com/ddtmonitor

This is some messing with home made MPU 10 DOF....
https://twitter.com/mcuautomation

Image