Skip to content

Commit

Permalink
Multiple fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
user2684 committed Apr 8, 2017
1 parent 4b3f8b7 commit 8280de9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 36 deletions.
66 changes: 50 additions & 16 deletions NodeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,33 @@ float getVcc() {
*/

// set the vcc and ground pin the sensor is connected to
void PowerManager::setPowerPins(int ground_pin, int vcc_pin, long wait) {
void PowerManager::setPowerPins(int ground_pin, int vcc_pin, int wait_time) {
#if DEBUG == 1
Serial.print(F("PWR G="));
Serial.print(ground_pin);
Serial.print(F(" V="));
Serial.println(vcc_pin);
#endif
// configure the vcc pin as output and initialize to low (power off)
// configure the vcc pin as output and initialize to high (power on)
_vcc_pin = vcc_pin;
pinMode(_vcc_pin, OUTPUT);
digitalWrite(_vcc_pin, LOW);
digitalWrite(_vcc_pin, HIGH);
// configure the ground pin as output and initialize to low
_ground_pin = ground_pin;
pinMode(_ground_pin, OUTPUT);
digitalWrite(_ground_pin, LOW);
_wait = wait;
_wait = wait_time;
}

// return true if power pins have been configured
bool PowerManager::_hasPowerManager() {
bool PowerManager::isConfigured() {
if (_vcc_pin != -1 && _ground_pin != -1) return true;
return false;
}

// turn on the sensor by activating its power pins
void PowerManager::powerOn() {
if (! _hasPowerManager()) return;
if (! isConfigured()) return;
#if DEBUG == 1
Serial.print(F("ON P="));
Serial.println(_vcc_pin);
Expand All @@ -73,7 +73,7 @@ void PowerManager::powerOn() {

// turn off the sensor
void PowerManager::powerOff() {
if (! _hasPowerManager()) return;
if (! isConfigured()) return;
#if DEBUG == 1
Serial.print(F("OFF P="));
Serial.println(_vcc_pin);
Expand Down Expand Up @@ -145,8 +145,8 @@ void Sensor::setFloatPrecision(int value) {
_float_precision = value;
}
#if POWER_MANAGER == 1
void Sensor::setPowerPins(int ground_pin, int vcc_pin, long wait) {
_powerManager.setPowerPins(ground_pin, vcc_pin, wait);
void Sensor::setPowerPins(int ground_pin, int vcc_pin, int wait_time) {
_powerManager.setPowerPins(ground_pin, vcc_pin, wait_time);
}
void Sensor::setAutoPowerPins(bool value) {
_auto_power_pins = value;
Expand Down Expand Up @@ -1032,6 +1032,8 @@ SensorDs18b20::SensorDs18b20(int child_id, int pin, DallasTemperature* sensors,
setValueType(TYPE_FLOAT);
_index = index;
_sensors = sensors;
// retrieve and store the address from the index
_sensors->getAddress(_device_address, index);
}

// what do to during before
Expand All @@ -1045,13 +1047,13 @@ void SensorDs18b20::onSetup() {
// what do to during loop
void SensorDs18b20::onLoop() {
// request the temperature
_sensors->requestTemperaturesByIndex(_index);
_sensors->requestTemperatures();
// read the temperature
float temperature = _sensors->getTempCByIndex(_index);
// convert it
if (! getControllerConfig().isMetric) temperature = temperature * 1.8 + 32;
#if DEBUG == 1
Serial.print(F("DS18 I="));
Serial.print(F("DS18B20 I="));
Serial.print(_child_id);
Serial.print(F(" T="));
Serial.println(temperature);
Expand All @@ -1064,6 +1066,22 @@ void SensorDs18b20::onLoop() {
void SensorDs18b20::onReceive(const MyMessage & message) {
onLoop();
}

// function to print a device address
DeviceAddress* SensorDs18b20::getDeviceAddress() {
return &_device_address;
}

// returns the sensor's resolution in bits
int SensorDs18b20::getResolution() {
return _sensors->getResolution(_device_address);
}

// set the sensor's resolution in bits
void SensorDs18b20::setResolution(int value) {
_sensors->setResolution(_device_address, value);
}

#endif

/*
Expand Down Expand Up @@ -1311,8 +1329,8 @@ void NodeManager::setInterrupt(int pin, int mode, int pull) {
}
}
#if POWER_MANAGER == 1
void NodeManager::setPowerPins(int ground_pin, int vcc_pin, long wait) {
_powerManager.setPowerPins(ground_pin, vcc_pin, wait);
void NodeManager::setPowerPins(int ground_pin, int vcc_pin, int wait_time) {
_powerManager.setPowerPins(ground_pin, vcc_pin, wait_time);
}
void NodeManager::setAutoPowerPins(bool value) {
_auto_power_pins = value;
Expand Down Expand Up @@ -1380,7 +1398,7 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
else if (sensor_type == SENSOR_DOOR) index = registerSensor(new SensorDoor(child_id, pin));
else if (sensor_type == SENSOR_MOTION) index = registerSensor(new SensorMotion(child_id, pin));
// set an interrupt on the pin and activate internal pull up
SensorSwitch* sensor = (SensorSwitch*)get(index);
SensorSwitch* sensor = (SensorSwitch*)getSensor(index);
setInterrupt(pin,sensor->getMode(),sensor->getInitial());
return index;
}
Expand Down Expand Up @@ -1466,6 +1484,22 @@ Sensor* NodeManager::get(int child_id) {
// return a pointer to the sensor from the given child_id
return _sensors[child_id];
}
Sensor* NodeManager::getSensor(int child_id) {
return get(child_id);
}

// assign a different child id to a sensor'
bool NodeManager::renameSensor(int old_child_id, int new_child_id) {
// ensure the old id exists and the new is available
if (_sensors[old_child_id] == 0 || _sensors[new_child_id] != 0) return false;
// assign the sensor to new id
_sensors[new_child_id] = _sensors[old_child_id];
// set the new child id
_sensors[new_child_id]->setChildId(new_child_id);
// free up the old id
_sensors[old_child_id] = 0;
return true;
}

// setup NodeManager
void NodeManager::before() {
Expand Down Expand Up @@ -1525,7 +1559,7 @@ void NodeManager::before() {
#endif
}
#endif
#if POWER_MANAGER == 1
#if BATTERY_MANAGER == 1
// set analogReference to internal if measuring the battery through a pin
if (! _battery_internal_vcc && _battery_pin > -1) analogReference(INTERNAL);
#endif
Expand Down Expand Up @@ -1731,7 +1765,7 @@ void NodeManager::_process(const char * message) {
}
// VERSION: send back the extension's version
else if (strcmp(message, "VERSION") == 0) {
_send(_msg.set(VERSION, 1));
_send(_msg.set(VERSION));
}
#if REMOTE_CONFIGURATION == 1
// IDxxx: change the node id to the provided one. E.g. ID025: change the node id to 25. Requires a reboot/restart
Expand Down
27 changes: 18 additions & 9 deletions NodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <Arduino.h>

// define NodeManager version
#define VERSION "1.4-dev1"

/***********************************
Constants
Expand Down Expand Up @@ -40,9 +42,6 @@
#define EEPROM_SLEEP_TIME_MINOR 3
#define EEPROM_SLEEP_UNIT 4

// define NodeManager version
#define VERSION 1.4

/************************************
* Include user defined configuration settings
*/
Expand Down Expand Up @@ -247,15 +246,15 @@ class PowerManager {
public:
PowerManager() {};
// to save battery the sensor can be optionally connected to two pins which will act as vcc and ground and activated on demand
void setPowerPins(int ground_pin, int vcc_pin, long wait = 50);
void setPowerPins(int ground_pin, int vcc_pin, int wait_time = 50);
void powerOn();
void powerOff();
float getVcc();
bool isConfigured();
private:
int _vcc_pin = -1;
int _ground_pin = -1;
long _wait = 0;
bool _hasPowerManager();
};


Expand Down Expand Up @@ -295,7 +294,7 @@ class Sensor {
void setSleepBetweenSend(int value);
#if POWER_MANAGER == 1
// to save battery the sensor can be optionally connected to two pins which will act as vcc and ground and activated on demand
void setPowerPins(int ground_pin, int vcc_pin, long wait = 50);
void setPowerPins(int ground_pin, int vcc_pin, int wait_time = 50);
// if enabled the pins will be automatically powered on while awake and off during sleeping (default: true)
void setAutoPowerPins(bool value);
// manually turn the power on
Expand Down Expand Up @@ -637,10 +636,17 @@ class SensorDs18b20: public Sensor {
void onSetup();
void onLoop();
void onReceive(const MyMessage & message);
// return the sensors' device address
DeviceAddress* getDeviceAddress();
// returns the sensor's resolution in bits
int getResolution();
// set the sensor's resolution in bits
void setResolution(int value);
protected:
float _offset = 0;
int _index;
DallasTemperature* _sensors;
DeviceAddress _device_address;
};
#endif

Expand Down Expand Up @@ -722,7 +728,7 @@ class NodeManager {
void setBatteryPin(int value);
// if setBatteryInternalVcc() is set to false, the volts per bit ratio used to calculate the battery voltage (default: 0.003363075)
void setBatteryVoltsPerBit(float value);
// If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: false)
// If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: true)
void setBatteryReportWithInterrupt(bool value);
#endif
#if SLEEP_MANAGER == 1
Expand All @@ -746,9 +752,12 @@ class NodeManager {
int registerSensor(Sensor* sensor);
// return a sensor by its index
Sensor* get(int sensor_index);
Sensor* getSensor(int sensor_index);
// assign a different child id to a sensor
bool renameSensor(int old_child_id, int new_child_id);
#if POWER_MANAGER == 1
// to save battery the sensor can be optionally connected to two pins which will act as vcc and ground and activated on demand
void setPowerPins(int ground_pin, int vcc_pin, long wait = 50);
void setPowerPins(int ground_pin, int vcc_pin, int wait_time = 50);
// if enabled the pins will be automatically powered on while awake and off during sleeping (default: true)
void setAutoPowerPins(bool value);
// manually turn the power on
Expand All @@ -773,7 +782,7 @@ class NodeManager {
float _battery_min = 2.6;
float _battery_max = 3.3;
int _battery_report_cycles = 10;
bool _battery_report_with_interrupt = false;
bool _battery_report_with_interrupt = true;
bool _battery_internal_vcc = true;
int _battery_pin = -1;
float _battery_volts_per_bit = 0.003363075;
Expand Down
3 changes: 2 additions & 1 deletion NodeManager.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ void before() {
/*
* Register below your sensors
*/
nodeManager.registerSensor(SENSOR_ML8511,A1);



/*
* Register above your sensors
Expand Down
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Node Manager comes with a reasonable default configuration. If you want/need to
void setBatteryPin(int value);
// if setBatteryInternalVcc() is set to false, the volts per bit ratio used to calculate the battery voltage (default: 0.003363075)
void setBatteryVoltsPerBit(float value);
// If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: false)
// If true, wake up by an interrupt counts as a valid cycle for battery reports otherwise only uninterrupted sleep cycles would contribute (default: true)
void setBatteryReportWithInterrupt(bool value);
#endif
#if SLEEP_MANAGER == 1
Expand All @@ -158,6 +158,9 @@ Node Manager comes with a reasonable default configuration. If you want/need to
int registerSensor(Sensor* sensor);
// return a sensor by its index
Sensor* get(int sensor_index);
Sensor* getSensor(int sensor_index);
// assign a different child id to a sensor
bool renameSensor(int old_child_id, int new_child_id);
#if POWER_MANAGER == 1
// to save battery the sensor can be optionally connected to two pins which will act as vcc and ground and activated on demand
void setPowerPins(int ground_pin, int vcc_pin, long wait = 0);
Expand Down Expand Up @@ -234,10 +237,10 @@ nodeManager.registerSensor(new SensorCustom(child_id, pin));
## Configuring the sensors
Each built-in sensor class comes with reasonable default settings. In case you want/need to customize any of those settings, after having registered the sensor, you can retrieve it back and call set functions common to all the sensors or specific for a given class.

To do so, use `nodeManager.get(child_id)` which will return a pointer to the sensor. Remeber to cast it to the right class before calling their functions. For example:
To do so, use `nodeManager.getSensor(child_id)` which will return a pointer to the sensor. Remeber to cast it to the right class before calling their functions. For example:

~~~c
((SensorLatchingRelay*)nodeManager.get(2))->setPulseWidth(50);
((SensorLatchingRelay*)nodeManager.getSensor(2))->setPulseWidth(50);
~~~
Expand Down Expand Up @@ -359,6 +362,16 @@ Each sensor class can expose additional methods.
void setInitial(int value);
~~~
#### SensorDs18b20
~~~c
// return the sensors' device address
DeviceAddress* getDeviceAddress();
// returns the sensor's resolution in bits
int getResolution();
// set the sensor's resolution in bits
void setResolution(int value);
~~~

## Upload your sketch

Upload your sketch to your arduino board as you are used to.
Expand Down Expand Up @@ -507,14 +520,14 @@ Register a LDR sensor attached to pin A1 and send to the gateway the average of

~~~c
int sensor_ldr = nodeManager.registerSensor(SENSOR_LDR,A1);
((SensorLDR*)nodeManager.get(sensor_ldr))->setSamples(3);
((SensorLDR*)nodeManager.getSensor(sensor_ldr))->setSamples(3);
~~~
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 1024) and the value will be reversed (so that no rain will be 0%):
~~~c
int rain = nodeManager.registerSensor(SENSOR_ANALOG_INPUT,A0);
SensorAnalogInput* rainSensor = ((SensorAnalogInput*)nodeManager.get(rain));
SensorAnalogInput* rainSensor = ((SensorAnalogInput*)nodeManager.getSensor(rain));
rainSensor->setPowerPins(4,5,300);
rainSensor->setPresentation(S_RAIN);
rainSensor->setType(V_RAINRATE);
Expand Down Expand Up @@ -765,7 +778,7 @@ void receive(const MyMessage &message) {
## Rain and Soil Moisture Sensor
The following sketch can be used to report the rain level and the soil moisture based on two sensors connected to the board's analog pins (A1 and A2). In this case we are customizing the out-of-the-box SENSOR_ANALOG_INPUT sensor type since we just need to measure an analog input but we also want to provide the correct type and presentation for each sensor.
We register the sensors first with registerSensor() which returns the child id assigned to the sensor. We then retrieve the sensor's reference by calling get() so we can invoke the sensor-specific functions, like setPresentation() and setType().
We register the sensors first with registerSensor() which returns the child id assigned to the sensor. We then retrieve the sensor's reference by calling getSensor() so we can invoke the sensor-specific functions, like setPresentation() and setType().
In this example, the two sensors are not directly connected to the battery's ground and vcc but, to save additional power, are powered through two arduino's pins. By using e.g. setPowerPins(4,5,300), NodeManger will assume pin 4 is ground and pin 5 is vcc for that specific sensor so it will turn on the power just before reading the analog input (and waiting 300ms for the sensor to initialize) and back off before going to sleep.
For both the sensors we want a percentage output and with setRangeMin() and setRangeMax() we define the boundaries for calculating the percentage (if we read e.g. 200 when the rain sensor is completely into the water, we know for sure it will not go below this value which will represent the new lower boundary).
Finally, since both the sensors reports low when wet and high when dry but we need the opposite, we set setReverse() so to have 0% reported when there is no rain/moisture, 100% on the opposite situation.
Expand Down Expand Up @@ -809,8 +822,8 @@ void before() {
int rain = nodeManager.registerSensor(SENSOR_ANALOG_INPUT,A1);
int soil = nodeManager.registerSensor(SENSOR_ANALOG_INPUT,A2);
SensorAnalogInput* rainSensor = ((SensorAnalogInput*)nodeManager.get(rain));
SensorAnalogInput* soilSensor = ((SensorAnalogInput*)nodeManager.get(soil));
SensorAnalogInput* rainSensor = ((SensorAnalogInput*)nodeManager.getSensor(rain));
SensorAnalogInput* soilSensor = ((SensorAnalogInput*)nodeManager.getSensor(soil));
rainSensor->setPresentation(S_RAIN);
rainSensor->setType(V_RAINRATE);
Expand Down
4 changes: 2 additions & 2 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* Sketch configuration
*/

#define SKETCH_NAME "NodeManager"
#define SKETCH_VERSION "1.4"
#define SKETCH_NAME "NodeManagerTemplate"
#define SKETCH_VERSION "1.0"

/**********************************
* MySensors configuration
Expand Down

0 comments on commit 8280de9

Please sign in to comment.