Commit 65b848b9 authored by user2684's avatar user2684 Committed by GitHub
Browse files

Added support for PWM output with SensorDimmer (#118)

parent 94bf3c7e
......@@ -2542,6 +2542,10 @@ void SensorMHZ19::onProcess(Request & request) {
_send(_msg_service.set(function));
}
// what to do when receiving an interrupt
void SensorMHZ19::onInterrupt() {
}
#endif
/*
......@@ -2620,6 +2624,10 @@ void SensorAM2320::onReceive(const MyMessage & message) {
// what to do when receiving a remote message
void SensorAM2320::onProcess(Request & request) {
}
// what to do when receiving an interrupt
void SensorAM2320::onInterrupt() {
}
#endif
/*
......@@ -2750,6 +2758,10 @@ void SensorTSL2561::onProcess(Request & request) {
}
_send(_msg_service.set(function));
}
// what to do when receiving an interrupt
void SensorTSL2561::onInterrupt() {
}
#endif
/*
......@@ -2764,7 +2776,7 @@ SensorPT100::SensorPT100(NodeManager* node_manager, int child_id, int pin): Sens
setValueType(TYPE_FLOAT);
}
//// setter/getter
// setter/getter
void SensorPT100::setVoltageRef(float value) {
_voltageRef = value;
}
......@@ -2784,7 +2796,6 @@ void SensorPT100::onSetup() {
void SensorPT100::onLoop() {
// read the PT100 sensor
int temperature = _PT100->readTemperature(_pin);
#if DEBUG == 1
Serial.print(F("PT100 I="));
Serial.print(_child_id);
......@@ -2809,6 +2820,112 @@ void SensorPT100::onProcess(Request & request) {
}
_send(_msg_service.set(function));
}
// what to do when receiving an interrupt
void SensorPT100::onInterrupt() {
}
#endif
/*
SensorDimmer
*/
#if MODULE_DIMMER == 1
// contructor
SensorDimmer::SensorDimmer(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
// set presentation, type and value type
setPresentation(S_DIMMER);
setType(V_PERCENTAGE);
}
// setter/getter
void SensorDimmer::setEasing(int value) {
_easing = value;
}
void SensorDimmer::setDuration(int value) {
_duration = value*1000;
}
void SensorDimmer::setStepDuration(int value) {
_duration = value;
}
// what to do during before
void SensorDimmer::onBefore() {
pinMode(_pin, OUTPUT);
}
// what to do during setup
void SensorDimmer::onSetup() {
}
// what to do during loop
void SensorDimmer::onLoop() {
}
// what to do as the main task when receiving a message
void SensorDimmer::onReceive(const MyMessage & message) {
if (message.getCommand() == C_SET) {
int percentage = message.getInt();
// normalize the provided percentage
if (percentage < 0) percentage = 0;
if (percentage > 100) percentage = 100;
fadeTo(percentage);
_value_int = percentage;
}
if (message.getCommand() == C_REQ) {
// return the current status
_value_int = _percentage;
}
}
// what to do when receiving a remote message
void SensorDimmer::onProcess(Request & request) {
int function = request.getFunction();
switch(function) {
case 101: setEasing(request.getValueInt()); break;
case 102: setDuration(request.getValueInt()); break;
case 103: setStepDuration(request.getValueInt()); break;
default: return;
}
_send(_msg_service.set(function));
}
// what to do when receiving an interrupt
void SensorDimmer::onInterrupt() {
}
// fade to the provided value
void SensorDimmer::fadeTo(int target_percentage) {
#if DEBUG == 1
Serial.print(F("DIM I="));
Serial.print(_child_id);
Serial.print(F(" V="));
Serial.println(target_percentage);
#endif
// count how many steps we need to do
int steps = _duration / _step_duration;
// for each step
for (int current_step = 1; current_step <= steps; current_step++) {
// calculate the delta between the target value and the current
int delta = target_percentage - _percentage;
// calculate the smooth transition and adjust it in the 0-255 range
int value_to_write = (int)(_getEasing(current_step,_percentage,delta,steps) / 100. * 255);
// write to the PWM output
analogWrite(_pin,value_to_write);
// wait at the end of this step
wait(_step_duration);
}
_percentage = target_percentage;
}
// for smooth transitions. t: current time, b: beginning value, c: change in value, d: duration
float SensorDimmer::_getEasing(float t, float b, float c, float d) {
if (_easing == EASE_INSINE) return -c * cos(t/d * (M_PI/2)) + c + b;
else if (_easing == EASE_OUTSINE) return c * sin(t/d * (M_PI/2)) + b;
else if (_easing == EASE_INOUTSINE) return -c/2 * (cos(M_PI*t/d) - 1) + b;
else return c*t/d + b;
}
#endif
/*******************************************
......@@ -3149,6 +3266,12 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
// register temperature sensor
return registerSensor(new SensorPT100(this,child_id,pin));
}
#endif
#if MODULE_DIMMER == 1
else if (sensor_type == SENSOR_DIMMER) {
// register the dimmer sensor
return registerSensor(new SensorDimmer(this,child_id,pin));
}
#endif
else {
#if DEBUG == 1
......
......@@ -190,6 +190,10 @@
#ifndef MODULE_BMP280
#define MODULE_BMP280 0
#endif
// Enable this module to use one of the following sensors: SENSOR_DIMMER
#ifndef MODULE_DIMMER
#define MODULE_DIMMER 0
#endif
/***********************************
Supported Sensors
......@@ -299,6 +303,10 @@ enum supported_sensors {
// BMP280 sensor, return temperature and pressure
SENSOR_BMP280,
#endif
#if MODULE_DIMMER == 1
// Generic dimmer sensor used to drive a pwm output
SENSOR_DIMMER,
#endif
};
/***********************************
......@@ -376,6 +384,9 @@ enum supported_sensors {
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#endif
#if MODULE_DIMMER == 1
#include <math.h>
#endif
/*******************************************************************
Classes
......@@ -1222,13 +1233,14 @@ class SensorMHZ19: public Sensor {
SensorMHZ19(NodeManager* node_manager, int child_id, int pin);
// set the pins for RX and TX of the SoftwareSerial (default: Rx=6, Tx=7)
void setRxTx(int rxpin, int txpin);
int readCO2();
// 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);
int readCO2();
void onInterrupt();
protected:
SoftwareSerial* _ser;
int _tx_pin = 6;
......@@ -1249,6 +1261,7 @@ class SensorAM2320: public Sensor {
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
void onInterrupt();
// constants
const static int TEMPERATURE = 0;
const static int HUMIDITY = 1;
......@@ -1279,6 +1292,7 @@ class SensorTSL2561: public Sensor {
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
void onInterrupt();
// constants
const static int ADDR_FLOAT = 0;
const static int ADDR_LOW = 1;
......@@ -1316,12 +1330,50 @@ class SensorPT100: public Sensor {
void onLoop();
void onReceive(const MyMessage & message);
void onProcess(Request & request);
void onInterrupt();
protected:
DFRobotHighTemperature* _PT100;
float _voltageRef = 3.3;
};
#endif
/*
SensorPT100
*/
#if MODULE_DIMMER == 1
class SensorDimmer: public Sensor {
public:
SensorDimmer(NodeManager* node_manager, int child_id, int pin);
// [101] set the effect to use for a smooth transition, can be one of SensorDimmer::EASE_LINEAR, SensorDimmer::EASE_INSINE, SensorDimmer::EASE_OUTSINE, SensorDimmer::EASE_INOUTSINE (default: EASE_LINEAR)
void setEasing(int value);
// [102] the duration of entire the transition in seconds (default: 1)
void setDuration(int value);
// [103] the duration of a single step of the transition in milliseconds (default: 100)
void setStepDuration(int value);
// fade the output from the current value to the target provided in the range 0-100
void fadeTo(int value);
enum easing {
EASE_LINEAR,
EASE_INSINE,
EASE_OUTSINE,
EASE_INOUTSINE,
};
// 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);
void onInterrupt();
protected:
int _percentage = 0;
int _easing = EASE_LINEAR;
int _duration = 1000;
int _step_duration = 100;
float _getEasing(float t, float b, float c, float d);
};
#endif
/***************************************
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:
......
......@@ -209,7 +209,8 @@ The next step is to enable NodeManager's additional functionalities and the modu
#define MODULE_PT100 0
// Enable this module to use one of the following sensors: SENSOR_BMP280
#define MODULE_BMP280 0
// Enable this module to use one of the following sensors: SENSOR_DIMMER
#define MODULE_DIMMER 0
~~~
### Installing the dependencies
......@@ -412,6 +413,7 @@ SENSOR_TSL2561 | TSL2561 sensor, return light in lux
SENSOR_AM2320 | AM2320 sensors, return temperature/humidity based on the attached AM2320 sensor
SENSOR_PT100 | High temperature sensor associated with DFRobot Driver, return the temperature in C° from the attached PT100 sensor
SENSOR_BMP280 | BMP280 sensor, return temperature/pressure based on the attached BMP280 sensor
SENSOR_DIMMER | Generic dimmer sensor used to drive a pwm output
To register a sensor simply call the NodeManager instance with the sensory type and the pin the sensor is conncted to and optionally a child id. For example:
~~~c
......@@ -688,6 +690,18 @@ Each sensor class can expose additional methods.
void setAddress(int value);
~~~
* SensorDimmer
~~~c
// [101] set the effect to use for a smooth transition, can be one of SensorDimmer::EASE_LINEAR, SensorDimmer::EASE_INSINE, SensorDimmer::EASE_OUTSINE, SensorDimmer::EASE_INOUTSINE (default: EASE_LINEAR)
void setEasing(int value);
// [102] the duration of entire the transition in seconds (default: 1)
void setDuration(int value);
// [103] the duration of a single step of the transition in milliseconds (default: 100)
void setStepDuration(int value);
// fade the output from the current value to the target provided in the range 0-100
void fadeTo(int value);
~~~
### Upload your sketch
Upload your sketch to your arduino board as you are used to.
......@@ -1350,6 +1364,7 @@ v1.6:
* Added support for PT100 high temperature sensor
* Added support for MH-Z19 CO2 sensor
* Added buil-in rain and soil moisture analog sensors
* Added support for generic dimmer sensor (PWM output)
* SensorRainGauge now supports sleep mode
* SensorSwitch now supports awake mode
* SensorLatchingRealy now handles automatically both on and off commands
......
......@@ -163,6 +163,8 @@
#define MODULE_PT100 0
// Enable this module to use one of the following sensors: SENSOR_BMP280
#define MODULE_BMP280 0
// Enable this module to use one of the following sensors: SENSOR_DIMMER
#define MODULE_DIMMER 0
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment