Improve the canonical "node-wifi-mqtt" firmware

Thanks for your feedback! We just reduced the default number of devices to one (1) to make it even easier for everyone getting started with this. Besides that, we tried to improve on the “naming things” side. Would you give the new vanilla version another try on your device to reassure nothing went wrong?

Thanks in advance!

Excellent. Since I already adapted the previous version to my setup I manually migrated the changes and it all works. I’m also read battery level and make use of ESP8266WiFiMulti to avoid changing the WiFi setup every time I switch locations. Not a big deal.
I’ll share my sketch here soon:

@Andreas and @Thias , thanks for such a great work!

Sounds good! Feel free to share the code right here in this topic and maybe report about your major improvements in the main topic. Then we can discuss further details here and will not pollute the main topic with too much technical details when sorting things out.

People will stumble across the code as both topics are interlinked and we will also update the code in the git repository with your changes, if you don’t mind. If you already have an account on GitHub, feel free to fork the repository there and feed back the improvements in form of a pull request. There’s no magic behind that and we are happy to help to get you started on this, as @mois is currently doing the same, see also Add firmware for Mois Box.

We are looking forward to your contributions!

Ich habe mittlerweile einigen Fortschritt gemacht und mir eurer Hilfe eine halbwegs individuelle Firmware zusammengefrickelt auf Basis von node-wifi-mqtt-basic. Siehe unten.

Zur Zeit tracke ich den Verlauf der Batterieladung ohne externe Stromversorgung. Mich interessiert dabei, ob sich die Trennung der WLAN-Verbindung nach der Datenübertragung signifikant lohnend auf die Betriebsdauer auswirkt. Den Call für den Verbindungsaufbau habe ich deshalb in loop() verschoben.

ESP8266WiFiMulti scheint auch zuverlässig zu funktionieren. Das spart mir die Umkonfiguration bei einem Standortwechel (Couch <-> Bienenstand). Für weitere Ideen zum Energiesparen bin ich auf Empfang. Für die tollen Entwicklungen hier sowieso.

/*

  Hiveeyes node-wifi-mqtt

  Collect beehive sensor data and transmit via WiFi to a MQTT broker.

  Copyright (C) 2016-2017  The Hiveeyes Developers <hello@hiveeyes.org>


  Changes
  -------
  2016-05-18 Initial version
  2016-10-31 Beta release
  2017-01-09 Add more sensors
  2017-02-01 Serialize sensor readings en bloc using JSON
  2017-03-31 Fix JSON serialization: Transmit sensor readings as float values. Thanks, Matthias and Giuseppe!
  2017-04-05 Improve efficiency and flexibility


  GNU GPL v3 License
  ------------------
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, see:
  <http://www.gnu.org/licenses/gpl-3.0.txt>,
  or write to the Free Software Foundation,
  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA

  -------------------------------------------------------------------------

  Hiveeyes node sketch for Arduino based platforms. Here: ESP8266.

  This is a Arduino sketch for the Hiveeyes beehive monitoring system.
  The purpose is to collect vital data and to send it via WiFi to
  the MQTT bus at swarm.hiveeyes.org:1883.

  This code is derived from the Adafruit ESP8266 MCU demo sketch,
  see below.

  Feel free to adapt this code to your own needs. Contributions are welcome!

  -------------------------------------------------------------------------

  Further information can be obtained at:

  The Hiveeyes Project         https://hiveeyes.org/
  System documentation         https://hiveeyes.org/docs/system/
  Code repository              https://github.com/hiveeyes/arduino/

  -------------------------------------------------------------------------

*/

/***************************************************
  Adafruit ESP8266 Sensor Module

  Must use ESP8266 Arduino from:
    https://github.com/esp8266/Arduino
  Works great with Adafruit's Huzzah ESP board:
  ----> https://www.adafruit.com/product/2471
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!
  Written by Tony DiCola for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
****************************************************/



// =====================
// General configuration
// =====================

// Measure and transmit each five minutes
#define MEASUREMENT_INTERVAL    10 * 60 * 1000


// ==========================
// Connectivity configuration
// ==========================

// ----
// WiFi
// ----
#define SSID_1 "MY_PRIVATE_WIFI"
#define PW_1 "MY_PRIVATE_WIFI_PASSWORD"
#define SSID_2 "Freifunk-Potsdam-254-11"
#define PW_2 ""
#define SSID_3 "machBar@Freifunk-Potsdam"
#define PW_3 ""
#define SSID_4 "freiLand@Freifunk-Potsdam"
#define PW_4 ""

// ----
// MQTT
// ----

// The address of the MQTT broker to connect to.
#define MQTT_BROKER     "hiveeyes.mbpriv.de"
#define MQTT_PORT       1883

// A MQTT client ID, which should be unique across multiple devices for a user.
// Maybe use your MQTT_USERNAME and the date and time the sketch was compiled
// or just use an UUID (https://www.uuidtools.com/) or other random value.
#define MQTT_CLIENT_ID  ""

// The credentials to authenticate with the MQTT broker.
#define MQTT_USERNAME   ""
#define MQTT_PASSWORD   ""

// The MQTT topic to transmit sensor readings to.
// Note that the "testdrive" channel is not authenticated and can be used anonymously.
// To publish to a protected data channel owned by you, please ask for appropriate
// credentials at https://community.hiveeyes.org/ or hello@hiveeyes.org.
#define MQTT_TOPIC      "hiveeyes/Thias/PDM/testnode/data.json"


// ====================
// Sensor configuration
// ====================

// A dummy sensor publishing static values of "temperature", "humidity" and "weight".
// Please turn this off when working with the real sensors.
#define HAS_DUMMY_SENSOR    false

// The real sensors
#define HAS_HX711           true
#define HAS_DHTxx           true
#define HAS_DS18B20         true
#define HAS_BATTERY         true


// -------------------
// HX711: Scale sensor
// -------------------

// HX711.DOUT  - pin #14
// HX711.PD_SCK - pin #12
#define HX711_PIN_DOUT      14
#define HX711_PIN_PDSCK     12

// Define here individual values for the used load cell. This is not type specific!
// Even load cells of the same type / model have individual characteristics
//
// - ZeroOffset is the raw sensor value for "0 kg"
//   write down the sensor value of the scale with no load and
//   adjust it here
//
// - KgDivider is the raw sensor value for a 1 kg weight load
//   add a load with known weight in kg to the scale, note the
//   sesor value, calculate the value for a 1 kg load and adjust
//   it here

const long loadCellZeroOffset = -41000.0f;

// 1/2 value for single side measurement, so that 1 kg is displayed as 2 kg
//const long loadCellKgDivider  = 22053;
const long loadCellKgDivider  = 11026;



// -----------------------------
// DHTxx: Humidity / Temperature
// -----------------------------


// Number of DHTxx devices connected
const int dht_device_count = 1;

// DHTxx device pins: Pin 2, Pin 4
const int dht_pins[dht_device_count] = {4};

// For more DHTxx devices, configure their pins like...
// DHTxx device pins: Pin 2, Pin 4
//const int dht_pins[dht_device_count] = {2,4};


// --------------------------
// DS18B20: Temperature array
// --------------------------

// Number of temperature devices on the 1-Wire bus
const int ds18b20_device_count = 1;

// Order of the physical array of temperature devices,
// the order is normally defined by the device id hardcoded in
// the device.
// You can physically arrange the DS18B20 in case you
// know the ID and use here {1,2,3,4 ...} or you can try out what
// sensor is on which position and adjust it here accordingly.
const int ds18b20_device_order[ds18b20_device_count] = {0};

// For more DS18B20 devices, configure them like...
//const int ds18b20_device_order[ds18b20_device_count] = {0,1};

// Resolution for all devices (9, 10, 11 or 12 bits)
const int ds18b20_precision = 12;

// 1-Wire pin for the temperature sensors
const int ds18b20_onewire_pin = 5;


// =========
// Libraries
// =========

// ------------
// Connectivity
// ------------

// ESP8266: https://github.com/esp8266/Arduino
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

// JSON serializer
#include <ArduinoJson.h>

// Adafruit MQTT
// https://github.com/adafruit/Adafruit_MQTT_Library
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"


// -------
// Sensors
// -------

#if HAS_HX711
#include "HX711.h"
HX711 hx711_sensor;  // create HX711 object

// Intermediate data structure for reading the sensor values
float weight;

#endif

// DHTxx sensor
#if HAS_DHTxx
#include <dht.h>

// Create DHT object
dht dht_sensor;

// Intermediate data structure for reading the sensor values
float dht_temperature[dht_device_count];
float dht_humidity[dht_device_count];

#endif

// DS18B20 sensor
#if HAS_DS18B20
// 1-Wire library
#include <OneWire.h>

// DS18B20/DallasTemperature library
#include <DallasTemperature.h>

// For communicating with any 1-Wire device (not just DS18B20)
OneWire oneWire(ds18b20_onewire_pin);

// Initialize DallasTemperature library with reference to 1-Wire object
DallasTemperature ds18b20_sensor(&oneWire);

// Arrays for device addresses
uint8_t ds18b20_addresses[ds18b20_device_count][8];

// Intermediate data structure for reading the sensor values
float ds18b20_temperature[ds18b20_device_count];

#endif

// Battery read
# if HAS_BATTERY
int battery_level;
#endif

// ===============
// Telemetry setup
// ===============

// Functions
void mqtt_connect();
void startWifi();

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
ESP8266WiFiMulti wifiMulti;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_BROKER, MQTT_PORT, MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD);

// Setup MQTT publishing handler
Adafruit_MQTT_Publish mqtt_publisher = Adafruit_MQTT_Publish(&mqtt, MQTT_TOPIC);


// ============
// Main program
// ============

void setup() {
  Serial.begin(9600);

  // Setup scale
#if HAS_HX711
  hx711_sensor.begin(HX711_PIN_DOUT, HX711_PIN_PDSCK);

  // These values are obtained by calibrating the scale with known weights; see the README for details
  hx711_sensor.set_scale(loadCellKgDivider);
  hx711_sensor.set_offset(loadCellZeroOffset);

  //  hx711_sensor.tare();             // reset the scale to 0
  yield();
#endif


  // temperature array
#if HAS_DS18B20

  ds18b20_sensor.begin();  // start DallasTemperature library
  ds18b20_sensor.setResolution(ds18b20_precision);  // set resolution of all devices

  // Assign address manually. The addresses below will need to be changed
  // to valid device addresses on your bus. Device addresses can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // ds18b20_sensor.getAddress(deviceAddress, index)
  //insideThermometer    = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

  // Search for devices on the bus and assign based on an index. Ideally,
  // you would do this to initially discover addresses on the bus and then
  // use those addresses and manually assign them (see above) once you know
  // the devices on your bus (and assuming they don't change).
  //
  // method 1: by index
  // change index to order divices as in nature
  // (an other approach can be to order physical devices ascending to device address on cable)

  for (int i=0; i<ds18b20_device_count; i++) {
    if (!ds18b20_sensor.getAddress(ds18b20_addresses[ds18b20_device_order[i]], i)) {
      Serial.print(F("Unable to find address for temperature array device "));
      Serial.print(i);
      Serial.println();
    }
  }

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices,
  // or you have already retrieved all of them. It might be a good idea to
  // check the CRC to make sure you didn't get garbage. The order is
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

#endif

}


// temperature array / DS18B20
void getTemperature() {

#if HAS_DS18B20

  // request temperature on all devices on the bus
  ds18b20_sensor.setWaitForConversion(false);  // makes it async
  // initiatie temperature retrieval
  ds18b20_sensor.requestTemperatures();

  // wait at least 750 ms for conversion
  delay(1000);

  // Iterate all DS18B20 devices and read temperature values
  for (int i=0; i<ds18b20_device_count; i++) {
    float temperatureC = ds18b20_sensor.getTempC(ds18b20_addresses[i]);
    ds18b20_temperature[i] = temperatureC;
  }

#endif

}

// humidity and temperature, DHTxx
void getHumidityTemperature() {

#if HAS_DHTxx

  // read humidity and temperature data
  // loop through all devices
  for (int i=0; i<dht_device_count; i++) {
    // read device
    int chk = dht_sensor.read33(dht_pins[i]);

    switch (chk) {
      // this is the normal case, all is working smoothly
    case DHTLIB_OK:
      //Serial.print("OK,\t");
      dht_temperature[i]  = dht_sensor.temperature;
      dht_humidity[i]     = dht_sensor.humidity;
      break;

      // following are error cases
    case DHTLIB_ERROR_CHECKSUM:
      Serial.println("Checksum error");
      break;

    case DHTLIB_ERROR_TIMEOUT:
      Serial.println("Time out error");
      break;

    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // FOR UNO + DHTxx 400ms SEEMS TO BE MINIMUM DELAY BETWEEN SENSOR READS,
  // ADJUST TO YOUR NEEDS
  // we do other time consuming things after reading DHTxx, so we can skip this
  //  delay(1000);

#endif

}


void getWeight() {

#if HAS_HX711

  hx711_sensor.power_up();
  weight = hx711_sensor.get_units(5);

  // Debugging
  // Serial.println(weight);

  // Aftermath
  hx711_sensor.power_down();              // put the ADC in sleep mode
  yield();

#endif

}

void getBatteryLevel() {
#if HAS_BATTERY

  // read the battery level from the ESP8266 analog in pin.
  // analog read level is 10 bit 0-1023 (0V-1V).
  // our 1M & 220K voltage divider takes the max
  // lipo value of 4.2V and drops it to 0.758V max.
  // this means our min analog read value should be 580 (3.14V)
  // and the max analog read value should be 774 (4.2V).
  int adc_level = analogRead(A0);
  Serial.print("ADC Level: "); Serial.println(adc_level);

  // convert battery level to percent
  battery_level = map(adc_level, 535, 759, 0, 100);
  Serial.print("Battery level: "); Serial.print(battery_level); Serial.println("%");

#endif
}

void loop() {

  startWifi();
  mqtt_connect();

  // Grab the current state of the sensor
  //  int humidity_data = (int)dht.readHumidity();
  //  int temperature_data = (int)dht.readTemperature();

  // note: only for a single DS18B20 on the bus!!
  // must be rewritten for more DS18B20


  // output humidity and temperature, DHTxx
  Serial.println(F("Read weight"));
  getWeight();
  Serial.println(F("Read temp"));
  getTemperature();
  Serial.println(F("Read hum temp"));
  getHumidityTemperature();

#if HAS_BATTERY
  Serial.println(F("Read Battery Level"));
  getBatteryLevel();
#endif

  // Build JSON object containing sensor readings
  StaticJsonBuffer<512> jsonBuffer;


  // Create telemetry payload by mapping sensor readings to telemetry field names
  // Note: For more advanced use cases, please have a look at the TerkinData C++ library
  //       https://hiveeyes.org/docs/arduino/TerkinData/README.html
  JsonObject& root = jsonBuffer.createObject();

#if HAS_HX711
  root["weight"]                      = weight;
#endif

#if HAS_DHTxx
  root["airtemperature"]              = dht_temperature[0];
  root["airhumidity"]                 = dht_humidity[0];
  if (dht_device_count >= 2) {
    root["airtemperature_outside"]  = dht_temperature[1];
    root["airhumidity_outside"]     = dht_humidity[1];
  }
#endif

#if HAS_DS18B20
  root["entrytemperature"]            = ds18b20_temperature[0];
  if (ds18b20_device_count >= 2) {
    root["broodtemperature"]        = ds18b20_temperature[1];
  }
#endif

#if HAS_DUMMY_SENSOR
  root["temperature"]                 = 42.42f;
  root["humidity"]                    = 84.84f;
  root["weight"]                      = 33.33f;
#endif

#if HAS_BATTERY
  root["battery_level"]               = battery_level;
#endif

  // Debugging
  root.printTo(Serial);


  // Serialize data
  int json_length = root.measureLength();
  char payload[json_length+1];
  root.printTo(payload, sizeof(payload));


  // Publish data
  if (mqtt_publisher.publish(payload)) {
    Serial.println(F("MQTT publish succeeded"));
  } else {
    Serial.println(F("MQTT publish failed"));
  }

  Serial.println(F("Disconnecting Wifi"));
  WiFi.disconnect();
  // Wait for the next measurement interval
  delay(MEASUREMENT_INTERVAL);

}


// Connect to MQTT
void mqtt_connect() {

  if (mqtt.connected()) {
    Serial.println(F("Already connected to MQTT"));
    return;
  }

  Serial.println(F("Connecting to MQTT..."));
  int8_t ret;

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) {
    Serial.println(mqtt.connectErrorString(ret));

    Serial.println("Retrying MQTT connect in 5 seconds...");
    delay(5000);

    retries--;
    if (retries == 0) {
      Serial.println(F("Could not connect to MQTT, dying!"));
    }

  }
  Serial.println(F("Connected to MQTT!"));
}

void startWifi() {

  Serial.println(); Serial.println();
  delay(10);
  Serial.print("Connecting to Wifi");

  // remove/add entries as needed
  wifiMulti.addAP(SSID_1, PW_1);
  wifiMulti.addAP(SSID_2, PW_2);
  wifiMulti.addAP(SSID_3, PW_3);
  wifiMulti.addAP(SSID_4, PW_4);

  while (wifiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

Hi Matthias,

vielen Dank für Deine Verbesserungen. Wir pflegen sie gerne in die kanonische “Basic” Firmware ein, wenn Du nichts dagegen hast.

Diesem Thema widmet sich @clemens bereits seit längerem intensiv, deswegen waren in dieser “Basic” Firmware solche Dinge bisher nicht vorgesehen, wir können uns aber die entsprechenden Stellen abschauen, z.B. ab hier - “go sleeping” ff. in dem Teil seiner Firmware, die für den ESP8266 vorgesehen ist:
https://github.com/hiveeyes/arduino/blob/master/node-gprs-http/node-gprs-http.ino#L1095


Fein, vielen Dank an dieser Stelle für “startWifi” in Zusammenhang mit “ESP8266WiFiMulti”, @clemens hatte das auch bereits erschlossen. Diesbzgl. hatte ich per “wifi_ensure_connection()” bereits einen entsprechenden Vorstoß gewagt, den ursprünglichen Code besser zu modularisieren:


Da wir uns anhand der “Basic” Firmware gerade so viel Mühe geben, den Code ordentlich zu modularisieren, fließen Teile davon vielleicht zukünftig auch wieder in @clemens’ “Advanced” Firmware zurück. Danke!

Viele Grüße,
Andreas.

tue dir keinen Zwang an :)

WiFi.disconnect() ist wohl keine so gute Idee. Die Datenübertragung wird damit unzuverlässig im nächsten Loop. Obwohl die Meldung MQTT publish succeeded kommt, erreicht kein Datenpaket den MQTT Broker. Ich werde mich wohl mit den Sleep-Funktionen auseinandersetzen müssen, bzw ein paar Beispiele aus dem Netz zur Anwendung bringen.

Hi there,

node-wifi-mqtt-basic again was improved a lot. We tried our best to incorporate the contributions and suggestions from @Thias and @gtuveri, thanks a bunch again! At a glance:

  • Enable connecting to multiple WiFi access points with multiple attempts, see “WIFI_SSID_X” and “WIFI_SSID_X” as well as “WIFI_RETRY_COUNT”, “WIFI_RETRY_DELAY”, “MQTT_RETRY_COUNT” and “MQTT_RETRY_DELAY”.
  • Read and transmit battery level, see “SENSOR_BATTERY_LEVEL”.
  • Read and transmit free heap memory, see “SENSOR_MEMORY_FREE”.
  • Add deep sleep mode, see “DEEPSLEEP_ENABLED”.
  • Improve overall configurability and documentation.

We are looking forward to keep up the good flow of ping pong between both of you and us and hope the recent changes didn’t break anything again.

With kind regards,
Andreas.

P.S.: After things have settled a bit, we are planning to use the TerkinData and TerkinTelemetry libraries in another variant of this firmware to let the hopefully well established data collection and telemetry routines converge into them. This could help @clemensrefactored node-gprs-http firmware gaining more flexibility - a thing we are aiming at since weeks ;].

1 Like

Hi Andreas, yes, here we are :-)
This morning I tested the updated code including multiple access point support and selectable sensors. I found two small issues (the IP should be printed by calling WiFi class, as the current code prints 0.0.0.0) and maybe it would be better to use elsif, when dealing with individual sensor activation, in order to better select the code branches if no sensors are present. I will try to make my commit proposal asap!
I also expect to test soon the DHT and HX711 peripherals, thus I will move to radio nodes testing.

Cheers,
Giuseppe

Hey,

I found two small issues… I will try to make my commit proposal asap!

Cool, thanks!

(the IP should be printed by calling WiFi class, as the current code prints 0.0.0.0)

Excellent!

and maybe it would be better to use elsif, when dealing with individual sensor activation, in order to better select the code branches if no sensors are present.

Not sure about that, let me see what you are aiming at.

If you get the chance, i would be interested if “DEEPSLEEP_ENABLED” actually works… ;] We believe @Thias as well!

See you,
Andreas.

Well, I was thinking it makes no sense to add #if SENSOR* stuff if SENSOR_DUMMY is true, but in fact also I’m not sure about that :-)

Finally, I was thinking about why to proceed within execution if no WiFi connection has been estabilished,

Cheers,
Giuseppe

That’s true!

Also true!


@Thias: If you could confirm the current version of the firmware is also working at your place, i’m inclined to merge the current state to the master branch and continue iterating on more improvements there. Thanks!

I’ll try to get a time slot for testing this evening

1 Like

Well, it seems the deepsleep does not work out of the box. However, I’m powering the MCU through USB. I will try to perform some debug soon,

Cheers

Giuseppe

Well it works! It was my fault. I just needed to connect the D0 pin with RST pin. This enables wakeup of the MCU. Of course, some spurious data is sent to UART, but in fact, in low power use-cases I think UART prints will be enabled just in debug contexts.

Cheers,
Giuseppe

Very cool, thanks for testing!

Thanks again, we will add an appropriate comment to the source code.

Do you see any way to improve this? Currently, there’s a Serial.flush(); before going to deep sleep mode. Should we add another one right after waking up in setup()?

Please be aware that our improvements now have been merged into the master branch, so please find the current version at node-wifi-mqtt.ino.

Thanks again for your efforts!

Cheers,
Andreas.

Unfortunately, still no way to make the Serial silent when sleeping it. But well, it still remains an acceptable glitch

Cheers,
Giuseppe

please change:
- #define DEEPSLEEP_TIME MEASUREMENT_INTERVAL * 1000UL * 1000UL
+ #define DEEPSLEEP_TIME MEASUREMENT_INTERVAL * 1000UL
since measurement interval is in ms already

DeepSleep works for me. Remember to wire connect RST with GPIO16 to enable wake up capability. Might be a different GPIO on a board other than my Adafruit Feather HUZZAH.

Hi there,

regarding the hardware wiring required to enable wakeup of the MCU:

… where @Thias is using an Adafruit Feather HUZZAH: Which kind of device are you currently using, @gtuveri, where the respective pin is labeled D0?

I’m just asking to make the documentation as precise as possible.