diff --git a/libraries/MySensors/examples/SensebenderMicro/SensebenderMicro.ino b/libraries/MySensors/examples/SensebenderMicro/SensebenderMicro.ino index 7c5a0749..805d5ab1 100644 --- a/libraries/MySensors/examples/SensebenderMicro/SensebenderMicro.ino +++ b/libraries/MySensors/examples/SensebenderMicro/SensebenderMicro.ino @@ -14,19 +14,22 @@ #include #include #include +#include +#include // Define a static node address, remove if you want auto address assignment //#define NODE_ADDRESS 3 -#define RELEASE "1.1" +#define RELEASE "1.2" + +#define AVERAGES 2 // Child sensor ID's #define CHILD_ID_TEMP 1 #define CHILD_ID_HUM 2 -#define CHILD_ID_BATT 199 // How many milli seconds between each measurement -#define MEASURE_INTERVAL 60000 +#define MEASURE_INTERVAL 1000 // FORCE_TRANSMIT_INTERVAL, this number of times of wakeup, the sensor is forced to report all values to the controller #define FORCE_TRANSMIT_INTERVAL 30 @@ -34,7 +37,7 @@ // When MEASURE_INTERVAL is 60000 and FORCE_TRANSMIT_INTERVAL is 30, we force a transmission every 30 minutes. // Between the forced transmissions a tranmission will only occur if the measured value differs from the previous measurement -//Pin definitions +// Pin definitions #define TEST_PIN A0 #define LED_PIN A2 #define ATSHA204_PIN 17 // A3 @@ -50,10 +53,10 @@ MySensor gw; // Sensor messages MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); -MyMessage msgBattery(CHILD_ID_BATT, V_VOLTAGE); // Global settings int measureCount = 0; +int sendBattery = 0; boolean isMetric = true; // Storage of old measurements @@ -61,14 +64,21 @@ float lastTemperature = -100; int lastHumidity = -100; long lastBattery = -100; -bool highfreq = true; +RunningAverage raHum(AVERAGES); +RunningAverage raTemp(AVERAGES); +/**************************************************** + * + * Setup code + * + ****************************************************/ void setup() { - +// clock_prescale_set(clock_div_8); // Switch to 1Mhz right after powerup. + pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); - Serial.begin(115200); + Serial.begin(19200); Serial.print(F("Sensebender Micro FW ")); Serial.print(RELEASE); Serial.flush(); @@ -79,6 +89,10 @@ void setup() { digitalWrite(TEST_PIN, HIGH); // Enable pullup if (!digitalRead(TEST_PIN)) testMode(); + // Make sure that ATSHA204 is not floating + pinMode(ATSHA204_PIN, INPUT); + digitalWrite(ATSHA204_PIN, HIGH); + digitalWrite(TEST_PIN,LOW); digitalWrite(LED_PIN, HIGH); @@ -99,19 +113,22 @@ void setup() { gw.present(CHILD_ID_HUM,S_HUM); isMetric = gw.getConfig().isMetric; - Serial.print("isMetric: "); Serial.println(isMetric); - + Serial.print(F("isMetric: ")); Serial.println(isMetric); + raHum.clear(); + raTemp.clear(); + sendTempHumidityMeasurements(false); } -// Main loop function +/*********************************************** + * + * Main loop function + * + ***********************************************/ void loop() { measureCount ++; + sendBattery ++; bool forceTransmit = false; - - // When we wake up the 5th time after power on, switch to 1Mhz clock - // This allows us to print debug messages on startup (as serial port is dependend on oscilator settings). - if ((measureCount == 5) && highfreq) switchClock(1< FORCE_TRANSMIT_INTERVAL) { // force a transmission forceTransmit = true; @@ -119,32 +136,52 @@ void loop() { } gw.process(); - sendBattLevel(forceTransmit); + sendTempHumidityMeasurements(forceTransmit); + if (sendBattery > 60) + { + sendBattLevel(forceTransmit); // Not needed to send battery info that often + sendBattery = 0; + } gw.sleep(MEASURE_INTERVAL); } -/* + +/********************************************* + * * Sends temperature and humidity from Si7021 sensor * * Parameters * - force : Forces transmission of a value (even if it's the same as previous measurement) - */ + * + *********************************************/ void sendTempHumidityMeasurements(bool force) { - if (force) { - lastHumidity = -100; - lastTemperature = -100; - } + bool tx = force; si7021_env data = humiditySensor.getHumidityAndTemperature(); + float oldAvgTemp = raTemp.getAverage(); + float oldAvgHum = raHum.getAverage(); - float temperature = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0; - - int humidity = data.humidityPercent; + raTemp.addValue(data.celsiusHundredths / 100); + raHum.addValue(data.humidityPercent); + + float diffTemp = abs(oldAvgTemp - raTemp.getAverage()); + float diffHum = abs(oldAvgHum - raHum.getAverage()); - if ((lastTemperature != temperature) | (lastHumidity != humidity)) { + Serial.println(diffTemp); + Serial.println(diffHum); + + if (isnan(diffTemp)) tx = true; + if (diffTemp > 0.2) tx = true; + if (diffHum > 0.5) tx = true; + + if (tx) { + measureCount = 0; + float temperature = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0; + + int humidity = data.humidityPercent; Serial.print("T: ");Serial.println(temperature); Serial.print("H: ");Serial.println(humidity); @@ -155,12 +192,14 @@ void sendTempHumidityMeasurements(bool force) } } -/* - * Sends battery information (both voltage, and battery percentage) +/******************************************** + * + * Sends battery information (battery percentage) * * Parameters * - force : Forces transmission of a value - */ + * + *******************************************/ void sendBattLevel(bool force) { if (force) lastBattery = -1; @@ -176,6 +215,11 @@ void sendBattLevel(bool force) } } +/******************************************* + * + * Internal battery ADC measuring + * + *******************************************/ long readVcc() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference @@ -202,18 +246,11 @@ long readVcc() { return result; // Vcc in millivolts } -void switchClock(unsigned char clk) -{ - cli(); - - CLKPR = 1< fillValue +// 0.2.03 - 2013-11-31 getElement +// 0.2.04 - 2014-07-03 added memory protection +// 0.2.05 - 2014-12-16 changed float -> double +// 0.2.06 - 2015-03-07 all size uint8_t +// 0.2.07 - 2015-03-16 added getMin() and getMax() functions (Eric Mulder) +// 0.2.08 - 2015-04-10 refactored getMin() and getMax() implementation +// +// Released to the public domain +// + +#include "RunningAverage.h" +#include + +RunningAverage::RunningAverage(uint8_t size) +{ + _size = size; + _ar = (double*) malloc(_size * sizeof(double)); + if (_ar == NULL) _size = 0; + clear(); +} + +RunningAverage::~RunningAverage() +{ + if (_ar != NULL) free(_ar); +} + +// resets all counters +void RunningAverage::clear() +{ + _cnt = 0; + _idx = 0; + _sum = 0.0; + _min = NAN; + _max = NAN; + for (uint8_t i = 0; i < _size; i++) + { + _ar[i] = 0.0; // keeps addValue simple + } +} + +// adds a new value to the data-set +void RunningAverage::addValue(double value) +{ + if (_ar == NULL) return; // allocation error + _sum -= _ar[_idx]; + _ar[_idx] = value; + _sum += _ar[_idx]; + _idx++; + if (_idx == _size) _idx = 0; // faster than % + // handle min max + if (_cnt == 0) _min = _max = value; + else if (value < _min) _min = value; + else if (value > _max) _max = value; + // update count as last otherwise if( _cnt == 0) above will fail + if (_cnt < _size) _cnt++; +} + +// returns the average of the data-set added sofar +double RunningAverage::getAverage() +{ + if (_cnt == 0) return NAN; + return _sum / _cnt; +} + +// returns the value of an element if exist, NAN otherwise +double RunningAverage::getElement(uint8_t idx) +{ + if (idx >=_cnt ) return NAN; + return _ar[idx]; +} + +// fill the average with a value +// the param number determines how often value is added (weight) +// number should preferably be between 1 and size +void RunningAverage::fillValue(double value, uint8_t number) +{ + clear(); // TODO conditional? if (clr) clear(); + + for (uint8_t i = 0; i < number; i++) + { + addValue(value); + } +} +// END OF FILE \ No newline at end of file diff --git a/libraries/RunningAverage/RunningAverage.h b/libraries/RunningAverage/RunningAverage.h new file mode 100644 index 00000000..c17240ad --- /dev/null +++ b/libraries/RunningAverage/RunningAverage.h @@ -0,0 +1,56 @@ +// +// FILE: RunningAverage.h +// AUTHOR: Rob dot Tillaart at gmail dot com +// VERSION: 0.2.08 +// DATE: 2015-apr-10 +// PURPOSE: RunningAverage library for Arduino +// URL: http://arduino.cc/playground/Main/RunningAverage +// HISTORY: See RunningAverage.cpp +// +// Released to the public domain +// +// backwards compatibility +// clr() clear() +// add(x) addValue(x) +// avg() getAverage() + +#ifndef RunningAverage_h +#define RunningAverage_h + +#define RUNNINGAVERAGE_LIB_VERSION "0.2.08" + +#include "Arduino.h" + +class RunningAverage +{ +public: + RunningAverage(void); + RunningAverage(uint8_t); + ~RunningAverage(); + + void clear(); + void addValue(double); + void fillValue(double, uint8_t); + + double getAverage(); + // returns lowest value added to the data-set since last clear + double getMin() { return _min; }; + // returns highest value added to the data-set since last clear + double getMax() { return _max; }; + + double getElement(uint8_t idx); + uint8_t getSize() { return _size; } + uint8_t getCount() { return _cnt; } + +protected: + uint8_t _size; + uint8_t _cnt; + uint8_t _idx; + double _sum; + double * _ar; + double _min; + double _max; +}; + +#endif +// END OF FILE \ No newline at end of file diff --git a/libraries/RunningAverage/examples/fillValue/fillValue.ino b/libraries/RunningAverage/examples/fillValue/fillValue.ino new file mode 100644 index 00000000..aaf89000 --- /dev/null +++ b/libraries/RunningAverage/examples/fillValue/fillValue.ino @@ -0,0 +1,38 @@ +// +// FILE: fillValue.pde +// AUTHOR: Rob Tillaart +// DATE: 2012-12-30 +// +// PUPROSE: show working of fillValue +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.print("Demo RunningAverage lib - fillValue "); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + + myRA.fillValue(100,5); +} + +void loop(void) +{ + long rn = random(0, 100); + myRA.addValue(rn/100.0); + samples++; + Serial.print("Running Average: "); + Serial.println(myRA.getAverage(), 4); + + if (samples == 300) + { + samples = 0; + myRA.fillValue(100, 10); + } + delay(100); +} \ No newline at end of file diff --git a/libraries/RunningAverage/examples/ra_MinMaxTest/ra_MinMaxTest.ino b/libraries/RunningAverage/examples/ra_MinMaxTest/ra_MinMaxTest.ino new file mode 100644 index 00000000..437251af --- /dev/null +++ b/libraries/RunningAverage/examples/ra_MinMaxTest/ra_MinMaxTest.ino @@ -0,0 +1,46 @@ +// +// FILE: runningAverageMinMaxTest.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.00 +// DATE: 2015-apr-10 +// +// PUPROSE: demo +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("\nDemo runningAverageMinMaxTest"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean + + Serial.println("\nCNT\tMIN\tAVG\tMAX"); +} + +void loop(void) +{ + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + samples++; + Serial.print(samples); + Serial.print("\t"); + Serial.print(myRA.getMin(), 3); + Serial.print("\t"); + Serial.print(myRA.getAverage(), 3); + Serial.print("\t"); + Serial.println(myRA.getMax(), 3); + + if (samples == 100) + { + samples = 0; + myRA.clear(); + Serial.println("\nCNT\tMIN\tAVG\tMAX"); + } + delay(10); +} diff --git a/libraries/RunningAverage/examples/ra_hour/ra_hour.ino b/libraries/RunningAverage/examples/ra_hour/ra_hour.ino new file mode 100644 index 00000000..09d9214c --- /dev/null +++ b/libraries/RunningAverage/examples/ra_hour/ra_hour.ino @@ -0,0 +1,40 @@ +// +// FILE: runningAverageHour.pde +// AUTHOR: Rob Tillaart +// DATE: 2012-12-30 +// +// PUPROSE: show working of runningAverage per hour +// in 2 steps - last minute + last hour +// 3 or more steps also possible +// + +#include "RunningAverage.h" + +RunningAverage raMinute(60); +RunningAverage raHour(60); + +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("Demo RunningAverage lib - average per minute & hour"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + raHour.clear(); + raMinute.clear(); +} + +void loop(void) +{ + long rn = random(0, 100); + raMinute.addValue(rn); + samples++; + + if (samples % 60 == 0) raHour.addValue(raMinute.getAverage()); + + Serial.print(" raMinute: "); + Serial.print(raMinute.getAverage(), 4); + Serial.print(" raHour: "); + Serial.println(raHour.getAverage(), 4); +} \ No newline at end of file diff --git a/libraries/RunningAverage/examples/ra_test/ra_test.ino b/libraries/RunningAverage/examples/ra_test/ra_test.ino new file mode 100644 index 00000000..146112ea --- /dev/null +++ b/libraries/RunningAverage/examples/ra_test/ra_test.ino @@ -0,0 +1,40 @@ +// +// FILE: runningAverageTest.pde +// AUTHOR: Rob Tillaart +// VERSION: 0.1.01 +// DATE: 2012-12-30 +// +// PUPROSE: show working of runningAverage +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("Demo RunningAverage lib"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean +} + +void loop(void) +{ + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + samples++; + Serial.print(samples); + Serial.print("\t Running Average: "); + Serial.println(myRA.getAverage(), 3); + + if (samples == 300) + { + samples = 0; + myRA.clear(); + Serial.println(); + } + delay(10); +} \ No newline at end of file diff --git a/libraries/RunningAverage/keywords.txt b/libraries/RunningAverage/keywords.txt new file mode 100644 index 00000000..3bac6317 --- /dev/null +++ b/libraries/RunningAverage/keywords.txt @@ -0,0 +1,32 @@ +####################################### +# Syntax Coloring Map For RunningAverage +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +RunningAverage KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +clear KEYWORD2 +addValue KEYWORD2 +getAverage KEYWORD2 +getMin KEYWORD2 +getMax KEYWORD2 +fillValue KEYWORD2 +getElement KEYWORD2 +getSize KEYWORD2 +getCount KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + + +####################################### +# Constants (LITERAL1) +####################################### \ No newline at end of file