Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Marmachine
#64974 Thanks for your help!

schufti wrote:...as your existing code goes through setup once and then keeps "looping" (and creating a wifi client) every 5min, I would suggest to at least move the

// Define a new client
WiFiClient client;

to the setup section (out of the loop).


I am pretty sure this was causing the locking, removing it like in below code, made it run for over 24 hours already, using a (5 min) pause at the end of the loop.

But the deepsleep makes sence as well, so instead of a pause, i've updated my code to the below;

schufti wrote:an esp.restart() will just restart the esp8266 but without a reinitialisation of the hw (cantrary to power up or reset), meaning: will go through setup and then enter loop. Deepsleep wakeup the esp8266 starts up like hw-reset (with all init of ports, registers etc)


The (updated) code with the deepsleep, intended as a (5 min = 300 seconds) cycle;

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

const int sleepTimeS = 300; // seconds to sleep between every cycle

// ========================= LED PIN ========================
#define LED_PIN D5 // Led pin

// ======================= DHT11 / 22 =======================
#define DHTPIN D3
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// ==================== lightmeter BH1750 ===================
// BH1750 Light Sensor connection: VCC to 5v+ | GND to GND | SCL to pin SCL/D1 | SDA to pin SDA/D2 | ADD not used
BH1750 lightMeter;

// ========================== Wifi ==========================
const char* ssid      = "myssid";
const char* password  = "mypass";

// ============= Domoticz host address and port =============
const char* host      = "192.168.2.100";     // NOTE: There should not be http:// before the address!!!
const int httpPort    = 8080;

// =============== Domoticz devices to update ===============
int domoticz_temp_idx = 133;
int domoticz_hum_idx  = 167;
int domoticz_lux_idx  = 168;

// ==========================================================

void WIFI_Connect(){
  digitalWrite(2,1);
  WiFi.disconnect();
  Serial.println("Booting Sketch...");
//  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  // Wait for connection
  for (int i = 0; i < 25; i++){
    if ( WiFi.status() != WL_CONNECTED ) {
      delay ( 250 );
      digitalWrite(2,0);
      Serial.print ( "." );
      delay ( 250 );
      digitalWrite(2,1);
    }
  }
  digitalWrite(2,0);
  Serial.println("");
  Serial.println("WiFi connected");

  Serial.print("Device IP: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("=============================================");
 
  Serial.println("");
}


void setup(void){
  pinMode(2, OUTPUT);
  Serial.begin(115200);
  Serial.println();
  WIFI_Connect();

  // starting DHT sensor
  dht.begin();
 
  // starting lightMeter BH1750
  lightMeter.begin();

}

// ==========================================================

void loop(void){
    if (WiFi.status() != WL_CONNECTED)
    {
      digitalWrite(2,1);
      WIFI_Connect();
    } else {
      digitalWrite(2,0);
    }

  Serial.println("Reading sensors:");

  // === DHT22 ===

  float hum = dht.readHumidity();
  float temp = dht.readTemperature();
  int hum_status = 0;
 
  if (isnan(hum) || isnan(temp)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  } else {

      // === TEMPERATURE ===
      Serial.print("Temperature: ");
      Serial.print(temp);
      Serial.println(" degrees Celsius");
   
      // When we set a correction...
      // Serial.print("After (-4%) correction, temperature is: ");
      // temp = temp*0.96; /* 4 precent correction */
      // Serial.print(temp);
      // Serial.println(" degrees Celsius");

      // === HUMIDITY ===
      Serial.print("Humidity: ");
      Serial.print(hum);
      Serial.println(" Percent");
   
  }

  // === BH1750 ===
 
  uint16_t lux = lightMeter.readLightLevel();
  int luxnum = lux;

  if (isnan(lux)) {
    Serial.println("Failed to read from LUX sensor!");
    return;
  } else {

    Serial.print("Lux: ");
    Serial.println(lux);
   
  }

  Serial.println("");

  Serial.println("Update values in Domoticz:");

  // Define a new client
  WiFiClient client;
  unsigned long timeout = millis();
 
  // Get Connected to the Server
  if (!client.connect(host, httpPort)) {
    Serial.println("[connection failed]");
    return;
  }

  // LED turns on when we connect
  digitalWrite(LED_PIN, HIGH);

  // === TEMPERATURE ===

  Serial.println("Temperature:");

  // get url to set temperature
  String url = gettempurl(temp, domoticz_temp_idx);
  Serial.print("Requesting URL: ");
  Serial.println(url);
 
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  // set the timeout value
  int TIMEOUT1 = millis() + 5000;

  // Read all the lines of the reply from server and print them to Serial
  while(client.available() == 0){
    // check for timeout
    if (TIMEOUT1 - millis() < 0) {
        Serial.println(">>> CLIENT TIMEOUT!");

        // Before we exit, turn the LED off.
        digitalWrite(LED_PIN, LOW);
       
        client.stop();
        return;
    }
   
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  // Disconnect from the server
  client.stop();

  Serial.println("");

  // Before we exit, turn the LED off.
  digitalWrite(LED_PIN, LOW);
 
  delay(500);


  // === HUMIDITY ===

  // Get Connected to the Server
  if (!client.connect(host, httpPort)) {
    Serial.println("[connection failed]");
    return;
  }

  // LED turns on when we connect
  digitalWrite(LED_PIN, HIGH);

  Serial.println("Humidity:");

  /* -- Mapping for Humidity_status
   * ----------------------------------------------------------------------------------------------------
                -- 0    = Normal
                -- 1    <> 46-70%   = Comfortable
                -- 2    < 46        = Dry
                -- 3    > 70%       = Wet
   * ---------------------------------------------------------------------------------------------------- */

     if (hum > 0){
        if ((hum >= 46) and (hum <= 70)) {
          hum_status = 1; /* comfortable */
        } else if (hum < 46) {
          hum_status = 2; /* dry */
        } else if (hum > 70)
          hum_status = 3; /* wet */
     }
 
  // get url to set humidity
  String url_hum = gethumurl(hum, hum_status, domoticz_hum_idx);
  Serial.print("Requesting URL: ");
  Serial.println(url_hum);
 
  // This will send the request to the server
  client.print(String("GET ") + url_hum + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  // set the timeout value
  int TIMEOUT2 = millis() + 5000;

  // Read all the lines of the reply from server and print them to Serial
  while(client.available() == 0){
    // check for timeout
    if (TIMEOUT2 - millis() < 0) {
        Serial.println(">>> CLIENT TIMEOUT!");

        // Before we exit, turn the LED off.
        digitalWrite(LED_PIN, LOW);
       
        client.stop();
        return;
    }
   
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  // Disconnect from the server
  client.stop();

  Serial.println("");

  // Before we exit, turn the LED off.
  digitalWrite(LED_PIN, LOW);
 
  delay(500);
 
  // === LUX ===
 
  // Get Connected to the Server
  if (!client.connect(host, httpPort)) {
    Serial.println("[connection failed]");
    return;
  }

  // LED turns on when we connect
  digitalWrite(LED_PIN, HIGH);
  Serial.println("Lux:");

  String url_lux = getluxurl(lux, domoticz_lux_idx);
  Serial.print("Requesting URL: ");
  Serial.println(url_lux);
 
  // This will send the request to the server
  client.print(String("GET ") + url_lux + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");

  // set the timeout value
  int TIMEOUT3 = millis() + 5000;

  // Read all the lines of the reply from server and print them to Serial
  while(client.available() == 0){
    // check for timeout
    if (TIMEOUT3 - millis() < 0) {
        Serial.println(">>> CLIENT TIMEOUT!");

        // Before we exit, turn the LED off.
        digitalWrite(LED_PIN, LOW);
       
        client.stop();
        return;
    }
   
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println("");
 
  // Disconnect from the server
  client.stop();

  Serial.println("");

  // Before we exit, turn the LED off.
  digitalWrite(LED_PIN, LOW);

  delay(500);

  // === SLEEP ===

  Serial.println("ESP8266 in sleep mode");
  Serial.println("");
  ESP.deepSleep(sleepTimeS * 1000000); //sleep time, seconds to usecs.
  delay(1000); // a short delay to keep in loop while ESP.deepSleep() is being implemented.
}

// ==========================================================

String gettempurl(int temperature, int idx){
  // this function returns url to set temp_value in domoticz
 
  /* example url for domoticz temperature device:
  http://192.168.2.100:8080/json.htm?type=command&param=udevice&idx=133&nvalue=0&svalue=24
  */

  // Create a URI for the request
  String url = "/json.htm?type=command&param=udevice&idx=";
  url += idx;
  url += "&nvalue=0&svalue=";
  url += temperature;

  return url;
}

String gethumurl(int humidity, int humstatus, int idx){
  // this function returns url to set hum_value in domoticz
 
  /* example url for domoticz humidity device:
  http://192.168.2.100:8080/json.htm?type=command&param=udevice&idx=IDX&nvalue=HUM&svalue=0
  */

  // We now create a URI for the request
  String url = "/json.htm?type=command&param=udevice&idx=";
  url += idx;
  url += "&nvalue=";
  url += humidity; // Humidity value
  url += "&svalue=";
  url += humstatus; // Humidity_status can be: 0=Normal | 1=Comfortable | 2=Dry | 3=Wet

  return url;
}

String getluxurl(int lux, int idx){
  // this function returns url to set lux_value in domoticz
 
  /* example url for domoticz lux device:
  http://192.168.2.100:8080/json.htm?type=command&param=udevice&idx=IDX&svalue=VALUE
  */

  // We now create a URI for the request
  String url = "/json.htm?type=command&param=udevice&idx=";
  url += idx;
  url += "&svalue=";
  url += lux;

  return url;
}


Going to deepsleep showed a nice signoff for the device in my wifi-logging:
5C:CF:XX:XX:XX:XX@wlan1: disconnected, received disassoc: sending station leaving (8)

However, the serial monitor does print a line of garbage, but does that instead of restarting after 5 minutes! :?: :(
So this never comes alive again after deepSleep()
I looked at this example, where everything is in setup{}, but that makes no difference for me.
Next i found this thread about putting a 1K resister (but even a lower one should work, such 470R or even 220R) between D0 and RST. :roll: :?
User avatar
By schufti
#64982 Hi,
yes the "garbage" is the bootloader sending out at 74880baud.
Unfortunately the esp8266 can internaly wake uo from deepsleep but the bootloader does not know how to handle internal wake-up.

So the work-around is to reset the esp8266 at deepsleep wakeup --> gpio16 --> rst.
Best solution would be schottky diode (cathode to gpio16, anode to rst), second best is resistor (1k should work, depending on used rst-pullup) worst solution is direct connect (wire) -> you will have problems reflashing.
User avatar
By Marmachine
#65052
schufti wrote:Hi,
yes the "garbage" is the bootloader sending out at 74880baud.
Unfortunately the esp8266 can internaly wake uo from deepsleep but the bootloader does not know how to handle internal wake-up.

So the work-around is to reset the esp8266 at deepsleep wakeup --> gpio16 --> rst.
Best solution would be schottky diode (cathode to gpio16, anode to rst), second best is resistor (1k should work, depending on used rst-pullup) worst solution is direct connect (wire) -> you will have problems reflashing.


I choose a 1k resistor between D0 and RST... guess what; still garbage!
This should be right for a WeMos D1 R2, right? (i found that the R1 version has a different pinout)
Should i set D0 to HIGH instead of calling the deepsleep? Or is that done by deepsleep when it (should) come out of it's sleeptime?
User avatar
By Mitchell QTT
#65064 1. You want to exit your loop-function quicky and do as little work as possible in it.
Reason is that there is no background process. Client and WiFi need to keep the connection alive and need to be called frequently to do this.
Calling client.loop() or yield() or delay() functions will yield the processor to these classes to keep things alive.
It may be that your loop() is blocking things slightly too long every now and then, causing a disconnect.

2. I notice that you set up a new client connection in every loop. I tend to create one client connection and then re-use it. It saves CPU cycles so Loop() can exit quickly (see point 1). It saves overhead in CPU and ethernet traffic.
So I would create clietn in a setup() and then verify the connection in the loop. Client has a state() method to give you the connection-state.
if client is not connected, reconnect it.