esp8266_deepsleep/deepSleep.ino
2019-05-14 08:33:58 +02:00

274 lines
7.0 KiB
C++

#include <vector>
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h" // Required for wifi_station_connect() to work
}
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define USE_BME680
#ifdef USE_BME680
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME680 bme; // I2C
#define BME_TEMPERATURE_FEED_FORMAT "/feeds/mathieu/portable/bme/temperature"
#define BME_HUMIDITY_FEED_FORMAT "/feeds/mathieu/portable/bme/humidity"
#define BME_VOLTAGE_FEED_FORMAT "/feeds/mathieu/portable/bme/voltage"
#define BME_PRESSURE_FEED_FORMAT "/feeds/mathieu/portable/bme/pressure"
#define BME_GAZ_FEED_FORMAT "/feeds/mathieu/portable/bme/gaz"
#endif
// if bigger than 4295, modem will wake up anyway? c.f. forceSleepBegin.
// https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf
// say no
// should stick on 64bits when mul by 1000000 -> shoudl be smaller than ~18000.10^9 ~580000year
#define SLEEP_TIME_SECOND 10*60
#ifdef USE_DHT
#include <DHT.h>
#define DHTTYPE DHT11
#define DHTPIN D3
#define DHT_POWER_PIN 13
DHT dht(DHTPIN, DHTTYPE);
#define TEMPERATURE_FEED_FORMAT "/feeds/mathieu/portable/temperature"
#define HUMIDITY_FEED_FORMAT "/feeds/mathieu/portable/humidity"
#define VOLTAGE_FEED_FORMAT "/feeds/mathieu/portable/voltage"
#endif
#define FPM_SLEEP_MAX_TIME 0xFFFFFFF // Could be replace by ESP.deepSleepMax() -> https://thingpulse.com/max-deep-sleep-for-esp8266/
#define MQTT_SERVER "192.168.0.250"
#define MQTT_USERNAME "XXXXXX"
#define MQTT_PASSWD "XXXXX"
#define MQTT_PORT 1883
WiFiClient client;
Adafruit_MQTT_Client *mqtt;
Adafruit_MQTT_Publish *mqtt_temp;
Adafruit_MQTT_Publish *mqtt_pressure;
Adafruit_MQTT_Publish *mqtt_voltage;
//const char *ssid = "AndroidAP-Mathieu";
//const char *password = "bonjourwifi";
const char *ssid = "freebox_sarah";
const char *password = "barca2grenada";
uint8_t bssid[6] = {0x14, 0x0C, 0x76, 0xB1, 0x37, 0x32};
int32_t channel = 11; //0 for Auto
ADC_MODE(ADC_VCC);
void setup()
{
#ifdef USE_DHT
// Power on DHT11
pinMode(DHT_POWER_PIN, OUTPUT);
digitalWrite(DHT_POWER_PIN, HIGH);
#endif
Serial.begin(115200);
Serial.print("\nRunning\n");
#ifdef USE_BME680
if (!bme.begin()) {
Serial.println("Could not find a valid BME680 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
#endif
}
// ESP.deepSleep( X, WAKE_RF_DISABLED ); disable the radio interface and it can't be
// activated after
// So use WAKE_RF_DEFAULT and play with wifi stat manually
void WiFiOn() // vs WiFi.forceSleepWake();
{
wifi_fpm_do_wakeup();
wifi_fpm_close();
Serial.println("Reconnecting");
wifi_set_opmode(STATION_MODE);
wifi_station_connect();
}
int WiFiOff() // vs WiFi.forceSleepBegin();
{
// Serial.println("diconnecting client and wifi");
//client.disconnect();
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_set_sleep_type(MODEM_SLEEP_T);
wifi_fpm_open();
return wifi_fpm_do_sleep(FPM_SLEEP_MAX_TIME);
}
struct mqttInfo {
float value;
char *topic;
};
int mqttConnect(std::vector<struct mqttInfo> tab) {
mqtt = new Adafruit_MQTT_Client(&client, MQTT_SERVER, MQTT_PORT,
MQTT_USERNAME, MQTT_USERNAME, MQTT_PASSWD);
uint8_t retries = 3;
Serial.println("Connecting to mqtt");
while ((mqtt->connect()) != 0) { // connect will return 0 for connected
mqtt->disconnect();
delay(100); // wait
retries--;
if (retries == 0) {
Serial.println("Cannot connect to mqtt");
return -1;
}
}
Serial.println("Sending mqtt info");
for (auto info : tab) {
Serial.print("publishing ");
Serial.print(info.value);
Serial.print(" for ");
Serial.println(info.topic);
Adafruit_MQTT_Publish client(mqtt, info.topic, 0);
if (!client.publish(info.value))
Serial.println("Fail :(");
}
//Do we need this ? Wifi will be cut anyway
mqtt->disconnect();
return 0;
}
int doBMEMeasure() {
#ifdef USE_BME680
if (! bme.performReading()) {
Serial.println("Failed to perform reading :(");
return -1;
}
Serial.print("Temperature = ");
Serial.print(bme.temperature);
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.pressure / 100.0);
Serial.println(" hPa");
Serial.print("Humidity = ");
Serial.print(bme.humidity);
Serial.println(" %");
Serial.print("Gas = ");
Serial.print(bme.gas_resistance / 1000.0);
Serial.println(" KOhms");
std::vector<struct mqttInfo> bmeInfo;
bmeInfo.push_back({bme.humidity, BME_HUMIDITY_FEED_FORMAT});
bmeInfo.push_back({bme.temperature, BME_TEMPERATURE_FEED_FORMAT});
bmeInfo.push_back({bme.pressure / 100.0, BME_PRESSURE_FEED_FORMAT});
bmeInfo.push_back({bme.gas_resistance / 1000.0, BME_GAZ_FEED_FORMAT});
bmeInfo.push_back({(float)ESP.getVcc(), BME_VOLTAGE_FEED_FORMAT});
wifiConnect();
mqttConnect(bmeInfo);
if (WiFiOff()) {
//if (WiFi.forceSleepBegin(0)) {
Serial.println("Fail to set sleep mode");
}
#else
return 0;
#endif
}
int wifiConnect() {
WiFiOn();
//WiFi.forceSleepWake();
IPAddress ip(192, 168, 0, 251);
IPAddress gateway(192, 168, 0, 254);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password, channel, bssid);
int retry = 10;
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
if (retry < 0)
continue;
retry --;
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
return 0;
}
int doDHTMeasure()
{
#ifdef USE_DHT
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return -1;
}
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print("Heat index: ");
Serial.print(hic);
Serial.print(" *C ");
std::vector<struct mqttInfo> dhtInfo;
dhtInfo.push_back({h, HUMIDITY_FEED_FORMAT});
dhtInfo.push_back({t, TEMPERATURE_FEED_FORMAT});
dhtInfo.push_back({(float)ESP.getVcc(), VOLTAGE_FEED_FORMAT});
wifiConnect();
mqttConnect(dhtInfo);
if (WiFiOff()) {
//if (WiFi.forceSleepBegin(0)) {
Serial.println("Fail to set sleep mode");
}
return 0;
#else
return 0;
#endif
}
void loop()
{
// Wait for DHT to be ready
delay(2000);
doDHTMeasure();
doBMEMeasure();
ESP.deepSleep(SLEEP_TIME_SECOND * 1000000, WAKE_RF_DEFAULT);
}