diff --git a/NodeManagerTemplate/NodeManager.cpp b/NodeManagerTemplate/NodeManager.cpp index b7708f09dea5c465b2cdab94cb60d5d819043599..05a1df296a779088a60a8e03de68fd5eea9161d5 100644 --- a/NodeManagerTemplate/NodeManager.cpp +++ b/NodeManagerTemplate/NodeManager.cpp @@ -21,10 +21,10 @@ const char* WAKEUP = "WAKEUP"; // set the vcc and ground pin the sensor is connected to void PowerManager::setPowerPins(int ground_pin, int vcc_pin, long wait = 10) { #if DEBUG == 1 - Serial.print("POWER V="); - Serial.print(vcc_pin); - Serial.print(" G="); - Serial.println(ground_pin); + Serial.print("POWER G="); + Serial.print(ground_pin); + Serial.print(" V="); + Serial.println(vcc_pin); #endif // configure the vcc pin as output and initialize to low (power off) _vcc_pin = vcc_pin; @@ -619,7 +619,7 @@ void SensorDHT::onReceive(const MyMessage & message) { */ #if MODULE_SHT21 == 1 // contructor -SensorSHT21::SensorSHT21(int child_id, int sensor_type): Sensor(child_id, -1) { +SensorSHT21::SensorSHT21(int child_id, int sensor_type): Sensor(child_id,A2) { // store the sensor type (0: temperature, 1: humidity) _sensor_type = sensor_type; if (_sensor_type == 0) { @@ -681,6 +681,15 @@ void SensorSHT21::onReceive(const MyMessage & message) { } #endif +/* + * SensorHTU21D + */ + #if MODULE_SHT21 == 1 +// constructor +SensorHTU21D::SensorHTU21D(int child_id, int pin): SensorSHT21(child_id, pin) { +} +#endif + /* * SensorSwitch */ @@ -795,8 +804,81 @@ void SensorDs18b20::onLoop() { void SensorDs18b20::onReceive(const MyMessage & message) { onLoop(); } +#endif + +/* + SensorBH1750 +*/ +#if MODULE_BH1750 == 1 +// contructor +SensorBH1750::SensorBH1750(int child_id): Sensor(child_id,A4) { + setPresentation(S_LIGHT_LEVEL); + setType(V_LEVEL); + _lightSensor = new BH1750(); +} + +// what do to during setup +void SensorBH1750::onBefore() { + _lightSensor->begin(); +} + +// what do to during loop +void SensorBH1750::onLoop() { + // request the light level + _value_int = _lightSensor->readLightLevel(); + #if DEBUG == 1 + Serial.print("BH1 I="); + Serial.print(_child_id); + Serial.print(" L="); + Serial.println(_value_int); + #endif +} + +// what do to as the main task when receiving a message +void SensorBH1750::onReceive(const MyMessage & message) { + onLoop(); +} +#endif + +/* + SensorMLX90614 +*/ +#if MODULE_MLX90614 == 1 +// contructor +SensorMLX90614::SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_type): Sensor(child_id,A4) { + // store the sensor type (0: ambient, 1: object) + _sensor_type = sensor_type; + _mlx = mlx; + // set presentation and type + setPresentation(S_TEMP); + setType(V_TEMP); + setValueType(TYPE_FLOAT); +} +// what do to during setup +void SensorMLX90614::onBefore() { + // initialize the library + _mlx->begin(); +} + +// what do to during loop +void SensorMLX90614::onLoop() { + float temperature = _sensor_type == 0 ? _mlx->readAmbientTempC() : _mlx->readObjectTempC(); + // convert it + if (! getControllerConfig().isMetric) temperature = temperature * 1.8 + 32; + #if DEBUG == 1 + Serial.print("MLX I="); + Serial.print(_child_id); + Serial.print(" T="); + Serial.println(temperature); + #endif + if (! isnan(temperature)) _value_float = temperature; +} +// what do to as the main task when receiving a message +void SensorMLX90614::onReceive(const MyMessage & message) { + onLoop(); +} #endif /******************************************* @@ -915,6 +997,11 @@ int NodeManager::registerSensor(int sensor_type, int pin = -1, int child_id = -1 child_id = _getAvailableChildId(); registerSensor(new SensorSHT21(child_id,1)); } + else if (sensor_type == SENSOR_HTU21D) { + registerSensor(new SensorHTU21D(child_id,0)); + child_id = _getAvailableChildId(); + registerSensor(new SensorHTU21D(child_id,1)); + } #endif #if MODULE_SWITCH == 1 else if (sensor_type == SENSOR_SWITCH || sensor_type == SENSOR_DOOR || sensor_type == SENSOR_MOTION) { @@ -944,6 +1031,22 @@ int NodeManager::registerSensor(int sensor_type, int pin = -1, int child_id = -1 } } #endif + #if MODULE_BH1750 == 1 + else if (sensor_type == SENSOR_BH1750) { + return registerSensor(new SensorBH1750(child_id)); + } + #endif + #if MODULE_MLX90614 == 1 + else if (sensor_type == SENSOR_MLX90614) { + Serial.println("1"); + Adafruit_MLX90614* mlx = new Adafruit_MLX90614(); + Serial.println("2"); + registerSensor(new SensorMLX90614(child_id,mlx,0)); + Serial.println("3"); + child_id = _getAvailableChildId(); + registerSensor(new SensorMLX90614(child_id,mlx,1)); + } + #endif else { #if DEBUG == 1 Serial.print("INVALID "); @@ -965,6 +1068,8 @@ int NodeManager::registerSensor(Sensor* sensor) { Serial.print(" T="); Serial.println(sensor->getType()); #endif + // set auto power pin + sensor->setAutoPowerPins(_auto_power_pins); // add the sensor to the array of registered sensors _sensors[sensor->getChildId()] = sensor; // return the child_id @@ -1114,7 +1219,7 @@ void NodeManager::loop() { // dispacth inbound messages void NodeManager::receive(const MyMessage &message) { #if DEBUG == 1 - Serial.print("RECV F="); + Serial.print("RECV S="); Serial.print(message.sender); Serial.print(" I="); Serial.print(message.sensor); @@ -1133,13 +1238,13 @@ void NodeManager::receive(const MyMessage &message) { else if (message.getCommand() == C_REQ && _sensors[message.sensor] != 0) { #if POWER_MANAGER == 1 // turn on the pin powering all the sensors - powerOn(); + if (_auto_power_pins) powerOn(); #endif // call the sensor's receive() _sensors[message.sensor]->receive(message); #if POWER_MANAGER == 1 // turn off the pin powering all the sensors - powerOff(); + if (_auto_power_pins) powerOff(); #endif } } diff --git a/NodeManagerTemplate/NodeManager.h b/NodeManagerTemplate/NodeManager.h index 7fc3edaaa99d67b20a4dbf2a5b3deb58c6240aee..bcdb2847807eeae96d5c79ccaa0b5093f1e4da5a 100644 --- a/NodeManagerTemplate/NodeManager.h +++ b/NodeManagerTemplate/NodeManager.h @@ -41,7 +41,7 @@ #define EEPROM_SLEEP_UNIT 4 // define NodeManager version -#define VERSION 1.1 +#define VERSION 1.2 /************************************ * Include user defined configuration settings @@ -109,7 +109,7 @@ #ifndef MODULE_DIGITAL_OUTPUT #define MODULE_DIGITAL_OUTPUT 0 #endif -// Enable this module to use one of the following sensors: SENSOR_SHT21 +// Enable this module to use one of the following sensors: SENSOR_SHT21, SENSOR_HTU21D #ifndef MODULE_SHT21 #define MODULE_SHT21 0 #endif @@ -125,7 +125,14 @@ #ifndef MODULE_DS18B20 #define MODULE_DS18B20 0 #endif - +// Enable this module to use one of the following sensors: SENSOR_BH1750 +#ifndef MODULE_BH1750 + #define MODULE_BH1750 0 +#endif +// Enable this module to use one of the following sensors: SENSOR_MLX90614 +#ifndef MODULE_MLX90614 + #define MODULE_MLX90614 0 +#endif /*********************************** Sensors types @@ -158,6 +165,7 @@ #if MODULE_SHT21 == 1 // SHT21 sensor, return temperature/humidity based on the attached SHT21 sensor #define SENSOR_SHT21 10 + #define SENSOR_HTU21D 15 #endif #if MODULE_SWITCH == 1 // Generic switch, wake up the board when a pin changes status @@ -171,7 +179,16 @@ // DS18B20 sensor, return the temperature based on the attached sensor #define SENSOR_DS18B20 14 #endif +#if MODULE_BH1750 == 1 + // BH1750 sensor, return light in lux + #define SENSOR_BH1750 16 +#endif +#if MODULE_MLX90614 == 1 + // MLX90614 sensor, contactless temperature sensor + #define SENSOR_MLX90614 17 +#endif +// last Id: 17 /*********************************** Libraries */ @@ -188,15 +205,18 @@ #include <Wire.h> #include <Sodaq_SHT2x.h> #endif -#if MODULE_SHT21 == 1 - #include <Wire.h> - #include <Sodaq_SHT2x.h> -#endif #if MODULE_DS18B20 == 1 #include <OneWire.h> #include <DallasTemperature.h> #endif - +#if MODULE_BH1750 == 1 + #include <BH1750.h> + #include <Wire.h> +#endif +#if MODULE_MLX90614 == 1 + #include <Wire.h> + #include <Adafruit_MLX90614.h> +#endif /************************************** Classes @@ -438,7 +458,7 @@ class SensorDHT: public Sensor { #endif /* - SensorSHT21 + SensorSHT21: temperature and humidity sensor */ #if MODULE_SHT21 == 1 class SensorSHT21: public Sensor { @@ -452,6 +472,15 @@ class SensorSHT21: public Sensor { float _offset = 0; int _sensor_type = 0; }; + +/* + SensorHTU21D: temperature and humidity sensor +*/ + +class SensorHTU21D: public SensorSHT21 { + public: + SensorHTU21D(int child_id, int pin); +}; #endif /* @@ -511,6 +540,38 @@ class SensorDs18b20: public Sensor { }; #endif +/* + SensorBH1750 +*/ +#if MODULE_BH1750 == 1 +class SensorBH1750: public Sensor { + public: + SensorBH1750(int child_id); + // define what to do at each stage of the sketch + void onBefore(); + void onLoop(); + void onReceive(const MyMessage & message); + protected: + BH1750* _lightSensor; +}; +#endif + +/* + SensorMLX90614 +*/ +#if MODULE_MLX90614 == 1 +class SensorMLX90614: public Sensor { + public: + SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_type); + // define what to do at each stage of the sketch + void onBefore(); + void onLoop(); + void onReceive(const MyMessage & message); + protected: + Adafruit_MLX90614* _mlx; + int _sensor_type; +}; +#endif /*************************************** NodeManager: manages all the aspects of the node diff --git a/NodeManagerTemplate/NodeManagerTemplate.ino b/NodeManagerTemplate/NodeManagerTemplate.ino index 90ea075c715b82f150168548cab84bec13639c9d..6bdc8e7246fdae68a7b859c3f4a7a341ff04dac1 100644 --- a/NodeManagerTemplate/NodeManagerTemplate.ino +++ b/NodeManagerTemplate/NodeManagerTemplate.ino @@ -28,12 +28,12 @@ void before() { Serial.begin(9600); /* * Register below your sensors - */ - + */ + /* * Register above your sensors - */ + */ nodeManager.before(); } diff --git a/NodeManagerTemplate/README.md b/NodeManagerTemplate/README.md index ae3b27f2e79b7357310d7c04537dd4c5717d366c..ccf893f6672e9625cd893d9318482b28208d8258 100644 --- a/NodeManagerTemplate/README.md +++ b/NodeManagerTemplate/README.md @@ -1,4 +1,4 @@ -Welcome to NodeManager (v1.1) +[NodeManager] # Introduction @@ -40,7 +40,21 @@ Please note NodeManager cannot be used as an arduino library since requires acce NodeManager configuration includes compile-time configuration directives (which can be set in config.h), runtime global and per-sensor configuration settings (which can be set in your sketch) and settings that can be customized remotely (via a special child id). ## Setup MySensors -Since NodeManager has to communicate with the MySensors gateway on your behalf, it has to know how to do it. Place on top of the `config.h` file all the MySensors typical directives you are used to set on top of your sketch so both your sketch AND NodeManager will be able to share the same configuration. +Since NodeManager has to communicate with the MySensors gateway on your behalf, it has to know how to do it. Place on top of the `config.h` file all the MySensors typical directives you are used to set on top of your sketch so both your sketch AND NodeManager will be able to share the same configuration. For example: +~~~c +//#define MY_DEBUG +#define MY_NODE_ID 100 + +#define MY_RADIO_NRF24 +//#define MY_RF24_ENABLE_ENCRYPTION +//#define MY_RF24_CHANNEL 76 + +//#define MY_RADIO_RFM69 +//#define MY_RFM69_FREQUENCY RF69_868MHZ +//#define MY_IS_RFM69HW +//#define MY_RFM69_ENABLE_ENCRYPTION +//#define MY_RFM69_NETWORKID 100 +~~~ ## Enable/Disable NodeManager's modules @@ -80,8 +94,24 @@ Those NodeManager's directives in the `config.h` file control which module/libra #define MODULE_SWITCH 0 // Enable this module to use one of the following sensors: SENSOR_DS18B20 #define MODULE_DS18B20 0 +// Enable this module to use one of the following sensors: SENSOR_BH1750 +#define MODULE_BH1750 0 +// Enable this module to use one of the following sensors: SENSOR_MLX90614 +#define MODULE_MLX90614 0 ~~~ +## Installing the dependencies + +Some of the modules above rely on third party libraries. Those libraries are not included within NodeManager and have to be installed from the Arduino IDE Library Manager (Sketch -> Include Library -> Manager Libraries). You need to install the library ONLY if the module is enabled: + +Module | Required Library + ------------- | ------------- +MODULE_SHT21 | https://github.com/SodaqMoja/Sodaq_SHT2x +MODULE_DHT | https://github.com/adafruit/DHT-sensor-library +MODULE_DS18B20 | https://github.com/milesburton/Arduino-Temperature-Control-Library +MODULE_BH1750 | https://github.com/claws/BH1750 +MODULE_MLX90614 | https://github.com/adafruit/Adafruit-MLX90614-Library + ## Configure NodeManager Node Manager comes with a reasonable default configuration. If you want/need to change its settings, this can be done in your sketch, inside the `before()` function and just before registering your sensors. The following methods are exposed for your convenience: @@ -157,6 +187,9 @@ SENSOR_SWITCH | Generic switch, wake up the board when a pin changes status SENSOR_DOOR | Door sensor, wake up the board and report when an attached magnetic sensor has been opened/closed SENSOR_MOTION | Motion sensor, wake up the board and report when an attached PIR has triggered SENSOR_DS18B20 | DS18B20 sensor, return the temperature based on the attached sensor +SENSOR_HTU21D | HTU21D sensor, return temperature/humidity based on the attached HTU21D sensor +SENSOR_BH1750 | BH1750 sensor, return light level in lux +SENSOR_MLX90614 | MLX90614 contactless temperature sensor, return ambient and object temperature To register a sensor simply call the NodeManager instance with the sensory type and the pin the sensor is conncted to. For example: ~~~c @@ -377,75 +410,61 @@ A NodeManager object must be created and called from within your sketch during ` * Invoke `Sensor::loop()` which will execute the sensor main taks and eventually call `Sensor::onReceive()` # Examples +All the examples below takes place within the before() function in the main sketch, just below the "Register below your sensors" comment. + Enable reboot pin, connect pin 4 to RST to enable rebooting the board with the REBOOT message: ~~~c -void before() { nodeManager.setRebootPin(4); - nodeManager.before(); -} ~~~ Set battery minimum and maxium voltage. This will be used to calculate the level percentage: ~~~c -void before() { nodeManager.setBatteryMin(1.8); nodeManager.setBatteryMin(3.2); - nodeManager.before(); -} ~~~ Instruct the board to sleep for 10 minutes at each cycle: ~~~c -void before() { nodeManager.setSleep(SLEEP,10,MINUTES); - nodeManager.before(); -} ~~~ Configure a wake up pin. When pin 3 is connected to ground, the board will stop sleeping: ~~~c -void before() { nodeManager.setSleepInterruptPin(3); - nodeManager.before(); -} ~~~ Use the arduino pins to power on and off the attached sensors. All the sensors' vcc and ground are connected to pin 6 (ground) and 7 (vcc). NodeManager will enable the vcc pin every time just before loop() and wait for 100ms for the power to settle before running loop() of each sensor: ~~~c -void before() { nodeManager.setPowerPins(6,7,100); - nodeManager.before(); -} ~~~ Register a thermistor sensor attached to pin A2. NodeManager will then send the temperature to the controller at the end of each sleeping cycle: ~~~c -void before() { nodeManager.registerSensor(SENSOR_THERMISTOR,A2); - nodeManager.before(); -} +~~~ + +Register a SHT21 temperature/humidity sensor; since using i2c for communicating with the sensor, the pins used are implicit (A4 and A5). NodeManager will then send the temperature and the humidity to the controller at the end of each sleeping cycle: + +~~~c + nodeManager.registerSensor(SENSOR_SHT21); ~~~ Register a LDR sensor attached to pin A1 and send to the gateway the average of 3 samples: ~~~c -void before() { int sensor_ldr = nodeManager.registerSensor(SENSOR_LDR,A1); ((SensorLDR*)nodeManager.get(sensor_ldr))->setSamples(3); - nodeManager.before(); -} ~~~ Register a rain sensor connected to A0. This will be powered with via pins 4 (ground) and 5 (vcc) just before reading its value at each cycle, it will be presented as S_RAIN. sending V_RAINRATE messages, the output will be a percentage (calculated between 200 and 2014) and the value will be reversed (so that no rain will be 0%): ~~~c -void before() { int rain = nodeManager.registerSensor(SENSOR_ANALOG_INPUT,A0); SensorAnalogInput* rainSensor = ((SensorAnalogInput*)nodeManager.get(rain)); rainSensor->setPowerPins(4,5,300); @@ -455,16 +474,11 @@ void before() { rainSensor->setRangeMin(200); rainSensor->setRangeMax(1024); rainSensor->setReverse(true); - nodeManager.before(); -} ~~~ Register a latching relay connecting to pin 6 (set) and pin 7 (unset): ~~~c -void before() { nodeManager.registerSensor(SENSOR_LATCHING_RELAY,6); nodeManager.registerSensor(SENSOR_LATCHING_RELAY,7); - nodeManager.before(); -} ~~~ \ No newline at end of file diff --git a/NodeManagerTemplate/config.h b/NodeManagerTemplate/config.h index 594d1124ca94757551cd4c584638a07e6670c2b7..85ff5a4b191f4b859f53893376a34e2934b64420 100644 --- a/NodeManagerTemplate/config.h +++ b/NodeManagerTemplate/config.h @@ -6,20 +6,31 @@ */ #define SKETCH_NAME "NodeManagerTemplate" -#define SKETCH_VERSION "1.1" +#define SKETCH_VERSION "1.2" /********************************** * MySensors configuration */ +//#define MY_DEBUG +//#define MY_NODE_ID 100 + #define MY_RADIO_NRF24 //#define MY_RF24_ENABLE_ENCRYPTION -//#define MY_DEBUG //#define MY_RF24_CHANNEL 76 -//#define MY_NODE_ID 100 + +//#define MY_RADIO_RFM69 +//#define MY_RFM69_FREQUENCY RF69_868MHZ +//#define MY_IS_RFM69HW +//#define MY_RFM69_ENABLE_ENCRYPTION +//#define MY_RFM69_NETWORKID 100 /*********************************** * NodeManager configuration */ + +// if enabled, enable debug messages on serial port +#define DEBUG 1 + // if enabled, will load the sleep manager library. Sleep mode and sleep interval have to be configured to make the board sleeping/waiting #define SLEEP_MANAGER 1 // if enabled, enable the capability to power on sensors with the arduino's pins to save battery while sleeping @@ -31,9 +42,6 @@ // if enabled, persist the remote configuration settings on EEPROM #define PERSIST 0 -// if enabled, enable debug messages on serial port -#define DEBUG 1 - // if enabled, send a SLEEPING and AWAKE service messages just before entering and just after leaving a sleep cycle #define SERVICE_MESSAGES 1 // if enabled, a battery sensor will be created at BATTERY_CHILD_ID and will report vcc voltage together with the battery level percentage @@ -53,5 +61,9 @@ #define MODULE_SWITCH 0 // Enable this module to use one of the following sensors: SENSOR_DS18B20 #define MODULE_DS18B20 0 +// Enable this module to use one of the following sensors: SENSOR_BH1750 +#define MODULE_BH1750 0 +// Enable this module to use one of the following sensors: SENSOR_MLX90614 +#define MODULE_MLX90614 0 #endif