753 lines
19 KiB
C++
753 lines
19 KiB
C++
|
|
// The ESP8266 RTC memory is arranged into blocks of 4 bytes. The access methods read and write 4 bytes at a time,
|
|
// so the RTC data structure should be padded to a 4-byte multiple.
|
|
struct {
|
|
uint32_t crc32; // 4 bytes
|
|
uint8_t channel; // 1 byte, 5 in total
|
|
uint8_t bssid[6]; // 6 bytes, 11 in total
|
|
uint8_t txPow = 0; // 1 byte, 12 in total
|
|
IPAddress mqttServer = mqttBroker; //save the dns lookup
|
|
#ifdef CCS_USE
|
|
bool ccsInit = false;
|
|
#endif
|
|
#ifdef SGP30_USE
|
|
bool sgpInit = false;
|
|
#endif
|
|
} rtcData;
|
|
/************************* RTC Mem *********************************/
|
|
#define WiFi_RTC 0
|
|
/************************* SSD1306 SPI *********************************/
|
|
#ifdef OLED_OUTPUT
|
|
#include <SSD1306.h>
|
|
SSD1306 display(0x3c, D4, D3);
|
|
//#include "OLEDDisplayUi.h"
|
|
#include "DejaVu_Sans_Mono_18.h"
|
|
// Initialize the OLED display using SPI
|
|
// D5 -> CLK
|
|
// D7 -> MOSI (DOUT)
|
|
// D1 -> RES
|
|
// D2 -> DC
|
|
// D8 -> CS
|
|
SSD1306Spi display(D1, D2, D8);
|
|
OLEDDisplayUi ui( &display );
|
|
#endif
|
|
/************************* BMP280 I2C *********************************/
|
|
#ifdef BME2_USE
|
|
//https://github.com/finitespace/BME280#usage
|
|
#include <BME280I2C.h>
|
|
#include "EnvironmentCalculations.h"
|
|
BME280I2C bme;
|
|
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
|
|
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
|
|
#endif
|
|
/************************* BMP680 I2C *********************************/
|
|
#ifdef BME6_USE //ToDo
|
|
/*
|
|
//https://github.com/finitespace/BME280#usage
|
|
#include <BME280I2C.h>
|
|
#include "EnvironmentCalculations.h"
|
|
BME280I2C bme6;
|
|
const bool metric = true;
|
|
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
|
|
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
|
|
*/
|
|
#endif
|
|
/************************* SHTXX I2C *********************************/
|
|
#ifdef SHT_USE
|
|
#include <SHTSensor.h>
|
|
SHTSensor sht(SHTSensor::SHT3X_ALT);
|
|
#endif
|
|
/************************* VEML6075 I2C *********************************/
|
|
#ifdef VEML_USE
|
|
//https://github.com/schizobovine/VEML6075
|
|
#include <VEML6075.h>
|
|
//#include <SparkFun_VEML6075_Arduino_Library.h>
|
|
VEML6075 uvMeter;
|
|
#endif
|
|
/************************* BH1750 I2C *********************************/
|
|
#ifdef BH_USE
|
|
//https://github.com/claws/BH1750
|
|
#include <BH1750.h>
|
|
BH1750 lightMeter;
|
|
#endif
|
|
/************************* CCS811 I2C *********************************/
|
|
#ifdef CCS_USE
|
|
//https://github.com/LucAce/CCS811
|
|
#include "CCS811.h"
|
|
|
|
// Error ID code
|
|
enum {
|
|
CCS811_ERROR_CODE_WRITE_REG_INVALID = B00000001,
|
|
CCS811_ERROR_CODE_READ_REG_INVALID = B00000010,
|
|
CCS811_ERROR_CODE_MEASMODE_INVALID = B00000100,
|
|
CCS811_ERROR_CODE_MAX_RESISTANCE = B00001000,
|
|
CCS811_ERROR_CODE_HEATER_FAULT = B00010000,
|
|
CCS811_ERROR_CODE_HEATER_SUPPLY = B00100000,
|
|
};
|
|
#ifdef SERIAL_DEBUG
|
|
//*****************************************************************************
|
|
// Function: errorDecode
|
|
// Environment decodes the single bits from the error return
|
|
//*****************************************************************************
|
|
void errorDecode(uint8_t error_code) {
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_WRITE_REG_INVALID)) Serial.println(F("ERROR: Wrong write request received"));
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_READ_REG_INVALID)) Serial.println(F("ERROR: Wrong read request received"));
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_MEASMODE_INVALID)) Serial.println(F("ERROR: Wrong meausrement mode request received"));
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_MAX_RESISTANCE)) Serial.println(F("ERROR: Maximum sensor resistance reached!"));
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_HEATER_FAULT)) Serial.println(F("ERROR: Heater current out of range!"));
|
|
if (bitRead(error_code, CCS811_ERROR_CODE_HEATER_SUPPLY)) Serial.println(F("ERROR: Heater supply voltage out of bounce!"));
|
|
}
|
|
#endif
|
|
|
|
// CCS811 I2C Interface
|
|
CCS811 ccs;
|
|
#define CCSINTERRUPT D7 //GPIO13
|
|
#define CCSRESET D6 //GPIO12
|
|
#endif
|
|
|
|
#ifdef SGP30_USE
|
|
#include "SparkFun_SGP30_Arduino_Library.h"
|
|
SGP30 sgp;
|
|
#endif
|
|
|
|
void messageReceived(String &topic, String &payload) {
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println("incoming: " + topic + " - " + payload);
|
|
#endif
|
|
}
|
|
/************** generic settings **************************/
|
|
void sleep(int duration, RFMode type) {
|
|
#ifdef SERIAL_DEBUG
|
|
//flush UART (pg. 11 esp8266 low power solution)
|
|
Serial.flush();
|
|
delay(10);
|
|
#endif
|
|
ESP.deepSleep(duration, type);
|
|
yield();
|
|
delay(100);
|
|
}
|
|
uint32_t calculateCRC32( const uint8_t *data, size_t length ) {
|
|
uint32_t crc = 0xffffffff;
|
|
while ( length-- ) {
|
|
uint8_t c = *data++;
|
|
for ( uint32_t i = 0x80; i > 0; i >>= 1 ) {
|
|
bool bit = crc & 0x80000000;
|
|
if ( c & i ) {
|
|
bit = !bit;
|
|
}
|
|
|
|
crc <<= 1;
|
|
if ( bit ) {
|
|
crc ^= 0x04c11db7;
|
|
}
|
|
}
|
|
}
|
|
|
|
return crc;
|
|
}
|
|
|
|
#ifdef BATTERY_USE
|
|
uint32_t voltageDivCorrelation(uint32_t u3) {
|
|
|
|
const unsigned int offset = 8;
|
|
|
|
if (u3 < offset) {
|
|
return BATT_MEASUREMENT_OFFSET;
|
|
}
|
|
|
|
//translate the 10bit value to reference voltage of 1.0V
|
|
//Resistors are usually in kOhm
|
|
|
|
//ToDo: Not working! adc contains millivoltage at native adc port
|
|
uint32_t adc = map (u3 - offset, 0, 1023, 0 , 1000);
|
|
const uint32_t r1 = 395;
|
|
const uint32_t r2 = 220;
|
|
const uint32_t r3 = 100;
|
|
uint32_t rges = r1 + r2 + r3;
|
|
uint32_t uges = u3 * rges / r3;
|
|
//TODO why?!
|
|
uges = uges / 10;
|
|
return uges;
|
|
}
|
|
|
|
uint32_t adc = 0;
|
|
#endif
|
|
|
|
#if defined(BME2_USE) || defined (BME6_USE)
|
|
float temperature(NAN);
|
|
float humidity(NAN);
|
|
float absHumidity(NAN);
|
|
float pressure(NAN);
|
|
float dew(NAN);
|
|
String temp_str;
|
|
String hum_str;
|
|
String absHum_str;
|
|
String pres_str;
|
|
char temp[7];
|
|
char hum[8];
|
|
char absHum[8];
|
|
char pres[7];
|
|
#endif
|
|
#ifdef BME6_USE
|
|
float iaqF(NAN);
|
|
float iaqprecF(NAN);
|
|
String iaq_str;
|
|
String iaqprec_str;
|
|
char iaq[5];
|
|
char iaqprec[5];
|
|
#endif
|
|
#if defined(SHT_USE) || defined(SI7021_USE)
|
|
float temperature(NAN);
|
|
float humidity(NAN);
|
|
float absHumidity(NAN);
|
|
float dew(NAN);
|
|
String temp_str;
|
|
String hum_str;
|
|
String absHum_str;
|
|
char temp[7];
|
|
char hum[8];
|
|
char absHum[8];
|
|
#endif
|
|
#ifdef BH_USE
|
|
float vislight(NAN);
|
|
String light_str;
|
|
char light[8];
|
|
#endif
|
|
#ifdef VEML_USE
|
|
float uvalight(NAN);
|
|
float uvblight(NAN);
|
|
float uvi(NAN);
|
|
String uva_str;
|
|
String uvb_str;
|
|
String uvindex_str;
|
|
char uva[8];
|
|
char uvb[8];
|
|
char uvindex[5];
|
|
#endif
|
|
#if defined(CCS_USE) || defined(SGP30_USE)
|
|
float eco2(NAN);
|
|
String eco2_str;
|
|
char eco2C[8];
|
|
float tvoc(NAN);
|
|
String tvoc_str;
|
|
char tvocC[8];
|
|
#endif
|
|
#ifdef BATTERY_USE
|
|
float battery(NAN);
|
|
String batt_str;
|
|
char batt[7];
|
|
#endif
|
|
|
|
bool wifiCheck = false;
|
|
bool mqttCheck = false;
|
|
bool bme280Check = false;
|
|
bool bme680Check = false;
|
|
bool veml6075Check = false;
|
|
bool bh1750Check = false;
|
|
bool ccs811Check = false;
|
|
bool sht30Check = false;
|
|
bool sgp30Check = false;
|
|
|
|
WiFiClient mqttSocket;
|
|
MQTTClient mqttClient;
|
|
/*************************** Sketch Code ************************************/
|
|
void initSensors() {
|
|
//assign i2c pins to different pins. SPI is hardware defined. | Wire.begin(SDA,SCL) | CLK D3 | DATA D4 --> be aware that a lot libs do that internally
|
|
//Wire.begin(D4, D3); //nodemcu
|
|
Wire.begin(D2, D1); //wemos D1 mini
|
|
/*********************SSD1306 OLED init **************************************/
|
|
#ifdef OLED_OUTPUT
|
|
display.init();
|
|
display.flipScreenVertically();
|
|
//display.setFont(DejaVu_Sans_Mono_18);
|
|
display.setFont(ArialMT_Plain_10);
|
|
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
|
display.displayOn();
|
|
#endif
|
|
|
|
/*********************BH1750 I2C init **************************************/
|
|
#ifdef BH_USE
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print("\tBH1750 init...\t");
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "BH1750 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!lightMeter.begin(BH1750::ONE_TIME_HIGH_RES_MODE))
|
|
{
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println("no BH1750 anwering");
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BH1750 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
else {
|
|
bh1750Check = true;
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println("BH1750 ready.");
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BH1750 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
/*********************VEML6075 I2C init **************************************/
|
|
#ifdef VEML_USE
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tVEML6075 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "VEML6075 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
uvMeter.begin();
|
|
if (!uvMeter.getDevID())
|
|
{
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no VEML6075 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "VEML6075 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
veml6075Check = true;
|
|
//set one time measurementw
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("VEML6075 ready."));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "VEML6075 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
/*********************BME680 I2C init **************************************/
|
|
#ifdef BME6_USE
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tBME680 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "BME680 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!bme6.begin())
|
|
{
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no BME680 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BME680 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
bme680Check = true;
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("BME680 ready."));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BME680 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/*********************BME280 I2C init **************************************/
|
|
#ifdef BME2_USE
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tBME280 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "BME280 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!bme.begin())
|
|
{
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no BME280 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BME280 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
bme280Check = true;
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("BME280 ready."));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "BME280 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
/*********************SHT3X I2C init **************************************/
|
|
#ifdef SHT_USE
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tSHT30 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "SHT30 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!sht.init())
|
|
{
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no SHT30 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "SHT30 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
sht30Check = true;
|
|
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); // only supported by SHT3x
|
|
yield();
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("SHT30 ready."));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "SHT30 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
/*********************CCS811 I2C init **************************************/
|
|
#ifdef CCS_USE
|
|
// Extend I2C clock stretch timeout (See Notes)
|
|
//Wire.setClockStretchLimit(500);
|
|
Wire.setClockStretchLimit(200000);
|
|
pinMode(CCSINTERRUPT, INPUT);
|
|
//pinMode(CCSRESET, OUTPUT);
|
|
delay(10);
|
|
digitalWrite(CCSRESET, HIGH);
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tCCS811 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "CCS811 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!ccs.begin())
|
|
{
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no CCS811 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "CCS811 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
ccs811Check = true;
|
|
if (!rtcData.ccsInit) {
|
|
Serial.println(F("CCS811 not initialised"));
|
|
rtcData.ccsInit = true;
|
|
}
|
|
//set CCS811 measurement mode
|
|
ccs.writeMeasModeRegister(CCS811_DRIVE_MODE_1SEC , 1 , 0);
|
|
//Serial.println(F("INFO: Set measurement refresh to 1s"));
|
|
//enable Interrupt
|
|
ccs.enableInterrupt();
|
|
//Serial.println(F("INFO: Enable interrupt"));
|
|
/*while (!digitalRead(CCSINTERRUPT))
|
|
{
|
|
delay(200);
|
|
Serial.print(".");
|
|
}
|
|
while (!ccs.isDATA_READY())
|
|
{
|
|
delay(100);
|
|
ccs.readStatusRegister();
|
|
Serial.print(".");
|
|
};
|
|
*/
|
|
// ToDo why and reasons
|
|
//float temp = ccs.calculateTemperature();
|
|
ccs.setTempOffset(temperature - 25.0);
|
|
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("CCS811 ready."));
|
|
/*
|
|
// Print CCS811 sensor information
|
|
Serial.println(F("CCS811 Sensor Enabled:"));
|
|
Serial.print(F("Hardware ID: 0x"));
|
|
Serial.println(ccs.getHWID(), HEX);
|
|
Serial.print(F("Hardware Version: 0x"));
|
|
Serial.println(ccs.getHWVersion(), HEX);
|
|
Serial.print(F("Firmware Boot Version: 0x"));
|
|
Serial.println(ccs.getFWBootVersion(), HEX);
|
|
Serial.print(F("Firmware App Version: 0x"));
|
|
Serial.println(ccs.getFWAppVersion(), HEX);
|
|
Serial.println(); */
|
|
#endif
|
|
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "CCS811 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
/*********************SGP30 I2C init **************************************/
|
|
#ifdef SGP30_USE
|
|
// Extend I2C clock stretch timeout (See Notes)
|
|
//Wire.setClockStretchLimit(500);
|
|
Wire.setClockStretchLimit(400000);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("\tSGP30 init...\t"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
// clear the display
|
|
display.clear();
|
|
display.drawStringMaxWidth(0, 0, 128, "SGP30 init" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
if (!sgp.begin())
|
|
{
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("no SGP30 detected!"));
|
|
#endif
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "SGP30 FAILED" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
|
|
}
|
|
else {
|
|
sgp30Check = true;
|
|
delay(100);
|
|
/*
|
|
//Get SGP30's ID
|
|
sgp.getSerialID();
|
|
//Get version number
|
|
sgp.getFeatureSetVersion();
|
|
Serial.print("SerialID: 0x");
|
|
Serial.print((unsigned long)sgp.serialID, HEX);
|
|
Serial.print("\tFeature Set Version: 0x");
|
|
Serial.println(sgp.featureSetVersion, HEX);*/
|
|
SGP30ERR error;
|
|
//measureTest() should not be called after a call to initAirQuality()
|
|
error = sgp.measureTest();
|
|
if (error == SUCCESS) {
|
|
Serial.println("Success!");
|
|
}
|
|
else if (error == ERR_BAD_CRC) {
|
|
Serial.println("CRC Failed");
|
|
}
|
|
else if (error == ERR_I2C_TIMEOUT) {
|
|
Serial.println("I2C Timed out");
|
|
}
|
|
else if (error == SELF_TEST_FAIL) {
|
|
Serial.println("Self Test Failed");
|
|
}
|
|
//if (!rtcData.sgpInit) {
|
|
if (error == SELF_TEST_FAIL)
|
|
{
|
|
Serial.println(F("SGP30 not initialised"));
|
|
sgp.initAirQuality();
|
|
Serial.println(F("SGP30 warm up "));
|
|
|
|
error = sgp.measureTest();
|
|
if (error == SUCCESS) {
|
|
rtcData.sgpInit = true;
|
|
}
|
|
}
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("SGP30 ready."));
|
|
#endif
|
|
|
|
|
|
#ifdef OLED_OUTPUT
|
|
display.drawStringMaxWidth(0, 16, 128, "SGP30 ready" );
|
|
// write the buffer to the display
|
|
display.display();
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/******************** i2c init END ****************/
|
|
}
|
|
|
|
|
|
|
|
void setup() {
|
|
pinMode(D0, WAKEUP_PULLUP);
|
|
// if serial is not initialized all following calls to serial end dead.
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.flush();
|
|
Serial.begin(9600);
|
|
while (!Serial) {
|
|
delay(1);
|
|
} // Wait
|
|
Serial.print(F("\nReset reason : \t\t\t"));
|
|
Serial.println(ESP.getResetReason());
|
|
#endif
|
|
WiFi.forceSleepBegin(); // send wifi to sleep to reduce power consumption
|
|
yield();
|
|
delay(100);
|
|
#ifdef BATTERY_USE
|
|
//check battery status
|
|
//Battery Voltage Measurement
|
|
//pinMode(D6, OUTPUT);
|
|
//digitalWrite(D6, HIGH); //activate transistor
|
|
//yield();
|
|
//delay(10);
|
|
pinMode(A0, INPUT);
|
|
yield();
|
|
adc = analogRead(A0);
|
|
yield();
|
|
delay(10);
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.print(F("ADC_measurement: \t\t\t"));
|
|
Serial.println (String(adc));
|
|
Serial.print(F("VoltageDividerCorrelation in V: \t"));
|
|
Serial.println(String(voltageDivCorrelation(adc)));
|
|
#endif
|
|
yield();
|
|
delay(10);
|
|
// go to sleep if to low
|
|
if (voltageDivCorrelation(adc) - BATT_MEASUREMENT_OFFSET < BATT_WARNING_VOLTAGE) {
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("Low Battery Voltage. Got to sleep"));
|
|
#endif
|
|
sleep(SLEEP_TIME_LOW_BAT, WAKE_RF_DISABLED);
|
|
}
|
|
#endif
|
|
|
|
//go further if not
|
|
//init wifi
|
|
wifiCheck = wifi_connect();
|
|
if (wifiCheck) {
|
|
//connect mqtt
|
|
if (!mqttClient.loop()) {
|
|
//connect mqtt
|
|
mqttCheck = mqtt_connect();
|
|
}
|
|
if (mqttCheck) {
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("Sensor init routine"));
|
|
yield();
|
|
#endif
|
|
initSensors();
|
|
yield();
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("--------measurement--------"));
|
|
yield();
|
|
#endif
|
|
measurement();
|
|
yield();
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("---------------------------"));
|
|
yield();
|
|
#endif
|
|
mqtt_disconnect();
|
|
yield();
|
|
}
|
|
//firmware update check
|
|
/*if (firmware_available()
|
|
//{
|
|
// get firmware
|
|
}*/
|
|
//regular --check whether 5min leads to wifi timeout
|
|
wifi_disconnect();
|
|
yield();
|
|
if (mqttCheck) {
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("regular sleep"));
|
|
Serial.println(F("***********************************************************"));
|
|
#endif
|
|
sleep(SLEEP_TIME_MEASUREMENT, WAKE_RF_DEFAULT);
|
|
|
|
}
|
|
else {
|
|
//ToDo Do more useful stuff
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("mqtt failed - wifi timeout sleep"));
|
|
#endif
|
|
sleep(SLEEP_TIME_WIFI_TIMEOUT, WAKE_RF_DEFAULT);
|
|
|
|
}
|
|
}
|
|
//no wifi available
|
|
else {
|
|
#ifdef SERIAL_DEBUG
|
|
Serial.println(F("Wifi failed"));
|
|
#endif
|
|
sleep(SLEEP_TIME_WIFI_TIMEOUT, WAKE_RFCAL);
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
yield();
|
|
}
|