added raw moisture, improved pct calc , formating

This commit is contained in:
2020-11-04 21:57:40 +01:00
parent fd28ffcfaf
commit 503c2b73b9
10 changed files with 555 additions and 409 deletions

View File

@@ -11,55 +11,57 @@
#ifndef CONTROLLER_CONFIG_H
#define CONTROLLER_CONFIG_H
#define FIRMWARE_VERSION "1.0.7"
#define FIRMWARE_VERSION "1.0.7"
#define ADC_TO_VOLT(adc) ((adc) * 3.3 ) / 4095)
#define ADC_TO_VOLT_WITH_MULTI(adc, multi) (((adc) * 3.3 * (multi)) / 4095)
#define ADC_TO_VOLT_WITH_MULTI(adc, multi) (((adc)*3.3 * (multi)) / 4095)
#define MOIST_SENSOR_MAX_ADC 85 * 4095 / 100
#define MOIST_SENSOR_MIN_ADC 25 * 4095 / 100
#define SOLAR_VOLT(adc) ADC_TO_VOLT_WITH_MULTI(adc, 4.0306) /**< 100k and 33k voltage dividor */
#define ADC_5V_TO_3V3(adc) ADC_TO_VOLT_WITH_MULTI(adc, 1.7) /**< 33k and 47k8 voltage dividor */
#define MS_TO_S 1000
#define SOLAR_VOLT(adc) ADC_TO_VOLT_WITH_MULTI(adc, 4.0306) /**< 100k and 33k voltage dividor */
#define ADC_5V_TO_3V3(adc) ADC_TO_VOLT_WITH_MULTI(adc, 1.7) /**< 33k and 47k8 voltage dividor */
#define MS_TO_S 1000
#define SENSOR_LIPO 34 /**< GPIO 34 (ADC1) */
#define SENSOR_SOLAR 35 /**< GPIO 35 (ADC1) */
#define SENSOR_PLANT0 32 /**< GPIO 32 (ADC1) */
#define SENSOR_PLANT1 33 /**< GPIO 33 (ADC1) */
#define SENSOR_PLANT2 25 /**< GPIO 25 (ADC2) */
#define SENSOR_PLANT3 26 /**< GPIO 26 (ADC2) */
#define SENSOR_PLANT4 27 /**< GPIO 27 (ADC2) */
#define SENSOR_PLANT5 14 /**< GPIO 14 (ADC2) */
#define SENSOR_PLANT6 12 /**< GPIO 12 (ADC2) */
#define SENSOR_LIPO 34 /**< GPIO 34 (ADC1) */
#define SENSOR_SOLAR 35 /**< GPIO 35 (ADC1) */
#define SENSOR_PLANT0 32 /**< GPIO 32 (ADC1) */
#define SENSOR_PLANT1 33 /**< GPIO 33 (ADC1) */
#define SENSOR_PLANT2 25 /**< GPIO 25 (ADC2) */
#define SENSOR_PLANT3 26 /**< GPIO 26 (ADC2) */
#define SENSOR_PLANT4 27 /**< GPIO 27 (ADC2) */
#define SENSOR_PLANT5 14 /**< GPIO 14 (ADC2) */
#define SENSOR_PLANT6 12 /**< GPIO 12 (ADC2) */
#define OUTPUT_PUMP0 23 /**< GPIO 23 */
#define OUTPUT_PUMP1 22 /**< GPIO 22 */
#define OUTPUT_PUMP2 21 /**< GPIO 21 */
#define OUTPUT_PUMP3 19 /**< GPIO 19 */
#define OUTPUT_PUMP4 18 /**< GPIO 18 */
#define OUTPUT_PUMP5 5 /**< GPIO 5 */
#define OUTPUT_PUMP6 15 /**< GPIO 15 */
#define OUTPUT_SENSOR 16 /**< GPIO 16 - Enable Sensors */
#define OUTPUT_PUMP 13 /**< GPIO 13 - Enable Pumps */
#define OUTPUT_PUMP0 23 /**< GPIO 23 */
#define OUTPUT_PUMP1 22 /**< GPIO 22 */
#define OUTPUT_PUMP2 21 /**< GPIO 21 */
#define OUTPUT_PUMP3 19 /**< GPIO 19 */
#define OUTPUT_PUMP4 18 /**< GPIO 18 */
#define OUTPUT_PUMP5 5 /**< GPIO 5 */
#define OUTPUT_PUMP6 15 /**< GPIO 15 */
#define SENSOR_DS18B20 2 /**< GPIO 2 */
#define BUTTON 0 /**< GPIO 0 */
#define OUTPUT_SENSOR 16 /**< GPIO 16 - Enable Sensors */
#define OUTPUT_PUMP 13 /**< GPIO 13 - Enable Pumps */
#define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */
#define MAX_PLANTS 7
#define MINIMUM_LIPO_VOLT 3.6f /**< Minimum voltage of the Lipo, that must be present */
#define NO_LIPO_VOLT 2.0f /**< No Lipo connected */
#define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */
#define SENSOR_DS18B20 2 /**< GPIO 2 */
#define BUTTON 0 /**< GPIO 0 */
#define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */
#define MAX_PLANTS 7
#define MINIMUM_LIPO_VOLT 3.6f /**< Minimum voltage of the Lipo, that must be present */
#define NO_LIPO_VOLT 2.0f /**< No Lipo connected */
#define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */
#define SOLAR_CHARGE_MIN_VOLTAGE 7
#define SOLAR_CHARGE_MAX_VOLTAGE 9
#define HC_SR04 /**< Ultrasonic distance sensor to measure water level */
#define SENSOR_SR04_ECHO 17 /**< GPIO 17 - Echo */
#define SENSOR_SR04_TRIG 23 /**< GPIO 23 - Trigger */
#define HC_SR04 /**< Ultrasonic distance sensor to measure water level */
#define SENSOR_SR04_ECHO 17 /**< GPIO 17 - Echo */
#define SENSOR_SR04_TRIG 23 /**< GPIO 23 - Trigger */
#define MAX_CONFIG_SETTING_ITEMS 50 /**< Parameter, that can be configured in Homie */
#define PANIK_MODE_DEEPSLEEP (60*60*5U) /**< 5 hours in usecond */
#define PANIK_MODE_DEEPSLEEP_US (PANIK_MODE_DEEPSLEEP*1000*1000)
#define PANIK_MODE_DEEPSLEEP (60 * 60 * 5U) /**< 5 hours in usecond */
#define PANIK_MODE_DEEPSLEEP_US (PANIK_MODE_DEEPSLEEP * 1000 * 1000)
#define TEMPERATURE_DELTA_TRIGGER_IN_C 1
#define MOIST_DELTA_TRIGGER_ADC 1337

View File

@@ -21,32 +21,36 @@
#include <OneWire.h>
class Ds18B20 {
private:
OneWire* mDs;
int foundDevices;
public:
Ds18B20(int pin) {
this->mDs = new OneWire(pin);
}
class Ds18B20
{
private:
OneWire *mDs;
int foundDevices;
~Ds18B20() {
delete this->mDs;
}
/**
public:
Ds18B20(int pin)
{
this->mDs = new OneWire(pin);
}
~Ds18B20()
{
delete this->mDs;
}
/**
* @brief read amount sensots
* check for available of DS18B20 sensors
* @return amount of sensors
*/
int readDevices(void);
int readDevices(void);
/**
/**
* @brief Read all temperatures in celsius
*
* @param pTemperatures array of float valuies
* @param maxTemperatures size of the given array
* @return int amount of read temperature values
*/
int readAllTemperatures(float* pTemperatures, int maxTemperatures);
int readAllTemperatures(float *pTemperatures, int maxTemperatures);
};
#endif

View File

@@ -45,18 +45,18 @@ HomieSetting<long> waterLevelMax("watermaxlevel", "distance (mm) at maximum wate
HomieSetting<long> waterLevelMin("waterminlevel", "distance (mm) at minimum water level (pumps still covered)");
HomieSetting<long> waterLevelWarn("waterlevelwarn", "warn (mm) if below this water level %");
HomieSetting<long> waterLevelVol("waterVolume", "(ml) between minimum and maximum");
HomieSetting<const char *>ntpServer("ntpServer", "NTP server (pool.ntp.org as default)");
HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as default)");
/** Plant specific ones */
#define GENERATE_PLANT(plant, strplant) \
HomieSetting<long> mSensorDry##plant = HomieSetting<long>("moistdry" strplant, "Plant " strplant "- Moist sensor dry threshold"); \
HomieSetting<long> mPumpAllowedHourRangeStart##plant = HomieSetting<long>("rangehourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \
HomieSetting<long> mPumpAllowedHourRangeEnd##plant = HomieSetting<long>("rangehourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \
#define GENERATE_PLANT(plant, strplant) \
HomieSetting<long> mSensorDry##plant = HomieSetting<long>("moistdry" strplant, "Plant " strplant "- Moist sensor dry threshold"); \
HomieSetting<long> mPumpAllowedHourRangeStart##plant = HomieSetting<long>("rangehourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \
HomieSetting<long> mPumpAllowedHourRangeEnd##plant = HomieSetting<long>("rangehourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \
HomieSetting<bool> mPumpOnlyWhenLowLight##plant = HomieSetting<bool>("onlyWhenLowLightZ" strplant, "Plant" strplant " - Enable the Pump only, when there is light but not enought to charge battery"); \
HomieSetting<long> mPumpCooldownInHours##plant = HomieSetting<long>("cooldownpump" strplant, "Plant" strplant " - How long to wait until the pump is activated again (minutes)"); \
PlantSettings_t mSetting##plant = { &mSensorDry##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInHours##plant };
HomieSetting<long> mPumpCooldownInHours##plant = HomieSetting<long>("cooldownpump" strplant, "Plant" strplant " - How long to wait until the pump is activated again (minutes)"); \
PlantSettings_t mSetting##plant = {&mSensorDry##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInHours##plant};
GENERATE_PLANT(0, "0");
GENERATE_PLANT(1, "1");
GENERATE_PLANT(2, "2");
@@ -65,6 +65,4 @@ GENERATE_PLANT(4, "4");
GENERATE_PLANT(5, "5");
GENERATE_PLANT(6, "6");
#endif /* HOMIE_PLANT_CONFIG_H */

View File

@@ -13,14 +13,15 @@
#include <Homie.h>
#define DEACTIVATED_PLANT 5000
#define DEACTIVATED_PLANT 5000
typedef struct PlantSettings_t {
HomieSetting<long>* pSensorDry;
HomieSetting<long>* pPumpAllowedHourRangeStart;
HomieSetting<long>* pPumpAllowedHourRangeEnd;
HomieSetting<bool>* pPumpOnlyWhenLowLight;
HomieSetting<long>* pPumpCooldownInHours;
typedef struct PlantSettings_t
{
HomieSetting<long> *pSensorDry;
HomieSetting<long> *pPumpAllowedHourRangeStart;
HomieSetting<long> *pPumpAllowedHourRangeEnd;
HomieSetting<bool> *pPumpOnlyWhenLowLight;
HomieSetting<long> *pPumpCooldownInHours;
} PlantSettings_t;
#endif

View File

@@ -15,17 +15,18 @@
#include "HomieTypes.h"
#include "RunningMedian.h"
class Plant {
class Plant
{
private:
RunningMedian moistureRaw = RunningMedian(5);
HomieNode* mPlant = NULL;
int mPinSensor=0; /**< Pin of the moist sensor */
int mPinPump=0; /**< Pin of the pump */
HomieNode *mPlant = NULL;
int mPinSensor = 0; /**< Pin of the moist sensor */
int mPinPump = 0; /**< Pin of the pump */
bool mConnected = false;
public:
PlantSettings_t* mSetting;
PlantSettings_t *mSetting;
/**
* @brief Construct a new Plant object
*
@@ -33,9 +34,9 @@ public:
* @param pinPump Pin of the Pump to use
*/
Plant(int pinSensor, int pinPump,
int plantId,
HomieNode* plant,
PlantSettings_t* setting);
int plantId,
HomieNode *plant,
PlantSettings_t *setting);
void postMQTTconnection(void);
@@ -46,7 +47,7 @@ public:
*
*/
void addSenseValue(void);
int getSensorValue() { return moistureRaw.getMedian(); }
void deactivatePump(void);
@@ -59,31 +60,39 @@ public:
* @return true
* @return false
*/
bool isPumpRequired() {
bool isPumpRequired()
{
bool isDry = getCurrentMoisture() > getSettingsMoisture();
bool isActive = isPumpTriggerActive();
return isDry && isActive;
}
bool isPumpTriggerActive(){
bool isPumpTriggerActive()
{
return this->mSetting->pSensorDry->get() != DEACTIVATED_PLANT;
}
float getCurrentMoisture(){
float getCurrentMoisture()
{
return this->moistureRaw.getMedian();
}
long getSettingsMoisture(){
if(this->mSetting->pSensorDry != NULL){
long getSettingsMoisture()
{
if (this->mSetting->pSensorDry != NULL)
{
return this->mSetting->pSensorDry->get();
} else {
}
else
{
return DEACTIVATED_PLANT;
}
}
HomieInternals::SendingPromise& setProperty(const String& property) const {
HomieInternals::SendingPromise &setProperty(const String &property) const
{
return mPlant->setProperty(property);
}
bool switchHandler(const HomieRange& range, const String& value);
bool switchHandler(const HomieRange &range, const String &value);
void init(void);
@@ -91,16 +100,19 @@ public:
* @brief determine, if the plant was recently casted
* @param sinceLastActivation timestamp of last time
*/
bool isInCooldown(long sinceLastActivation) {
bool isInCooldown(long sinceLastActivation)
{
/* if the time difference is greater than one month, we know these are initial values */
if (sinceLastActivation > (60 * 60 * 24 * 30)) {
if (sinceLastActivation > (60 * 60 * 24 * 30))
{
return false;
}
return (this->mSetting->pPumpCooldownInHours->get() > sinceLastActivation / 3600);
}
bool isAllowedOnlyAtLowLight(void) {
bool isAllowedOnlyAtLowLight(void)
{
return this->mSetting->pPumpOnlyWhenLowLight->get();
}
};

View File

@@ -17,13 +17,11 @@
// not tested ==> use at own risk :)
// #define RUNNING_MEDIAN_USE_MALLOC
// should at least be 5 to be practical,
// odd sizes results in a 'real' middle element and will be a bit faster.
// even sizes takes the average of the two middle elements as median
#define MEDIAN_MIN_SIZE 5
#define MEDIAN_MAX_SIZE 19
#define MEDIAN_MIN_SIZE 5
#define MEDIAN_MAX_SIZE 19
class RunningMedian
{
@@ -45,7 +43,7 @@ public:
float getAverage(uint8_t nMedian);
float getHighest() { return getSortedElement(_cnt - 1); };
float getLowest() { return getSortedElement(0); };
float getLowest() { return getSortedElement(0); };
// get n'th element from the values in time order
float getElement(const uint8_t n);
@@ -58,7 +56,6 @@ public:
// returns current used elements, getCount() <= getSize()
uint8_t getCount() { return _cnt; };
protected:
boolean _sorted;
uint8_t _size;
@@ -66,8 +63,8 @@ protected:
uint8_t _idx;
#ifdef RUNNING_MEDIAN_USE_MALLOC
float * _ar;
uint8_t * _p;
float *_ar;
uint8_t *_p;
#else
float _ar[MEDIAN_MAX_SIZE];
uint8_t _p[MEDIAN_MAX_SIZE];