diff --git a/check_custom_build_flags_nrf52840.sh b/check_custom_build_flags_nrf52840.sh index 5b8cce5..c8fe8d2 100755 --- a/check_custom_build_flags_nrf52840.sh +++ b/check_custom_build_flags_nrf52840.sh @@ -7,6 +7,7 @@ export FLAGS="$FLAGS -DMODBUS_DISABLE" export FLAGS="$FLAGS -std=gnu++11" export FLAGS="$FLAGS -DWIFI_MANAGER_DISABLE" export FLAGS="$FLAGS -DCOUNTER_DISABLE" +export FLAGS="$FLAGS -DCSSHDC_DISABLE" CUSTOM_BUILD_FLAGS_FILE=custom-build-flags/build_flags_nrf52840.sh if [ -f $CUSTOM_BUILD_FLAGS_FILE ]; then diff --git a/check_custom_build_flags_stm32.sh b/check_custom_build_flags_stm32.sh index 63ac0bc..a9b00fe 100755 --- a/check_custom_build_flags_stm32.sh +++ b/check_custom_build_flags_stm32.sh @@ -7,6 +7,7 @@ export FLAGS="$FLAGS -DOWIRE_DISABLE" export FLAGS="$FLAGS -DDHT_DISABLE" export FLAGS="$FLAGS -DCOUNTER_DISABLE" export FLAGS="$FLAGS -DNO_HOMIE" +export FLAGS="$FLAGS -DCSSHDC_DISABLE" if [ -f $CUSTOM_BUILD_FLAGS_FILE ]; then source $CUSTOM_BUILD_FLAGS_FILE fi diff --git a/lighthub/abstractin.h b/lighthub/abstractin.h new file mode 100644 index 0000000..192173c --- /dev/null +++ b/lighthub/abstractin.h @@ -0,0 +1,11 @@ +class Input; +class abstractIn { +public: + abstractIn(Input * _in){in=_in;}; + virtual int Setup(int addr) = 0; + virtual int Poll() = 0; + +protected: + Input * in; +friend Input; +}; diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index 4501cd8..99bf4f9 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -108,27 +108,81 @@ void Input::Parse() } } -int Input::poll() { - if (!isValid()) return -1; - if (0) ; +void Input::setup() +{ +if (!isValid()) return; +#ifndef CSSHDC_DISABLE + in_ccs811 ccs811(this); + in_hdc1080 hdc1080(this); + + if (inType == IN_CCS811) + ccs811.Setup(pin); + else if (inType == IN_HDC1080) + hdc1080.Setup(pin); +// TODO rest types setup +#endif + +} + +int Input::poll(short cause) { + +if (!isValid()) return -1; +#ifndef CSSHDC_DISABLE + in_ccs811 ccs811(this); + in_hdc1080 hdc1080(this); +#endif + +switch (cause) { + case CHECK_INPUT: //Fast polling + switch (inType) + { + case IN_PUSH_ON: + case IN_PUSH_ON | IN_ACTIVE_HIGH: + case IN_PUSH_TOGGLE : + case IN_PUSH_TOGGLE | IN_ACTIVE_HIGH: + contactPoll(); + break; + case IN_ANALOG: + case IN_ANALOG | IN_ACTIVE_HIGH: + analogPoll(); + break; + + // No fast polling + case IN_DHT22: + case IN_COUNTER: + case IN_UPTIME: + case IN_CCS811: + case IN_HDC1080: + break; + } + break; + case CHECK_SENSOR: //Slow polling + switch (inType) + { + #ifndef CSSHDC_DISABLE + case IN_CCS811: + ccs811.Poll(); + break; + case IN_HDC1080: + hdc1080.Poll(); + break; + #endif #ifndef DHT_DISABLE - else if (inType & IN_DHT22) - dht22Poll(); + case IN_DHT22: + dht22Poll(); + break; #endif #ifndef COUNTER_DISABLE - else if (inType & IN_COUNTER) - counterPoll(); - else if (inType & IN_UPTIME) - uptimePoll(); + case IN_COUNTER: + counterPoll(); + break; + case IN_UPTIME: + uptimePoll(); + break; #endif - else if (inType & IN_ANALOG) - analogPoll(); - else - contactPoll(); - return 0; - - // contactPoll(); + } + } } #ifndef COUNTER_DISABLE diff --git a/lighthub/inputs.h b/lighthub/inputs.h index 9815fe0..2722ffa 100644 --- a/lighthub/inputs.h +++ b/lighthub/inputs.h @@ -17,8 +17,9 @@ GIT: https://github.com/anklimov/lighthub e-mail anklimov@gmail.com */ - +#pragma once #include +#include "modules/in_ccs811_hdc1080.h" #define IN_ACTIVE_HIGH 2 // High level = PUSHED/ CLOSED/ ON othervise :Low Level. Use INPUT mode instead of INPUT_PULLUP for digital pin #define IN_ANALOG 64 // Analog input @@ -26,14 +27,22 @@ e-mail anklimov@gmail.com #define IN_PUSH_ON 0 // PUSH - ON, Release - OFF (ovverrided by pcmd/rcmd) - DEFAULT #define IN_PUSH_TOGGLE 1 // Used for push buttons. Every physicall push toggle logical switch on/off. Toggle on leading edge + #define IN_DHT22 4 +#define IN_CCS811 5 +#define IN_HDC1080 6 + #define IN_COUNTER 8 #define IN_UPTIME 16 + #define SAME_STATE_ATTEMPTS 3 #define ANALOG_STATE_ATTEMPTS 6 #define ANALOG_NOIZE 1 +#define CHECK_INPUT 1 +#define CHECK_SENSOR 2 + // in syntaxis // "pin": { "T":"N", "emit":"out_emit", item:"out_item", "scmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd":"repeat_command" } @@ -69,6 +78,7 @@ extern aJsonObject *inputs; typedef union { long int aslong; + uint32_t timestamp; struct { int8_t logicState; int8_t bounce; @@ -95,7 +105,8 @@ public: void onContactChanged(int newValue); void onAnalogChanged(int newValue); - int poll(); + int poll(short cause); + void setup(); static void inline onCounterChanged(int i); static void onCounterChanged0(); diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 8052de7..8b195ea 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -135,6 +135,7 @@ uint32_t nextPollingCheck = 0; uint32_t nextInputCheck = 0; uint32_t nextLanCheckTime = 0; uint32_t nextThermostatCheck = 0; +uint32_t nextSensorCheck =0; aJsonObject *pollingItem = NULL; @@ -806,7 +807,6 @@ void cmdFunctionReboot(int arg_cnt, char **args) { void applyConfig() { if (!root) return; - #ifdef _dmxin int itemsCount; dmxArr = aJson.getObjectItem(root, "dmxin"); @@ -878,6 +878,8 @@ void applyConfig() { } inputs = aJson.getObjectItem(root, "in"); mqttArr = aJson.getObjectItem(root, "mqtt"); + + inputSetup(); #ifdef SYSLOG_ENABLE udpSyslogArr = aJson.getObjectItem(root, "syslog"); #endif @@ -1571,17 +1573,45 @@ void modbusIdle(void) { void inputLoop(void) { if (!inputs) return; + + if (millis() > nextInputCheck) { aJsonObject *input = inputs->child; while (input) { if ((input->type == aJson_Object)) { Input in(input); - in.poll(); + in.poll(CHECK_INPUT); } input = input->next; } nextInputCheck = millis() + INTERVAL_CHECK_INPUT; } + + if (millis() > nextSensorCheck) { + aJsonObject *input = inputs->child; + while (input) { + if ((input->type == aJson_Object)) { + Input in(input); + in.poll(CHECK_SENSOR); + } + input = input->next; + } + nextSensorCheck = millis() + INTERVAL_CHECK_SENSOR; + } + +} + +void inputSetup(void) { + if (!inputs) return; + + aJsonObject *input = inputs->child; + while (input) { + if ((input->type == aJson_Object)) { + Input in(input); + in.setup(); + } + input = input->next; + } } #ifndef MODBUS_DISABLE diff --git a/lighthub/main.h b/lighthub/main.h index 5e8968f..351545b 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -232,6 +232,8 @@ void modbusIdle(void); void inputLoop(void); +void inputSetup(void); + void pollingLoop(void); void thermoLoop(void); diff --git a/lighthub/modules/in_ccs811_hdc1080.cpp b/lighthub/modules/in_ccs811_hdc1080.cpp new file mode 100644 index 0000000..7bd3b63 --- /dev/null +++ b/lighthub/modules/in_ccs811_hdc1080.cpp @@ -0,0 +1,183 @@ +#include "modules/in_ccs811_hdc1080.h" +#ifndef CSSHDC_DISABLE + +CCS811 ccs811(CCS811_ADDR); +ClosedCube_HDC1080 hdc1080; +uint16_t ccs811Baseline; + +int in_ccs811::Setup(int addr) +{ +#ifdef WAK_PIN + pinMode(WAK_PIN,OUTPUT); + digitalWrite(WAK_PIN,LOW); +#endif + +Serial.println("CCS811 Init"); + +Wire.begin(); //Inialize I2C Harware + + //It is recommended to check return status on .begin(), but it is not + //required. + CCS811Core::status returnCode = ccs811.begin(); + if (returnCode != CCS811Core::SENSOR_SUCCESS) + { + Serial.println("CCS811 Init error"); + printDriverError(returnCode); + return 0; + } +ccs811.setBaseline(62000); +return 1; +} + +int in_hdc1080::Setup(int addr) +{ +Serial.println("HDC1080 Init "); +Wire.begin(); //Inialize I2C Harware +// Default settings: +// - Heater off +// - 14 bit Temperature and Humidity Measurement Resolutions +hdc1080.begin(0x40); +Serial.print("Manufacturer ID=0x"); +Serial.println(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments +Serial.print("Device ID=0x"); +Serial.println(hdc1080.readDeviceId(), HEX); // 0x1050 ID of the device +printSerialNumber(); +return 1; +} + +void i2cReset(){ +Wire.endTransmission(true); +#if defined (ARDUINO_ARCH_ESP8266) +SCL_LOW(); +delay(300); +SCL_HIGH(); +#endif +} + +int in_hdc1080::Poll() +{ + float h,t; + int reg; + +// #ifdef WAK_PIN +// digitalWrite(WAK_PIN,LOW); +// #endif + + +Serial.print("T="); +Serial.print(t=hdc1080.readTemperature()); +Serial.print("C, RH="); +Serial.print(h=hdc1080.readHumidity()); +Serial.print("% Status="); +Serial.println(reg=hdc1080.readRegister().rawData,HEX); +/////// TODO ccs811.setEnvironmentalData(h,t); + +if (reg==0xff) //ESP I2C glitch + { + Serial.println("I2C Reset"); + i2cReset(); + } + +delay(100); +//#ifdef WAK_PIN +// digitalWrite(WAK_PIN,HIGH); +//#endif +return 1; +} + +int in_ccs811::Poll() +{ + //#ifdef WAK_PIN + // digitalWrite(WAK_PIN,LOW); + //#endif +//Check to see if data is ready with .dataAvailable() + if (ccs811.dataAvailable()) + { + //If so, have the sensor read and calculate the results. + //Get them later + CCS811Core::status returnCode = ccs811.readAlgorithmResults(); + printDriverError(returnCode); + + Serial.print(" CO2["); + //Returns calculated CO2 reading + Serial.print(ccs811.getCO2()); + Serial.print("] tVOC["); + //Returns calculated TVOC reading + + Serial.print(ccs811.getTVOC()); + Serial.print("] baseline["); + Serial.print(ccs811Baseline = ccs811.getBaseline()); + Serial.print("] millis["); + //Simply the time since program start + Serial.print(millis()); + Serial.print("]"); + Serial.println(); + printSensorError(); + + //#ifdef WAK_PIN + // digitalWrite(WAK_PIN,HIGH); //Relax some time + //#endif + } + return 1; +} + +void in_hdc1080::printSerialNumber() { +Serial.print("Device Serial Number="); +HDC1080_SerialNumber sernum = hdc1080.readSerialNumber(); +char format[12]; +sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast); +Serial.println(format); +} + +//printDriverError decodes the CCS811Core::status type and prints the +//type of error to the serial terminal. +// +//Save the return value of any function of type CCS811Core::status, then pass +//to this function to see what the output was. +void in_ccs811::printDriverError( CCS811Core::status errorCode ) +{ + switch ( errorCode ) + { + case CCS811Core::SENSOR_SUCCESS: + Serial.print("SUCCESS"); + break; + case CCS811Core::SENSOR_ID_ERROR: + Serial.print("ID_ERROR"); + break; + case CCS811Core::SENSOR_I2C_ERROR: + Serial.print("I2C_ERROR"); + break; + case CCS811Core::SENSOR_INTERNAL_ERROR: + Serial.print("INTERNAL_ERROR"); + break; + case CCS811Core::SENSOR_GENERIC_ERROR: + Serial.print("GENERIC_ERROR"); + break; + default: + Serial.print("Unspecified error."); + } +} + +//printSensorError gets, clears, then prints the errors +//saved within the error register. +void in_ccs811::printSensorError() +{ + uint8_t error = ccs811.getErrorRegister(); + + if ( error == 0xFF ) //comm error + { + Serial.println("Failed to get ERROR_ID register."); + } + else + { + //Serial.print(""); + if (error & 1 << 5) Serial.print("Error: HeaterSupply"); + if (error & 1 << 4) Serial.print("Error: HeaterFault"); + if (error & 1 << 3) Serial.print("Error: MaxResistance"); + if (error & 1 << 2) Serial.print("Error: MeasModeInvalid"); + if (error & 1 << 1) Serial.print("Error: ReadRegInvalid"); + if (error & 1 << 0) Serial.print("Error: MsgInvalid"); + Serial.println(); + } +} +#endif diff --git a/lighthub/modules/in_ccs811_hdc1080.h b/lighthub/modules/in_ccs811_hdc1080.h new file mode 100644 index 0000000..676d81c --- /dev/null +++ b/lighthub/modules/in_ccs811_hdc1080.h @@ -0,0 +1,45 @@ + +#pragma once +#ifndef CSSHDC_DISABLE +#include +#include +#include +#include "ClosedCube_HDC1080.h" +#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811 + +//#define CCS811_ADDR 0x5B //Default I2C Address +#define CCS811_ADDR 0x5A //Alternate I2C Address + +#if defined (ARDUINO_ARCH_ESP8266) +#define twi_scl D1 +#define WAK_PIN D4 + +#define SCL_LOW() (GPES = (1 << twi_scl)) +#define SCL_HIGH() (GPEC = (1 << twi_scl)) +#endif + +class Input; +class in_ccs811 : public abstractIn { +public: + //CCS811 ccs811(CCS811_ADDR); + //uint16_t ccs811Baseline; + in_ccs811(Input * _in):abstractIn(_in){}; + int Setup(int addr) override; + int Poll() override; + +protected: + void printDriverError( CCS811Core::status errorCode ); + void printSensorError(); +}; + +class in_hdc1080 : public abstractIn { +public: + //ClosedCube_HDC1080 hdc1080; + in_hdc1080(Input * _in):abstractIn(_in){}; + int Setup(int addr) override; + int Poll() override; + +protected: + void printSerialNumber(); +}; +#endif diff --git a/lighthub/options.h b/lighthub/options.h index 8a09245..1f19bed 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -33,6 +33,11 @@ #ifndef INTERVAL_CHECK_INPUT #define INTERVAL_CHECK_INPUT 50 #endif + +#ifndef INTERVAL_CHECK_SENSOR +#define INTERVAL_CHECK_SENSOR 5000 +#endif + #define INTERVAL_CHECK_MODBUS 2000 #define INTERVAL_POLLING 100 #define THERMOSTAT_CHECK_PERIOD 5000 diff --git a/platformio.ini b/platformio.ini index 0710a83..6023f2d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; http://docs.platformio.org/page/projectconf.html [platformio] src_dir = lighthub -;env_default = esp32 +;env_default = esp8266 ;monitor_speed = 115200 ; megaatmega2560 ; megaatmega2560-net @@ -55,6 +55,8 @@ lib_ignore = WebServer UIPEthernet ;Adafruit_Sensor + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library lib_deps = https://github.com/anklimov/Arduino-Temperature-Control-Library.git https://github.com/anklimov/DS2482_OneWire @@ -73,6 +75,7 @@ lib_deps = ; https://github.com/livello/PrintEx#is-select-redecl + [env:esp32] platform = espressif32 framework = arduino @@ -116,7 +119,8 @@ lib_deps = https://github.com/anklimov/DS2482_OneWire https://github.com/anklimov/ESP-Dmx FastLED - + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:due] platform = atmelsam framework = arduino @@ -155,7 +159,8 @@ lib_deps = DHT sensor library https://github.com/arcao/Syslog.git Streaming - + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:megaatmega2560] platform = atmelavr @@ -192,6 +197,8 @@ lib_deps = DHT sensor library https://github.com/arcao/Syslog.git Streaming + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:esp8266] platform = espressif8266 @@ -232,6 +239,8 @@ lib_deps = https://github.com/arcao/Syslog.git Streaming ESP_EEPROM + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:megaatmega2560-net] platform = atmelavr @@ -269,6 +278,8 @@ lib_deps = DHT sensor library https://github.com/arcao/Syslog.git Streaming + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:due-5500] platform = atmelsam @@ -310,6 +321,8 @@ lib_deps = https://github.com/arcao/Syslog.git Streaming https://github.com/livello/PrintEx#is-select-redecl + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:controllino] platform = atmelavr @@ -347,6 +360,8 @@ lib_deps = DHT sensor library Streaming https://github.com/livello/PrintEx#is-select-redecl + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library [env:stm32] platform = ststm32 @@ -382,6 +397,8 @@ lib_ignore = Syslog Wire EEPROM + ClosedCube HDC1080 + SparkFun CCS811 Arduino Library lib_deps = https://github.com/anklimov/aJson https://github.com/anklimov/CmdArduino