Commit 54868549 authored by getlarge's avatar getlarge Committed by user2684
Browse files

Added support for AM2320, DHT21, PT100 and TSL2561 sensors (#171 #109 #110 #111)

parent 01bc9d8a
File mode changed from 100644 to 100755
......@@ -10,21 +10,21 @@
// set the vcc and ground pin the sensor is connected to
void PowerManager::setPowerPins(int ground_pin, int vcc_pin, int wait_time) {
_ground_pin = ground_pin;
_vcc_pin = vcc_pin;
#if DEBUG == 1
Serial.print(F("PWR G="));
Serial.print(ground_pin);
Serial.print(_ground_pin);
Serial.print(F(" V="));
Serial.println(vcc_pin);
Serial.println(_vcc_pin);
#endif
if (_ground_pin > 0) {
// configure the ground pin as output and initialize to low
_ground_pin = ground_pin;
pinMode(_ground_pin, OUTPUT);
digitalWrite(_ground_pin, LOW);
}
if (_vcc_pin > 0) {
// configure the vcc pin as output and initialize to high (power on)
_vcc_pin = vcc_pin;
pinMode(_vcc_pin, OUTPUT);
digitalWrite(_vcc_pin, HIGH);
}
......@@ -1027,6 +1027,7 @@ SensorDigitalOutput::SensorDigitalOutput(NodeManager* node_manager, int child_id
// what to do during before
void SensorDigitalOutput::onBefore() {
_setupPin(_pin);
}
// what to do during setup
......@@ -2501,6 +2502,272 @@ void SensorMHZ19::onProcess(Request & request) {
#endif
/*
SensorAM2320
*/
#if MODULE_AM2320 == 1
// constructor
SensorAM2320::SensorAM2320(NodeManager* node_manager, int child_id, AM2320* th, int sensor_type): Sensor(node_manager, child_id,A2) {
_th = th;
_sensor_type = sensor_type;
if (_sensor_type == SensorAM2320::TEMPERATURE) {
// temperature sensor
setPresentation(S_TEMP);
setType(V_TEMP);
setValueType(TYPE_FLOAT);
}
else if (_sensor_type == SensorAM2320::HUMIDITY) {
// humidity sensor
setPresentation(S_HUM);
setType(V_HUM);
setValueType(TYPE_FLOAT);
}
}
// what do to during before
void SensorAM2320::onBefore() {
}
// what do to during setup
void SensorAM2320::onSetup() {
}
// what do to during loop
void SensorAM2320::onLoop() {
switch(_th->Read()) {
case 0:
// temperature sensor
if (_sensor_type == SensorAM2320::TEMPERATURE) {
// read the temperature
float temperature = _th->t;
#if DEBUG == 1
Serial.print(F("AM2320 I="));
Serial.print(_child_id);
Serial.print(F(" T="));
Serial.println(temperature);
#endif
// store the value
_value_float = temperature;
}
// humidity sensor
else if (_sensor_type == SensorAM2320::HUMIDITY) {
// read humidity
float humidity = _th->h;
if (isnan(humidity)) return;
#if DEBUG == 1
Serial.print(F("AM2320 I="));
Serial.print(_child_id);
Serial.print(F(" H="));
Serial.println(humidity);
#endif
// store the value
_value_float = humidity;
}
break;
case 1: Serial.println(F("AM2320 offline")); break;
case 2: Serial.println(F("AM2320 CRC failed")); break;
}
}
// what do to as the main task when receiving a message
void SensorAM2320::onReceive(const MyMessage & message) {
onLoop();
}
// what to do when receiving a remote message
void SensorAM2320::onProcess(Request & request) {
}
#endif
/*
SensorTSL2561
*/
#if MODULE_TSL2561 == 1
// contructor
SensorTSL2561::SensorTSL2561(NodeManager* node_manager, int child_id): Sensor(node_manager, child_id,A2) {
setPresentation(S_LIGHT_LEVEL);
setType(V_LEVEL);
}
// setter/getter
void SensorTSL2561::setGain(int value) {
_tsl_gain = value;
}
void SensorTSL2561::setTiming(int value) {
_tsl_timing = value;
}
void SensorTSL2561::setSpectrum(int value) {
_tsl_spectrum = value;
}
void SensorTSL2561::setAddress(int value) {
_tsl_address = value;
}
// what do to during before
void SensorTSL2561::onBefore() {
switch (_tsl_address) {
case SensorTSL2561::ADDR_FLOAT:
_tsl = new TSL2561(TSL2561_ADDR_FLOAT);
break;
case SensorTSL2561::ADDR_LOW:
_tsl = new TSL2561(TSL2561_ADDR_LOW);
break;
case SensorTSL2561::ADDR_HIGH:
_tsl = new TSL2561(TSL2561_ADDR_HIGH);
break;
}
}
// what do to during setup
void SensorTSL2561::onSetup() {
if (_tsl->begin()) {
switch (_tsl_gain) {
case SensorTSL2561::GAIN_0X:
_tsl->setGain(TSL2561_GAIN_0X);
break;
case SensorTSL2561::GAIN_16X:
_tsl->setGain(TSL2561_GAIN_16X);
break;
}
switch (_tsl_timing) {
case SensorTSL2561::INTEGRATIONTIME_13MS:
_tsl->setTiming(TSL2561_INTEGRATIONTIME_13MS);
break;
case SensorTSL2561::INTEGRATIONTIME_101MS:
_tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS);
break;
case SensorTSL2561::INTEGRATIONTIME_402MS:
_tsl->setTiming(TSL2561_INTEGRATIONTIME_402MS);
break;
}
}
else {
Serial.println(F("TSL2561 offline"));
}
}
// what do to during loop
void SensorTSL2561::onLoop() {
// request the light level
switch (_tsl_spectrum) {
case SensorTSL2561::VISIBLE:
_value_int = _tsl->getLuminosity(TSL2561_VISIBLE);
break;
case SensorTSL2561::FULLSPECTRUM:
_value_int = _tsl->getLuminosity(TSL2561_FULLSPECTRUM);
break;
case SensorTSL2561::INFRARED:
_value_int = _tsl->getLuminosity(TSL2561_INFRARED);
break;
case SensorTSL2561::FULL:
// request the full light level
uint32_t lum = _tsl->getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
_value_int = _tsl->calculateLux(full, ir);
#if DEBUG == 1
Serial.print(F("TSL I="));
Serial.print(_child_id);
Serial.print(F(" LUX="));
Serial.print(_value_int);
Serial.print(F(" IR="));
Serial.print(ir);
Serial.print(F(" FULL="));
Serial.print(full);
Serial.print(F(" VIS="));
Serial.println(full-ir);
#endif
break;
}
#if DEBUG == 1
if (_tsl_spectrum < 3) {
Serial.print(F("TSL I="));
Serial.print(_child_id);
Serial.print(F(" L="));
Serial.println(_value_int);
}
#endif
}
// what do to as the main task when receiving a message
void SensorTSL2561::onReceive(const MyMessage & message) {
onLoop();
}
// what to do when receiving a remote message
void SensorTSL2561::onProcess(Request & request) {
int function = request.getFunction();
switch(function) {
case 101: setGain(request.getValueInt()); break;
case 102: setTiming(request.getValueInt()); break;
case 103: setSpectrum(request.getValueInt()); break;
case 104: setAddress(request.getValueInt()); break;
default: return;
}
_send(_msg_service.set(function));
}
#endif
/*
SensorPT100
*/
// contructor
SensorPT100::SensorPT100(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
// set presentation, type and value type
setPresentation(S_TEMP);
setType(V_TEMP);
setValueType(TYPE_FLOAT);
}
//// setter/getter
void SensorPT100::setVoltageRef(float value) {
_voltageRef = value;
}
// what to do during before
void SensorPT100::onBefore() {
_PT100 = new DFRobotHighTemperature(_voltageRef);
// set the pin as input
pinMode(_pin, INPUT);
}
// what to do during setup
void SensorPT100::onSetup() {
}
// what to do during loop
void SensorPT100::onLoop() {
// read the PT100 sensor
int temperature = _PT100->readTemperature(_pin);
#if DEBUG == 1
Serial.print(F("PT100 I="));
Serial.print(_child_id);
Serial.print(F(" T="));
Serial.println(temperature);
#endif
// store the value
_value_float = temperature;
}
// what to do as the main task when receiving a message
void SensorPT100::onReceive(const MyMessage & message) {
if (message.getCommand() == C_REQ) onLoop();
}
// what to do when receiving a remote message
void SensorPT100::onProcess(Request & request) {
int function = request.getFunction();
switch(function) {
case 101: setVoltageRef(request.getValueFloat()); break;
default: return;
}
_send(_msg_service.set(function));
}
/*******************************************
NodeManager
......@@ -2597,7 +2864,7 @@ void NodeManager::setInterruptMinDelta(long value) {
_powerManager.setPowerPins(ground_pin, vcc_pin, wait_time);
}
void NodeManager::setAutoPowerPins(bool value) {
_auto_power_pins = value;
_auto_power_pins = value;
}
void NodeManager::powerOn() {
_powerManager.powerOn();
......@@ -2666,8 +2933,11 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
else if (sensor_type == SENSOR_LATCHING_RELAY) return registerSensor(new SensorLatchingRelay(this,child_id, pin));
#endif
#if MODULE_DHT == 1
else if (sensor_type == SENSOR_DHT11 || sensor_type == SENSOR_DHT22) {
int dht_type = sensor_type == SENSOR_DHT11 ? DHT11 : DHT22;
else if (sensor_type == SENSOR_DHT11 || sensor_type == SENSOR_DHT22 || sensor_type == SENSOR_DHT21) {
int dht_type;
if (sensor_type == SENSOR_DHT11) dht_type = DHT11;
else if (sensor_type == SENSOR_DHT21) dht_type = DHT21;
else if (sensor_type == SENSOR_DHT22) dht_type = DHT22;
DHT* dht = new DHT(pin,dht_type);
// register temperature sensor
registerSensor(new SensorDHT(this,child_id,pin,dht,SensorDHT::TEMPERATURE,dht_type));
......@@ -2807,6 +3077,28 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
return registerSensor(new SensorMHZ19(this, child_id, pin));
}
#endif
#if MODULE_AM2320 == 1
else if (sensor_type == SENSOR_AM2320) {
AM2320* th = new AM2320();
// register temperature sensor
registerSensor(new SensorAM2320(this,child_id,th,SensorAM2320::TEMPERATURE));
// register humidity sensor
child_id = _getAvailableChildId();
return registerSensor(new SensorAM2320(this,child_id,th,SensorAM2320::HUMIDITY));
}
#endif
#if MODULE_TSL2561 == 1
else if (sensor_type == SENSOR_TSL2561) {
// register light sensor
return registerSensor(new SensorTSL2561(this,child_id));
}
#endif
#if MODULE_PT100 == 1
else if (sensor_type == SENSOR_PT100) {
// register temperature sensor
return registerSensor(new SensorPT100(this,child_id,pin));
}
#endif
else {
#if DEBUG == 1
Serial.print(F("INVALID "));
......
......@@ -111,7 +111,7 @@
Default module settings
*/
// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_ACS712
// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_ACS712, SENSOR_PT100
#ifndef MODULE_ANALOG_INPUT
#define MODULE_ANALOG_INPUT 0
#endif
......@@ -127,7 +127,11 @@
#ifndef MODULE_SHT21
#define MODULE_SHT21 0
#endif
// Enable this module to use one of the following sensors: SENSOR_DHT11, SENSOR_DHT22
// Enable this module to use one of the following sensors: SENSOR_AM2320
#ifndef MODULE_AM2320
#define MODULE_AM2320 0
#endif
// Enable this module to use one of the following sensors: SENSOR_DHT11, SENSOR_DHT22, SENSOR_DHT21
#ifndef MODULE_DHT
#define MODULE_DHT 0
#endif
......@@ -143,6 +147,10 @@
#ifndef MODULE_BH1750
#define MODULE_BH1750 0
#endif
// Enable this module to use one of the following sensors: SENSOR_TSL2561
#ifndef MODULE_TSL2561
#define MODULE_TSL2561 0
#endif
// Enable this module to use one of the following sensors: SENSOR_MLX90614
#ifndef MODULE_MLX90614
#define MODULE_MLX90614 0
......@@ -214,6 +222,7 @@ enum supported_sensors {
// DHT11/DHT22 sensors, return temperature/humidity based on the attached DHT sensor
SENSOR_DHT11,
SENSOR_DHT22,
SENSOR_DHT21,
#endif
#if MODULE_SHT21 == 1
// SHT21 sensor, return temperature/humidity based on the attached SHT21 sensor
......@@ -268,7 +277,20 @@ enum supported_sensors {
// MH-Z19 CO2 sensor
SENSOR_MHZ19,
#endif
#if MODULE_TSL2561 == 1
// TSL2561 sensor, return light in lux
SENSOR_TSL2561,
#endif
#if MODULE_AM2320 == 1
// AM2320 sensors, return temperature/humidity based on the attached AM2320 sensor
SENSOR_AM2320,
#endif
#if MODULE_PT100 == 1
// High temperature sensor associated with DFRobot Driver, return the temperature in C° from the attached PT100 sensor
SENSOR_PT100,
#endif
};
/***********************************
Libraries
*/
......@@ -328,6 +350,17 @@ enum supported_sensors {
#if MODULE_MHZ19 == 1
#include <SoftwareSerial.h>
#endif
#if MODULE_AM2320 == 1
#include <Wire.h>
#include <AM2320.h>
#endif
#if MODULE_TSL2561 == 1
#include <TSL2561.h>
#include <Wire.h>
#endif
#if MODULE_PT100 == 1
#include<DFRobotHighTemperatureSensor.h>
#endif
/*******************************************************************
Classes
......@@ -1175,6 +1208,90 @@ class SensorMHZ19: public Sensor {
};
#endif
/*
SensorAM2320
*/
#if MODULE_AM2320 == 1
class SensorAM2320: public Sensor {
public:
SensorAM2320(NodeManager* node_manager, int child_id, AM2320* th, int sensor_type);
// define what to do at each stage of the sketch
void onBefore();
void onSetup();
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
// constants
const static int TEMPERATURE = 0;
const static int HUMIDITY = 1;
protected:
AM2320* _th;
int _sensor_type = 0;
};
#endif
/*
SensorTSL2561
*/
#if MODULE_TSL2561 == 1
class SensorTSL2561: public Sensor {
public:
SensorTSL2561(NodeManager* node_manager, int child_id);
// [101] set the gain, possible values are SensorTSL2561::GAIN_0X (0), SensorTSL2561::GAIN_16X (1) (default 16x)
void setGain(int value);
// [102] set the timing, possible values are SensorTSL2561::INTEGRATIONTIME_13MS (0), SensorTSL2561::INTEGRATIONTIME_101MS (1), SensorTSL2561::INTEGRATIONTIME_402MS (2) (default: 13ms)
void setTiming(int value);
// [103] set the spectrum, possible values are SensorTSL2561::VISIBLE (0), SensorTSL2561::FULLSPECTRUM (1), SensorTSL2561::INFRARED (2), SensorTSL2561::FULL (3) (default: visible)
void setSpectrum(int value);
// [104] set the i2c address values are SensorTSL2561::ADDR_FLOAT, SensorTSL2561::ADDR_LOW, SensorTSL2561::ADDR_HIGH
void setAddress(int value);
// define what to do at each stage of the sketch
void onBefore();
void onSetup();
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
// constants
const static int ADDR_FLOAT = 0;
const static int ADDR_LOW = 1;
const static int ADDR_HIGH = 2;
const static int GAIN_0X = 0;
const static int GAIN_16X = 1;
const static int INTEGRATIONTIME_13MS = 0;
const static int INTEGRATIONTIME_101MS = 1;
const static int INTEGRATIONTIME_402MS = 2;
const static int VISIBLE = 0;
const static int FULLSPECTRUM = 1;
const static int INFRARED = 2;
const static int FULL = 3;
protected:
TSL2561* _tsl;
int _tsl_address = 0;
int _tsl_gain = 1;
int _tsl_timing = 0;
int _tsl_spectrum = 0;
};
#endif
/*
SensorPT100
*/
class SensorPT100: public Sensor {
public:
SensorPT100(NodeManager* node_manager, int child_id, int pin);
// [101] set the voltageRef used to compare with analog measures
void setVoltageRef(float value);
// define what to do at each stage of the sketch
void onBefore();
void onSetup();
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
protected:
DFRobotHighTemperature* _PT100;
float _voltageRef = 3.3;
};
/***************************************
NodeManager: manages all the aspects of the node
......
/*
NodeManager is intended to take care on your behalf of all those common tasks a MySensors node has to accomplish, speeding up the development cycle of your projects.
NodeManager includes the following main components:
- Sleep manager: allows managing automatically the complexity behind battery-powered sensors spending most of their time sleeping
- Power manager: allows powering on your sensors only while the node is awake
- Battery manager: provides common functionalities to read and report the battery level
- Remote configuration: allows configuring remotely the node without the need to have physical access to it
- Built-in personalities: for the most common sensors, provide embedded code so to allow their configuration with a single line
Documentation available on: https://github.com/mysensors/NodeManager
*/
......@@ -30,11 +28,15 @@ NodeManager nodeManager;
void before() {
// setup the serial port baud rate
Serial.begin(MY_BAUD_RATE);
/*
* Register below your sensors
* Register below your device specific config
*/
/*
* Register below your sensors
*/
/*
......@@ -72,5 +74,3 @@ void receiveTime(unsigned long ts) {
// call NodeManager receiveTime routine
nodeManager.receiveTime(ts);
}
......@@ -151,7 +151,7 @@ Those NodeManager's directives in the `config.h` file control which module/libra
#define MODULE_DIGITAL_OUTPUT 1
// Enable this module to use one of the following sensors: SENSOR_SHT21
#define MODULE_SHT21 0
// Enable this module to use one of the following sensors: SENSOR_DHT11, SENSOR_DHT22
// Enable this module to use one of the following sensors: SENSOR_DHT11, SENSOR_DHT22, SENSOR_DHT21
#define MODULE_DHT 0
// Enable this module to use one of the following sensors: SENSOR_SWITCH, SENSOR_DOOR, SENSOR_MOTION
#define MODULE_SWITCH 0
......@@ -175,6 +175,10 @@ Those NodeManager's directives in the `config.h` file control which module/libra
#define MODULE_MQ 0
// Enable this module to use one of the following sensors: SENSOR_MHZ19
#define MODULE_MHZ19 0
// Enable this module to use one of the following sensors: SENSOR_AM2320
#define MODULE_AM2320 0
// Enable this module to use one of the following sensors: SENSOR_TSL2561
#define MODULE_TSL2561 0
~~~
### Installing the dependencies
......@@ -193,6 +197,8 @@ MODULE_SONOFF | https://github.com/thomasfredericks/Bounce2
MODULE_BMP085 | https://github.com/adafruit/Adafruit-BMP085-Library
MODULE_HCSR04 | https://github.com/mysensors/MySensorsArduinoExamples/tree/master/libraries/NewPing
MODULE_MCP9808 | https://github.com/adafruit/Adafruit_MCP9808_Library
MODULE_AM2320 | https://github.com/thakshak/AM2320
MODULE_TSL2561 | https://github.com/adafruit/TSL2561-Arduino-Library
### Configure NodeManager
......@@ -340,6 +346,8 @@ SENSOR_RAIN_GAUGE | Rain gauge sensor
SENSOR_RAIN | Rain sensor, return the percentage of rain from an attached analog sensor
SENSOR_SOIL_MOISTURE | Soil moisture sensor, return the percentage of moisture from an attached analog sensor
SENSOR_MHZ19 | MH-Z19 CO2 sensor via UART (SoftwareSerial, default on pins 6(Rx) and 7(Tx)
SENSOR_TSL2561 | TSL2561 sensor, return light in lux
SENSOR_AM2320 | AM2320 sensors, return temperature/humidity based on the attached AM2320 sensor
To register a sensor simply call the NodeManager instance with the sensory type and the pin the sensor is conncted to. For example:
~~~c
......@@ -602,6 +610,18 @@ Each sensor class can expose additional methods.
void setRxTx(int rxpin, int txpin);
~~~
* SensorTSL2561
~~~c
// [101] set the gain, possible values are SensorTSL2561::GAIN_0X (0), SensorTSL2561::GAIN_16X (1) (default 16x)
void setGain(int value);
// [102] set the timing, possible values are SensorTSL2561::INTEGRATIONTIME_13MS (0), SensorTSL2561::INTEGRATIONTIME_101MS (1), SensorTSL2561::INTEGRATIONTIME_402MS (2) (default: 13ms)
void setTiming(int value);
// [103] set the spectrum, possible values are SensorTSL2561::VISIBLE (0), SensorTSL2561::FULLSPECTRUM (1), SensorTSL2561::INFRARED (2), SensorTSL2561::FULL (3) (default: visible)
void setSpectrum(int value);
// [104] set the i2c address values are SensorTSL2561::ADDR_FLOAT, SensorTSL2561::ADDR_LOW, SensorTSL2561::ADDR_HIGH
void setAddress(int value);
~~~
### Upload your sketch
Upload your sketch to your arduino board as you are used to.
......
......@@ -18,11 +18,13 @@
//#define MY_NODE_ID 100
// NRF24 radio settings
#define MY_RADIO_NRF24
//#define MY_RADIO_NRF24
//#define MY_RF24_ENABLE_ENCRYPTION
//#define MY_RF24_CHANNEL 76
//#define MY_RF24_PA_LEVEL RF24_PA_HIGH
//#define MY_DEBUG_VERBOSE_RF24
//#define MY_RF24_DATARATE RF24_250KBPS
// RFM69 radio settings
//#define MY_RADIO_RFM69
......@@ -108,7 +110,7 @@
#define MODULE_DIGITAL_INPUT 1
// Enable this module to use one of the following sensors: SENSOR_DIGITAL_OUTPUT, SENSOR_RELAY, SENSOR_LATCHING_RELAY
#define MODULE_DIGITAL_OUTPUT 1
// Enable this module to use one of the following sensors: SENSOR_DHT11, SENSOR_DHT22