Compare commits

..

No commits in common. "master" and "bme688" have entirely different histories.

6 changed files with 96 additions and 256 deletions

View File

@ -3,7 +3,7 @@ located in IKEAs Vindriktning
after this upgrade it will measure: after this upgrade it will measure:
* air quality * air quality
* temperature * temperatur
* pressure * pressure
* altitude * altitude
@ -39,10 +39,10 @@ VCC | GND
``` ```
The following pins are used: The following pins are used:
* GPIO4 PM1006 particle sensor PIN REST on Vindriktning board * GPIO4 PM1006 particle sensor
* GPIO2 WS2812 stripe out of three LEDs, replacing the original LEDs at front * GPIO2 WS2812 stripe out of three LEDs, replacing the orignal LEDs at front
* GPIO15 Red LED (optional) * GPIO15 Red LED (optional)
* GPIO12 Green LED (optional) Used as 3.3V Supply for the I2C sensor * GPIO12 Green LED (optional)
* GPIO13 Blue LED (optional) * GPIO13 Blue LED (optional)
* GPIO13 VCC of I2C (3.3 V) * GPIO13 VCC of I2C (3.3 V)
* GPIO14 I2C clock * GPIO14 I2C clock
@ -55,6 +55,4 @@ The following pins are used:
* some wire * some wire
# Sources # Sources
For the Witty board * [https://github.com/amkuipers/witty Witty pinout]
* [https://github.com/amkuipers/witty Witty pinout]
* [https://arduino.ua/products_pictures/large_AOC361-5.jpg Schematics]

View File

@ -27,7 +27,7 @@ usage: ota_updater.py [-h] -l BROKER_HOST -p BROKER_PORT [-u BROKER_USERNAME]
[-d BROKER_PASSWORD] [-t BASE_TOPIC] -i DEVICE_ID [-d BROKER_PASSWORD] [-t BASE_TOPIC] -i DEVICE_ID
firmware firmware
ota firmware update script for ESP8226 implementation of the Homie mqtt IoT ota firmware update scirpt for ESP8226 implemenation of the Homie mqtt IoT
convention. convention.
positional arguments: positional arguments:

View File

@ -7,6 +7,5 @@ if [ $? -ne 0 ]; then
fi fi
codespell -w ../src/* codespell -w ../src/*
codespell -w ../include/* codespell -w ../include/*
codespell -w ../*.md codespell ../Readme.md
codespell -w *.md
exit 0 exit 0

View File

@ -12,7 +12,7 @@
#ifndef HOMIE_SETTINGS #ifndef HOMIE_SETTINGS
#define HOMIE_SETTINGS #define HOMIE_SETTINGS
#define HOMIE_FIRMWARE_NAME "RoomSensor" #define HOMIE_FIRMWARE_NAME "Vindriktning"
#define HOMIE_FIRMWARE_VERSION "2.3.0" #define HOMIE_FIRMWARE_VERSION "1.2.1"
#endif #endif

View File

@ -12,17 +12,11 @@
platform = espressif8266 platform = espressif8266
board = d1_mini board = d1_mini
framework = arduino framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY -D BME680 build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
; build_flag needs define the Bosch sensor...
; -D BMP280
;or
; -D BME680
; the latest development branch (convention V3.0.x) ; the latest development branch (convention V3.0.x)
lib_deps = https://github.com/homieiot/homie-esp8266.git#develop lib_deps = https://github.com/homieiot/homie-esp8266.git#develop
EspSoftwareSerial EspSoftwareSerial
NeoPixel NeoPixel
adafruit/Adafruit BMP280 Library @ ^2.4.2
adafruit/Adafruit BME680 Library @ ^2.0.1 adafruit/Adafruit BME680 Library @ ^2.0.1
upload_port = /dev/ttyUSB0 upload_port = /dev/ttyUSB1

View File

@ -18,42 +18,30 @@
#include <Adafruit_NeoPixel.h> #include <Adafruit_NeoPixel.h>
#include <Wire.h> #include <Wire.h>
#include <Adafruit_Sensor.h> #include <Adafruit_Sensor.h>
#ifdef BME680
#include "Adafruit_BME680.h" #include "Adafruit_BME680.h"
#else
#ifdef BMP280
#include "Adafruit_BMP280.h"
#else
#error "Decition, which BMx??? is used missing"
#endif
#endif
/****************************************************************************** /******************************************************************************
* DEFINES * DEFINES
******************************************************************************/ ******************************************************************************/
#define GPIO_WS2812 D4 /**< GPIO2 */ #define GPIO_WS2812 D4 /**< GPIO2 */
#define SENSOR_PM1006_RX D2 /**< GPIO4 */ #define SENSOR_PM1006_RX D2 /**< GPIO4 */
#define SENSOR_PM1006_TX -1 /**< Unused */ #define SENSOR_PM1006_TX -1 /**< Unused */
#define WITTY_RGB_R D8 /**< GPIO15 */ #define WITTY_RGB_R D8 /**< GPIO15 */
#define WITTY_RGB_G D6 /**< GPIO12 Used as 3.3V Power supply for the I2C Sensor */ #define WITTY_RGB_G D6 /**< GPIO12 */
#define WITTY_RGB_B D7 /**< GPIO13 */ #define WITTY_RGB_B D7 /**< GPIO13 */
#define PM1006_BIT_RATE 9600 #define PM1006_BIT_RATE 9600
#define PM1006_MQTT_UPDATE 30000 /**< Check the sensor every 30 seconds; New measurement is done every 20seconds by the PM1006 sensor */ #define PM1006_MQTT_UPDATE 5000 /**< Check the sensor every 10 seconds; New measurement is done every 20seconds by the sensor */
#define PIXEL_COUNT 3 #define PIXEL_COUNT 3
#define GPIO_BUTTON SENSOR_PM1006_RX /**< Button and software serial share one pin on Witty board */ #define GPIO_BUTTON SENSOR_PM1006_RX /**< Button and software serial share one pin on Witty board */
#define SENSOR_I2C_SCK D5 /**< GPIO14 - I2C clock pin */ #define SENSOR_I2C_SCK D1 /**< GPIO14 - I2C clock pin */
#define SENSOR_I2C_SDI D1 /**< GPIO5 - I2C data pin */ #define SENSOR_I2C_SDI D5 /**< GPIO5 - I2C data pin */
#define PM1006_BIT_RATE 9600
#define PM1006_MQTT_UPDATE 5000 /**< Check the sensor every 10 seconds; New measurement is done every 20seconds by the sensor */
#define SEALEVELPRESSURE_HPA (1013.25) #define SEALEVELPRESSURE_HPA (1013.25)
#define BUTTON_MAX_CYCLE 10000U /**< Action: Reset configuration */
#define BUTTON_MIN_ACTION_CYCLE 55U /**< Minimum cycle to react on the button (e.g. 5 second) */
#define BUTTON_CHECK_INTERVALL 100U /**< Check every 100 ms the button state */
#define MIN_MEASURED_CYCLES 2
#define PM_MAX 1001 /**< According datasheet https://en.gassensor.com.cn/ParticulateMatterSensor/info_itemid_105.html 1000 is the maximum */
#define LOG_TOPIC "log\0" #define LOG_TOPIC "log\0"
#define MQTT_LEVEL_ERROR 1 #define MQTT_LEVEL_ERROR 1
#define MQTT_LEVEL_WARNING 10 #define MQTT_LEVEL_WARNING 10
@ -74,8 +62,6 @@
strcat(topic, "/"); \ strcat(topic, "/"); \
strcat(topic, test); strcat(topic, test);
#define PERCENT2FACTOR(b, a) ((b * a.get()) / 100)
#define NUMBER_TYPE "Number" #define NUMBER_TYPE "Number"
#define NODE_PARTICLE "particle" #define NODE_PARTICLE "particle"
#define NODE_TEMPERATUR "temp" #define NODE_TEMPERATUR "temp"
@ -84,8 +70,6 @@
#define NODE_GAS "gas" #define NODE_GAS "gas"
#define NODE_HUMIDITY "humidity" #define NODE_HUMIDITY "humidity"
#define NODE_AMBIENT "ambient" #define NODE_AMBIENT "ambient"
#define NODE_BUTTON "button"
#define SERIAL_RCEVBUF_MAX 80 /**< Maximum 80 characters can be received from the PM1006 sensor */
/****************************************************************************** /******************************************************************************
* TYPE DEFS * TYPE DEFS
******************************************************************************/ ******************************************************************************/
@ -102,62 +86,36 @@ void log(int level, String message, int code);
bool mConfigured = false; bool mConfigured = false;
bool mConnected = false; bool mConnected = false;
bool mOTAactive = false; /**< Stop sleeping, if OTA is running */
bool mFailedI2Cinitialization = false; bool mFailedI2Cinitialization = false;
long mLastButtonAction = 0;
/******************************* Sensor data **************************/ /******************************* Sensor data **************************/
HomieNode particle(NODE_PARTICLE, "particle", "number"); /**< Measuret in micro gram per quibik meter air volume */ HomieNode particle(NODE_PARTICLE, "particle", "number"); /**< Measuret in micro gram per quibik meter air volume */
HomieNode temperaturNode(NODE_TEMPERATUR, "Room Temperature", "number"); HomieNode temperatureNode(NODE_TEMPERATUR, "Room Temperature", "number");
HomieNode pressureNode(NODE_PRESSURE, "Pressure", "number"); HomieNode pressureNode(NODE_PRESSURE, "Pressure", "number");
HomieNode altitudeNode(NODE_ALTITUDE, "Altitude", "number"); HomieNode altitudeNode(NODE_ALTITUDE, "Altitude", "number");
#ifdef BME680
HomieNode gasNode(NODE_GAS, "Gas", "number"); HomieNode gasNode(NODE_GAS, "Gas", "number");
HomieNode humidityNode(NODE_HUMIDITY, "Humidity", "number"); HomieNode humidityNode(NODE_HUMIDITY, "Humidity", "number");
#endif
HomieNode buttonNode(NODE_BUTTON, "Button", "number");
/****************************** Output control ***********************/ /****************************** Output control ***********************/
HomieNode ledStripNode /* to rule them all */("led", "RGB led", "color"); HomieNode ledStripNode /* to rule them all */("led", "RGB led", "color");
/************************** Settings ******************************/ /************************** Settings ******************************/
HomieSetting<bool> i2cEnable("i2c", HomieSetting<bool> i2cEnable("i2c", "BME280 sensor present");
#ifdef BME680 HomieSetting<bool> rgbTemp("rgbTemp", "Show temperatur via red (>20 °C) and blue (< 20°C)");
"BME680 sensor present"
#else
#ifdef BMP280
"BMP280 sensor present"
#else
"No I2C sensor specified in the project"
#endif
#endif
);
HomieSetting<bool> rgbTemp("rgbTemp", "Show temperature via red (>20 °C) and blue (< 20°C)");
HomieSetting<long> rgbDim("rgbDim", "Factor (1 to 200%) of the status LEDs");
HomieSetting<long> deepsleep("deepsleep", "Amount of seconds to sleep (default 0 - always online, maximum 4294 - 71 minutes)");
static SoftwareSerial pmSerial(SENSOR_PM1006_RX, SENSOR_PM1006_TX); static SoftwareSerial pmSerial(SENSOR_PM1006_RX, SENSOR_PM1006_TX);
#ifdef BME680 Adafruit_BME680 bme(&Wire); // connected via I2C
Adafruit_BME680 bmx(&Wire); // connected via I2C
#else
#ifdef BMP280
Adafruit_BMP280 bmx; // connected via I2C
#endif
#endif
Adafruit_NeoPixel strip(PIXEL_COUNT, GPIO_WS2812, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel strip(PIXEL_COUNT, GPIO_WS2812, NEO_GRB + NEO_KHZ800);
// Variablen // Variablen
uint8_t serialRxBuf[SERIAL_RCEVBUF_MAX]; uint8_t serialRxBuf[80];
uint8_t rxBufIdx = 0; uint8_t rxBufIdx = 0;
int mParticle_pM25 = 0; int spm25 = 0;
int last = 0; int last = 0;
unsigned int mButtonPressed = 0; unsigned int mButtonPressed = 0;
bool mSomethingReceived = false; bool mSomethingReceived = false;
uint32_t mMeasureIndex = 0;
/****************************************************************************** /******************************************************************************
* LOCAL FUNCTIONS * LOCAL FUNCTIONS
*****************************************************************************/ *****************************************************************************/
@ -196,12 +154,7 @@ int getSensorData() {
// Header und Prüfsumme checken // Header und Prüfsumme checken
if (serialRxBuf[0] == 0x16 && serialRxBuf[1] == 0x11 && serialRxBuf[2] == 0x0B /* && checksum == 0 */) if (serialRxBuf[0] == 0x16 && serialRxBuf[1] == 0x11 && serialRxBuf[2] == 0x0B /* && checksum == 0 */)
{ {
int pmValue = (serialRxBuf[5] << 8 | serialRxBuf[6]); return (serialRxBuf[5] << 8 | serialRxBuf[6]);
if (pmValue > PM_MAX) {
return (-1);
} else {
return pmValue;
}
} }
else else
{ {
@ -217,84 +170,53 @@ void onHomieEvent(const HomieEvent &event)
{ {
switch (event.type) switch (event.type)
{ {
case HomieEventType::READY_TO_SLEEP:
if (mOTAactive) {
Homie.getLogger() << "Skip sleeping, as OTA was started" << endl;
return;
} else if (deepsleep.get() > 0) {
long sleepInSeconds = deepsleep.get();
Homie.doDeepSleep(sleepInSeconds * 1000000, RF_NO_CAL);
}
break;
case HomieEventType::MQTT_READY: case HomieEventType::MQTT_READY:
mConnected=true; mConnected=true;
digitalWrite(WITTY_RGB_R, LOW); digitalWrite(WITTY_RGB_R, LOW);
if (!i2cEnable.get()) { /** keep green LED activated to power I2C sensor */ if (!i2cEnable.get()) { /** keep green LED activated to power I2C sensor */
digitalWrite(WITTY_RGB_G, LOW); digitalWrite(WITTY_RGB_G, LOW);
log(MQTT_LEVEL_INFO, F("I2C powersupply deactivated"), MQTT_LOG_I2CINIT);
} }
digitalWrite(WITTY_RGB_B, LOW); digitalWrite(WITTY_RGB_B, LOW);
/* Update LED only, if not sleeping */ strip.fill(strip.Color(0,0,128));
if (deepsleep.get() <= 0) { strip.show();
strip.fill(strip.Color(0,0,PERCENT2FACTOR(127, rgbDim)));
strip.show();
}
if (mFailedI2Cinitialization) { if (mFailedI2Cinitialization) {
log(MQTT_LEVEL_DEBUG, log(MQTT_LEVEL_DEBUG, F("Could not find a valid BME680 sensor, check wiring or "
#ifdef BME680 "try a different address!"), MQTT_LOG_I2CINIT);
"Could not find a valid BME680 sensor, check wiring or try a different address!"
#else
#ifdef BMP280
"Could not find a valid BMP280 sensor, check wiring or try a different address!"
#else
"no I2C sensor defined"
#endif
#endif
, MQTT_LOG_I2CINIT);
} else { } else {
log(MQTT_LEVEL_INFO, F("BME680 sensor found"), MQTT_LOG_I2CINIT); log(MQTT_LEVEL_INFO, F("BME680 sensor found"), MQTT_LOG_I2CINIT);
} }
break; break;
case HomieEventType::READY_TO_SLEEP:
break;
case HomieEventType::OTA_STARTED: case HomieEventType::OTA_STARTED:
mOTAactive = true;
break; break;
case HomieEventType::OTA_SUCCESSFUL: case HomieEventType::OTA_SUCCESSFUL:
ESP.restart(); ESP.restart();
break; break;
case HomieEventType::WIFI_CONNECTED:
digitalWrite(WITTY_RGB_B, HIGH);
break;
default: default:
break; break;
} }
} }
void bmpPublishValues() { void bmpPublishValues() {
#ifdef BME680
// Tell BME680 to begin measurement. // Tell BME680 to begin measurement.
unsigned long endTime = bmx.beginReading(); unsigned long endTime = bme.beginReading();
if (endTime == 0) { if (endTime == 0) {
log(MQTT_LEVEL_ERROR, "BMX not accessible", MQTT_LOG_I2READ); log(MQTT_LEVEL_ERROR, F("BME680 not accessable"), MQTT_LOG_I2READ);
return; return;
} }
#endif temperatureNode.setProperty(NODE_TEMPERATUR).send(String(bme.readTemperature()));
// Publish the values pressureNode.setProperty(NODE_PRESSURE).send(String(bme.readPressure() / 100.0F));
temperaturNode.setProperty(NODE_TEMPERATUR).send(String(bmx.readTemperature())); altitudeNode.setProperty(NODE_ALTITUDE).send(String(bme.readAltitude(SEALEVELPRESSURE_HPA)));
pressureNode.setProperty(NODE_PRESSURE).send(String(bmx.readPressure() / 100.0F)); gasNode.setProperty(NODE_GAS).send(String((bme.gas_resistance / 1000.0)));
altitudeNode.setProperty(NODE_ALTITUDE).send(String(bmx.readAltitude(SEALEVELPRESSURE_HPA)));
#ifdef BME680 humidityNode.setProperty(NODE_HUMIDITY).send(String(bme.humidity));
gasNode.setProperty(NODE_GAS).send(String((bmx.gas_resistance / 1000.0)));
humidityNode.setProperty(NODE_HUMIDITY).send(String(bmx.humidity));
#endif
log(MQTT_LEVEL_DEBUG, String("Temp" + String(bmx.readTemperature()) + "\tPressure:" +
String(bmx.readPressure() / 100.0F) + "\t Altitude:"+
String(bmx.readAltitude(SEALEVELPRESSURE_HPA))), MQTT_LOG_I2READ);
if ( (rgbTemp.get()) && (!mSomethingReceived) ) { if ( (rgbTemp.get()) && (!mSomethingReceived) ) {
if (bmx.readTemperature() < TEMPBORDER) { if (bme.readTemperature() < TEMPBORDER) {
strip.setPixelColor(0, strip.Color(0,0,PERCENT2FACTOR(127, rgbDim))); strip.setPixelColor(0, strip.Color(0,0,255));
} else { } else {
strip.setPixelColor(0, strip.Color(PERCENT2FACTOR(127, rgbDim),0,0)); strip.setPixelColor(0, strip.Color(255,0,0));
} }
strip.show(); strip.show();
} }
@ -315,16 +237,16 @@ void loopHandler()
{ {
static long lastRead = 0; static long lastRead = 0;
if ((millis() - lastRead) > PM1006_MQTT_UPDATE) { if ((millis() - lastRead) > PM1006_MQTT_UPDATE) {
mParticle_pM25 = getSensorData(); int pM25 = getSensorData();
if (mParticle_pM25 >= 0) { if (pM25 >= 0) {
particle.setProperty(NODE_PARTICLE).send(String(mParticle_pM25)); particle.setProperty(NODE_PARTICLE).send(String(pM25));
if (!mSomethingReceived) { if (!mSomethingReceived) {
if (mParticle_pM25 < 35) { if (pM25 < 35) {
strip.fill(strip.Color(0, PERCENT2FACTOR(127, rgbDim), 0)); /* green */ strip.fill(strip.Color(0, 255, 0)); /* green */
} else if (mParticle_pM25 < 85) { } else if (pM25 < 85) {
strip.fill(strip.Color(PERCENT2FACTOR(127, rgbDim), PERCENT2FACTOR(64, rgbDim), 0)); /* orange */ strip.fill(strip.Color(255, 127, 0)); /* orange */
} else { } else {
strip.fill(strip.Color(PERCENT2FACTOR(127, rgbDim), 0, 0)); /* red */ strip.fill(strip.Color(255, 0, 0)); /* red */
} }
strip.show(); strip.show();
} }
@ -334,28 +256,9 @@ void loopHandler()
if (i2cEnable.get() && (!mFailedI2Cinitialization)) { if (i2cEnable.get() && (!mFailedI2Cinitialization)) {
bmpPublishValues(); bmpPublishValues();
} }
mMeasureIndex++;
/* Clean cycles buttons */
if (mButtonPressed <= BUTTON_MIN_ACTION_CYCLE) {
buttonNode.setProperty(NODE_BUTTON).send("0");
}
lastRead = millis(); lastRead = millis();
/* If nothing needs to be done, sleep and the time is ready for sleeping */
if (mMeasureIndex > MIN_MEASURED_CYCLES && (deepsleep.get() > 0) ) {
Homie.prepareToSleep();
delay(100);
}
} }
/* if the user sees something via the LEDs, inform MQTT, too */
if (mButtonPressed > BUTTON_MIN_ACTION_CYCLE) {
buttonNode.setProperty(NODE_BUTTON).send(String(mButtonPressed));
}
// Feed the dog -> ESP stay alive // Feed the dog -> ESP stay alive
ESP.wdtFeed(); ESP.wdtFeed();
} }
@ -365,30 +268,23 @@ void loopHandler()
bool ledHandler(const HomieRange& range, const String& value) { bool ledHandler(const HomieRange& range, const String& value) {
if (range.isRange) return false; // only one switch is present if (range.isRange) return false; // only one switch is present
Homie.getLogger() << "Received: " << (value) << endl; mSomethingReceived = true; // Stop animation
if (value.equals("250,250,250")) {
mSomethingReceived = false; // enable animation again int sep1 = value.indexOf(',');
ledStripNode.setProperty(NODE_AMBIENT).send(value); int sep2 = value.indexOf(',', sep1 + 1);
if ((sep1 > 0) && (sep2 > 0)) {
int red = value.substring(0,sep1).toInt(); /* OpenHAB hue (0-360°) */
int green = value.substring(sep1 + 1, sep2).toInt(); /* OpenHAB saturation (0-100%) */
int blue = value.substring(sep2 + 1, value.length()).toInt(); /* brightness (0-100%) */
uint8_t r = (red * 255) / 250;
uint8_t g = (green *255) / 250;
uint8_t b = (blue *255) / 250;
uint32_t c = strip.Color(r,g,b);
strip.fill(c);
strip.show();
ledStripNode.setProperty(NODE_AMBIENT).send(String(r) + "," + String(g) + "," + String(b));
return true; return true;
} else {
mSomethingReceived = true; // Stop animation
int sep1 = value.indexOf(',');
int sep2 = value.indexOf(',', sep1 + 1);
if ((sep1 > 0) && (sep2 > 0)) {
int red = value.substring(0,sep1).toInt();
int green = value.substring(sep1 + 1, sep2).toInt();
int blue = value.substring(sep2 + 1, value.length()).toInt();
uint8_t r = (red * 255) / 250;
uint8_t g = (green *255) / 250;
uint8_t b = (blue *255) / 250;
uint32_t c = strip.Color(r,g,b);
strip.fill(c);
strip.show();
ledStripNode.setProperty(NODE_AMBIENT).send(value);
return true;
}
} }
return false; return false;
} }
@ -400,7 +296,7 @@ bool ledHandler(const HomieRange& range, const String& value) {
*****************************************************************************/ *****************************************************************************/
void setup() void setup()
{ {
SPIFFS.begin(); SPIFFS.begin();
Serial.begin(115200); Serial.begin(115200);
Serial.setTimeout(2000); Serial.setTimeout(2000);
@ -416,19 +312,13 @@ void setup()
Homie.onEvent(onHomieEvent); Homie.onEvent(onHomieEvent);
i2cEnable.setDefaultValue(false); i2cEnable.setDefaultValue(false);
rgbTemp.setDefaultValue(false); rgbTemp.setDefaultValue(false);
rgbDim.setDefaultValue(100).setValidator([] (long candidate) { memset(serialRxBuf, 0, 80);
return (candidate > 1) && (candidate <= 200);
});
deepsleep.setDefaultValue(0).setValidator([] (long candidate) {
return ((candidate >= 0) && (candidate < 4294)); /* between 0 (deactivated) and 71 minutes */
});
memset(serialRxBuf, 0, SERIAL_RCEVBUF_MAX);
pmSerial.begin(PM1006_BIT_RATE); pmSerial.begin(PM1006_BIT_RATE);
Homie.setup(); Homie.setup();
particle.advertise(NODE_PARTICLE).setName("Particle").setDatatype(NUMBER_TYPE).setUnit("micro gram per quibik"); particle.advertise(NODE_PARTICLE).setName("Particle").setDatatype(NUMBER_TYPE).setUnit("micro gram per quibik");
temperaturNode.advertise(NODE_TEMPERATUR).setName("Degrees") temperatureNode.advertise(NODE_TEMPERATUR).setName("Degrees")
.setDatatype("float") .setDatatype("float")
.setUnit("ºC"); .setUnit("ºC");
pressureNode.advertise(NODE_PRESSURE).setName("Pressure") pressureNode.advertise(NODE_PRESSURE).setName("Pressure")
@ -437,70 +327,47 @@ void setup()
altitudeNode.advertise(NODE_ALTITUDE).setName("Altitude") altitudeNode.advertise(NODE_ALTITUDE).setName("Altitude")
.setDatatype("float") .setDatatype("float")
.setUnit("m"); .setUnit("m");
#ifdef BME680
gasNode.advertise(NODE_GAS).setName("Gas") gasNode.advertise(NODE_GAS).setName("Gas")
.setDatatype("float") .setDatatype("float")
.setUnit(" KOhms"); .setUnit(" KOhms");
humidityNode.advertise(NODE_HUMIDITY).setName("Humidity") humidityNode.advertise(NODE_HUMIDITY).setName("Humidity")
.setDatatype("float") .setDatatype("float")
.setUnit("%"); .setUnit("%");
#endif
ledStripNode.advertise(NODE_AMBIENT).setName("All Leds") ledStripNode.advertise(NODE_AMBIENT).setName("All Leds")
.setDatatype("color").setFormat("rgb") .setDatatype("color").setFormat("rgb")
.settable(ledHandler); .settable(ledHandler);
buttonNode.advertise(NODE_BUTTON).setName("Button pressed")
.setDatatype("integer");
strip.begin(); strip.begin();
/* activate I2C for BOSCH sensor */
Wire.begin(SENSOR_I2C_SDI, SENSOR_I2C_SCK);
mConfigured = Homie.isConfigured(); mConfigured = Homie.isConfigured();
digitalWrite(WITTY_RGB_G, HIGH); digitalWrite(WITTY_RGB_G, HIGH);
if (mConfigured) if (mConfigured)
{ {
if (i2cEnable.get()) { if (i2cEnable.get()) {
#ifdef BME680 strip.fill(strip.Color(0,128,0));
printf("Wait 1 second...\r\n");
delay(1000);
#endif
/* activate I2C for BOSCH sensor */
Wire.begin(SENSOR_I2C_SDI, SENSOR_I2C_SCK);
printf("Wait 50 milliseconds...\r\n");
delay(50);
/* Extracted from library's example */
mFailedI2Cinitialization = !bmx.begin();
if (!mFailedI2Cinitialization) {
strip.fill(strip.Color(0,PERCENT2FACTOR(64, rgbDim),0));
strip.show();
#ifdef BME680
bmx.setTemperatureOversampling(BME680_OS_8X);
bmx.setHumidityOversampling(BME680_OS_2X);
bmx.setPressureOversampling(BME680_OS_4X);
bmx.setIIRFilterSize(BME680_FILTER_SIZE_3);
bmx.setGasHeater(320, 150); // 320*C for 150 ms
#endif
#ifdef BMP280
/* Default settings from datasheet. */
bmx.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
#endif
printf("Sensor found on I2C bus\r\n");
} else {
printf("Failed to initialize I2C bus\r\n");
}
}
/* Nothing when sleeping */
if (deepsleep.get() <= 0) {
strip.fill(strip.Color(0,0,0));
for (int i=0;i < (PIXEL_COUNT / 2); i++) {
strip.setPixelColor(0, strip.Color(0,0,128 * rgbDim.get()));
}
strip.show(); strip.show();
/* Extracted from library's example */
mFailedI2Cinitialization = !bme.begin();
if (!mFailedI2Cinitialization) {
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
} else {
printf("Faild to initialize I2C bus\r\n");
}
} }
strip.fill(strip.Color(0,0,0));
for (int i=0;i < (PIXEL_COUNT / 2); i++) {
strip.setPixelColor(0, strip.Color(0,0,128));
}
strip.show();
digitalWrite(WITTY_RGB_B, HIGH);
} else { } else {
digitalWrite(WITTY_RGB_R, HIGH);
strip.fill(strip.Color(128,0,0)); strip.fill(strip.Color(128,0,0));
for (int i=0;i < (PIXEL_COUNT / 2); i++) { for (int i=0;i < (PIXEL_COUNT / 2); i++) {
strip.setPixelColor(0, strip.Color(0,0,128)); strip.setPixelColor(0, strip.Color(0,0,128));
@ -514,36 +381,19 @@ void loop()
Homie.loop(); Homie.loop();
/* use the pin, receiving the soft serial additionally as button */ /* use the pin, receiving the soft serial additionally as button */
if (digitalRead(GPIO_BUTTON) == LOW) { if (digitalRead(GPIO_BUTTON) == LOW) {
if ((millis() - mLastButtonAction) > BUTTON_CHECK_INTERVALL) { mButtonPressed++;
mButtonPressed++;
}
if (mButtonPressed > BUTTON_MIN_ACTION_CYCLE) {
digitalWrite(WITTY_RGB_R, HIGH);
digitalWrite(WITTY_RGB_B, LOW);
strip.fill(strip.Color(0,0,0));
strip.setPixelColor(0, strip.Color((mButtonPressed % 100),0,0));
strip.setPixelColor(1, strip.Color((mButtonPressed / 100),0,0));
strip.setPixelColor(2, strip.Color((mButtonPressed / 100),0,0));
strip.show();
}
} else { } else {
mButtonPressed=0U; mButtonPressed=0U;
digitalWrite(WITTY_RGB_R, LOW);
} }
if (mButtonPressed > BUTTON_MAX_CYCLE) { if (mButtonPressed > 10000U) {
mButtonPressed=0U;
if (SPIFFS.exists("/homie/config.json")) { if (SPIFFS.exists("/homie/config.json")) {
strip.fill(strip.Color(0,PERCENT2FACTOR(127, rgbDim),0));
strip.show();
printf("Resetting config\r\n"); printf("Resetting config\r\n");
SPIFFS.remove("/homie/config.json"); SPIFFS.remove("/homie/config.json");
SPIFFS.end(); SPIFFS.end();
delay(50);
Homie.reboot();
} else { } else {
printf("No config present\r\n"); printf("No config present\r\n");
strip.fill(strip.Color(0,0,128));
strip.show();
} }
} }
} }
@ -564,5 +414,4 @@ void log(int level, String message, int statusCode)
Homie.getMqttClient().publish(logTopic, 2, false, buffer.c_str()); Homie.getMqttClient().publish(logTopic, 2, false, buffer.c_str());
delete logTopic; delete logTopic;
} }
Homie.getLogger() << (level) << "@" << (statusCode) << " " << (message) << endl;
} }