allow sensor type selection per plant, changed calculations to use PCT values, due to different raw value meaning
This commit is contained in:
parent
7a54065a5f
commit
d0320beaa7
@ -93,6 +93,9 @@
|
|||||||
#define MOIST_SENSOR_MAX_FRQ 10000 // 10kHz (as never more then 3000 was measured)
|
#define MOIST_SENSOR_MAX_FRQ 10000 // 10kHz (as never more then 3000 was measured)
|
||||||
#define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin)
|
#define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin)
|
||||||
|
|
||||||
|
#define ANALOG_SENSOR_MAX_MV 1000
|
||||||
|
#define ANALOG_SENSOR_MIN_MV 100
|
||||||
|
|
||||||
#define SOLAR_VOLT_FACTOR 11
|
#define SOLAR_VOLT_FACTOR 11
|
||||||
#define BATTSENSOR_INDEX_SOLAR 0
|
#define BATTSENSOR_INDEX_SOLAR 0
|
||||||
#define BATTSENSOR_INDEX_BATTERY 1
|
#define BATTSENSOR_INDEX_BATTERY 1
|
||||||
|
@ -101,6 +101,7 @@ HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as d
|
|||||||
|
|
||||||
#define GENERATE_PLANT(plant, strplant) \
|
#define GENERATE_PLANT(plant, strplant) \
|
||||||
HomieSetting<double> mSensorDry##plant = HomieSetting<double>("dry" strplant, "Plant " strplant "- Moist sensor dry %"); \
|
HomieSetting<double> mSensorDry##plant = HomieSetting<double>("dry" strplant, "Plant " strplant "- Moist sensor dry %"); \
|
||||||
|
HomieSetting<long> pSensorType##plant = HomieSetting<long>("sensoryType" strplant, "sensor" strplant " - sensortype"); \
|
||||||
HomieSetting<long> mPumpAllowedHourRangeStart##plant = HomieSetting<long>("hourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \
|
HomieSetting<long> mPumpAllowedHourRangeStart##plant = HomieSetting<long>("hourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \
|
||||||
HomieSetting<long> mPumpAllowedHourRangeEnd##plant = HomieSetting<long>("hourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \
|
HomieSetting<long> mPumpAllowedHourRangeEnd##plant = HomieSetting<long>("hourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \
|
||||||
HomieSetting<bool> mPumpOnlyWhenLowLight##plant = HomieSetting<bool>("lowLight" strplant, "Plant" strplant " - Enable the Pump only, when there is no sunlight"); \
|
HomieSetting<bool> mPumpOnlyWhenLowLight##plant = HomieSetting<bool>("lowLight" strplant, "Plant" strplant " - Enable the Pump only, when there is no sunlight"); \
|
||||||
@ -108,7 +109,7 @@ HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as d
|
|||||||
HomieSetting<long> pPumpDuration##plant = HomieSetting<long>("pumpDuration" strplant, "Plant" strplant " - time seconds to water when pump is active"); \
|
HomieSetting<long> pPumpDuration##plant = HomieSetting<long>("pumpDuration" strplant, "Plant" strplant " - time seconds to water when pump is active"); \
|
||||||
HomieSetting<long> pPumpMl##plant = HomieSetting<long>("pumpAmount" strplant, "Plant" strplant " - ml (if using flowmeter) to water when pump is active"); \
|
HomieSetting<long> pPumpMl##plant = HomieSetting<long>("pumpAmount" strplant, "Plant" strplant " - ml (if using flowmeter) to water when pump is active"); \
|
||||||
HomieSetting<long> pPowerLevel##plant = HomieSetting<long>("powerLevel" strplant, "Plant" strplant " - pwm duty cycle in percent"); \
|
HomieSetting<long> pPowerLevel##plant = HomieSetting<long>("powerLevel" strplant, "Plant" strplant " - pwm duty cycle in percent"); \
|
||||||
PlantSettings_t mSetting##plant = {&mSensorDry##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInMinutes##plant, &pPumpDuration##plant, &pPowerLevel##plant, &pPumpMl##plant}; \
|
PlantSettings_t mSetting##plant = {&mSensorDry##plant, &pSensorType##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInMinutes##plant, &pPumpDuration##plant, &pPowerLevel##plant, &pPumpMl##plant}; \
|
||||||
/**< Generate all settings for one plant \
|
/**< Generate all settings for one plant \
|
||||||
* \
|
* \
|
||||||
* Feature to start pumping only at morning: @link{SOLAR_CHARGE_MIN_VOLTAGE} and @link{SOLAR_CHARGE_MAX_VOLTAGE} \
|
* Feature to start pumping only at morning: @link{SOLAR_CHARGE_MIN_VOLTAGE} and @link{SOLAR_CHARGE_MAX_VOLTAGE} \
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
|
|
||||||
#include <Homie.h>
|
#include <Homie.h>
|
||||||
|
|
||||||
|
#define SENSOR_NONE 0
|
||||||
|
#define SENSOR_CAPACITIVE_FREQUENCY_MOD 1
|
||||||
|
#define SENSOR_ANALOG_RESISTANCE_PROBE 2
|
||||||
|
|
||||||
//plant pump is deactivated, but sensor values are still recorded and published
|
//plant pump is deactivated, but sensor values are still recorded and published
|
||||||
#define DEACTIVATED_PLANT -1
|
#define DEACTIVATED_PLANT -1
|
||||||
//special value to indicate a missing sensor when the plant is not deactivated but no valid sensor value was read
|
//special value to indicate a missing sensor when the plant is not deactivated but no valid sensor value was read
|
||||||
@ -23,6 +27,7 @@
|
|||||||
typedef struct PlantSettings_t
|
typedef struct PlantSettings_t
|
||||||
{
|
{
|
||||||
HomieSetting<double> *pSensorDry;
|
HomieSetting<double> *pSensorDry;
|
||||||
|
HomieSetting<long> *pSensorMode;
|
||||||
HomieSetting<long> *pPumpAllowedHourRangeStart;
|
HomieSetting<long> *pPumpAllowedHourRangeStart;
|
||||||
HomieSetting<long> *pPumpAllowedHourRangeEnd;
|
HomieSetting<long> *pPumpAllowedHourRangeEnd;
|
||||||
HomieSetting<bool> *pPumpOnlyWhenLowLight;
|
HomieSetting<bool> *pPumpOnlyWhenLowLight;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#define LOG_HARDWARECOUNTER_ERROR_MESSAGE "PCNR returned error"
|
#define LOG_HARDWARECOUNTER_ERROR_MESSAGE "PCNR returned error"
|
||||||
#define LOG_HARDWARECOUNTER_ERROR_CODE -4
|
#define LOG_HARDWARECOUNTER_ERROR_CODE -4
|
||||||
|
|
||||||
|
#define LOG_SENSORMODE_UNKNOWN "Unknown sensor mode requested"
|
||||||
|
#define LOG_SENSORMODE_UNKNOWN_CODE -5
|
||||||
|
|
||||||
#define LOG_PUMP_AND_DOWNLOADMODE "Download mode, ignoring pump request"
|
#define LOG_PUMP_AND_DOWNLOADMODE "Download mode, ignoring pump request"
|
||||||
#define LOG_PUMP_AND_DOWNLOADMODE_CODE 2
|
#define LOG_PUMP_AND_DOWNLOADMODE_CODE 2
|
||||||
|
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
|
|
||||||
|
|
||||||
bool equalish(double x, double y);
|
bool equalish(double x, double y);
|
||||||
|
double mapf(double x, double in_min, double in_max, double out_min, double out_max);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -17,19 +17,21 @@
|
|||||||
#include "ControllerConfiguration.h"
|
#include "ControllerConfiguration.h"
|
||||||
#include "RunningMedian.h"
|
#include "RunningMedian.h"
|
||||||
#include "MathUtils.h"
|
#include "MathUtils.h"
|
||||||
|
#include "MQTTUtils.h"
|
||||||
|
#include "LogDefines.h"
|
||||||
|
|
||||||
#define MOISTURE_MEASUREMENT_DURATION 400 /** ms */
|
#define ANALOG_REREADS 5
|
||||||
|
#define MOISTURE_MEASUREMENT_DURATION 400 /** ms */
|
||||||
#define PWM_FREQ 50000
|
#define PWM_FREQ 50000
|
||||||
#define PWM_BITS 8
|
#define PWM_BITS 8
|
||||||
|
|
||||||
|
|
||||||
class Plant
|
class Plant
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HomieNode *mPlant = NULL;
|
HomieNode *mPlant = NULL;
|
||||||
HomieInternals::PropertyInterface mPump;
|
HomieInternals::PropertyInterface mPump;
|
||||||
int32_t mMoisture_freq = 0;
|
RunningMedian mMoisture_raw = RunningMedian(ANALOG_REREADS);
|
||||||
int mPinSensor = 0; /**< Pin of the moist sensor */
|
int mPinSensor = 0; /**< Pin of the moist sensor */
|
||||||
int mPinPump = 0; /**< Pin of the pump */
|
int mPinPump = 0; /**< Pin of the pump */
|
||||||
bool mConnected = false;
|
bool mConnected = false;
|
||||||
@ -52,10 +54,9 @@ public:
|
|||||||
|
|
||||||
void advertise(void);
|
void advertise(void);
|
||||||
|
|
||||||
/**
|
//for sensor that might take any time
|
||||||
* @brief Measure a new analog moister value
|
void blockingMoistureMeasurement(void);
|
||||||
*
|
//for sensor that need a start and a end in defined timing
|
||||||
*/
|
|
||||||
void startMoistureMeasurement(void);
|
void startMoistureMeasurement(void);
|
||||||
void stopMoistureMeasurement(void);
|
void stopMoistureMeasurement(void);
|
||||||
|
|
||||||
@ -63,10 +64,15 @@ public:
|
|||||||
|
|
||||||
void activatePump(void);
|
void activatePump(void);
|
||||||
|
|
||||||
|
bool isHydroponic()
|
||||||
bool isHydroponic(){
|
{
|
||||||
long current = this->mSetting->pSensorDry->get();
|
long current = this->mSetting->pSensorDry->get();
|
||||||
return equalish(current,HYDROPONIC_MODE);
|
return equalish(current, HYDROPONIC_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
long isSensorMode(int sensorMode)
|
||||||
|
{
|
||||||
|
return this->mSetting->pSensorMode->get() == sensorMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,11 +83,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isPumpRequired()
|
bool isPumpRequired()
|
||||||
{
|
{
|
||||||
if(isHydroponic()){
|
if (isHydroponic())
|
||||||
|
{
|
||||||
//hydroponic only uses timer based controll
|
//hydroponic only uses timer based controll
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool isDry = getCurrentMoisture() > getSetting2Moisture();
|
bool isDry = getCurrentMoisturePCT() < getTargetMoisturePCT();
|
||||||
bool isActive = isPumpTriggerActive();
|
bool isActive = isPumpTriggerActive();
|
||||||
return isDry && isActive;
|
return isDry && isActive;
|
||||||
}
|
}
|
||||||
@ -89,24 +96,14 @@ public:
|
|||||||
bool isPumpTriggerActive()
|
bool isPumpTriggerActive()
|
||||||
{
|
{
|
||||||
long current = this->mSetting->pSensorDry->get();
|
long current = this->mSetting->pSensorDry->get();
|
||||||
return !equalish(current,DEACTIVATED_PLANT);
|
return !equalish(current, DEACTIVATED_PLANT);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getCurrentMoisture()
|
float getTargetMoisturePCT()
|
||||||
{
|
{
|
||||||
if(mMoisture_freq < MOIST_SENSOR_MIN_FRQ){
|
if (isPumpTriggerActive())
|
||||||
return MISSING_SENSOR;
|
|
||||||
}
|
|
||||||
return mMoisture_freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getSetting2Moisture()
|
|
||||||
{
|
|
||||||
if (this->mSetting->pSensorDry != NULL)
|
|
||||||
{
|
{
|
||||||
//1 is totally wet, 0 is try, 0 is MOIST_SENSOR_MAX_FRQ, 1 is MOIST_SENSOR_MIN_FRQ
|
return this->mSetting->pSensorDry->get();
|
||||||
float factor = (this->mSetting->pSensorDry->get());
|
|
||||||
return map(factor,0,100,MOIST_SENSOR_MAX_FRQ,MOIST_SENSOR_MIN_FRQ);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -114,6 +111,38 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getCurrentMoisturePCT()
|
||||||
|
{
|
||||||
|
if (isSensorMode(SENSOR_NONE))
|
||||||
|
{
|
||||||
|
return DEACTIVATED_PLANT;
|
||||||
|
}
|
||||||
|
if (isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD))
|
||||||
|
{
|
||||||
|
return mapf(mMoisture_raw.getMedian(), MOIST_SENSOR_MAX_FRQ, MOIST_SENSOR_MIN_FRQ, 0, 100);
|
||||||
|
}
|
||||||
|
else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE))
|
||||||
|
{
|
||||||
|
return mapf(mMoisture_raw.getMedian(), ANALOG_SENSOR_MAX_MV, ANALOG_SENSOR_MIN_MV, 0, 100);
|
||||||
|
} else {
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
|
return DEACTIVATED_PLANT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float getCurrentMoistureRaw()
|
||||||
|
{
|
||||||
|
if (isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD))
|
||||||
|
{
|
||||||
|
if (mMoisture_raw.getMedian() < MOIST_SENSOR_MIN_FRQ)
|
||||||
|
{
|
||||||
|
return MISSING_SENSOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mMoisture_raw.getMedian();
|
||||||
|
}
|
||||||
|
|
||||||
HomieInternals::SendingPromise &setProperty(const String &property) const
|
HomieInternals::SendingPromise &setProperty(const String &property) const
|
||||||
{
|
{
|
||||||
return mPlant->setProperty(property);
|
return mPlant->setProperty(property);
|
||||||
@ -121,7 +150,8 @@ public:
|
|||||||
|
|
||||||
void init(void);
|
void init(void);
|
||||||
|
|
||||||
long getCooldownInSeconds() {
|
long getCooldownInSeconds()
|
||||||
|
{
|
||||||
return this->mSetting->pPumpCooldownInSeconds->get();
|
return this->mSetting->pPumpCooldownInSeconds->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +160,8 @@ public:
|
|||||||
*
|
*
|
||||||
* @return hour
|
* @return hour
|
||||||
*/
|
*/
|
||||||
int getHoursStart() {
|
int getHoursStart()
|
||||||
|
{
|
||||||
return this->mSetting->pPumpAllowedHourRangeStart->get();
|
return this->mSetting->pPumpAllowedHourRangeStart->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +170,15 @@ public:
|
|||||||
*
|
*
|
||||||
* @return hour
|
* @return hour
|
||||||
*/
|
*/
|
||||||
int getHoursEnd() {
|
int getHoursEnd()
|
||||||
|
{
|
||||||
return this->mSetting->pPumpAllowedHourRangeEnd->get();
|
return this->mSetting->pPumpAllowedHourRangeEnd->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAllowedOnlyAtLowLight(void)
|
bool isAllowedOnlyAtLowLight(void)
|
||||||
{
|
{
|
||||||
if(this->isHydroponic()){
|
if (this->isHydroponic())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->mSetting->pPumpOnlyWhenLowLight->get();
|
return this->mSetting->pPumpOnlyWhenLowLight->get();
|
||||||
@ -153,11 +186,12 @@ public:
|
|||||||
|
|
||||||
void publishState(String state);
|
void publishState(String state);
|
||||||
|
|
||||||
bool switchHandler(const HomieRange& range, const String& value);
|
bool switchHandler(const HomieRange &range, const String &value);
|
||||||
|
|
||||||
void setSwitchHandler(HomieInternals::PropertyInputHandler f);
|
void setSwitchHandler(HomieInternals::PropertyInputHandler f);
|
||||||
|
|
||||||
long getPumpDuration() {
|
long getPumpDuration()
|
||||||
|
{
|
||||||
return this->mSetting->pPumpDuration->get();
|
return this->mSetting->pPumpDuration->get();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -5,3 +5,8 @@ bool equalish(double x, double y)
|
|||||||
{
|
{
|
||||||
return (abs(x - y) < 0.5);
|
return (abs(x - y) < 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
|
||||||
|
{
|
||||||
|
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||||
|
}
|
||||||
|
@ -9,18 +9,11 @@
|
|||||||
*
|
*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PlantCtrl.h"
|
#include "PlantCtrl.h"
|
||||||
#include "ControllerConfiguration.h"
|
#include "ControllerConfiguration.h"
|
||||||
#include "TimeUtils.h"
|
#include "TimeUtils.h"
|
||||||
#include "MathUtils.h"
|
|
||||||
#include "driver/pcnt.h"
|
#include "driver/pcnt.h"
|
||||||
|
|
||||||
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
|
|
||||||
{
|
|
||||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSettings_t *setting)
|
Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSettings_t *setting)
|
||||||
{
|
{
|
||||||
this->mPinSensor = pinSensor;
|
this->mPinSensor = pinSensor;
|
||||||
@ -37,6 +30,12 @@ void Plant::init(void)
|
|||||||
this->mSetting->pSensorDry->setValidator([](long candidate) {
|
this->mSetting->pSensorDry->setValidator([](long candidate) {
|
||||||
return (((candidate >= 0.0) && (candidate <= 100.0)) || equalish(candidate,DEACTIVATED_PLANT) || equalish(candidate,HYDROPONIC_MODE));
|
return (((candidate >= 0.0) && (candidate <= 100.0)) || equalish(candidate,DEACTIVATED_PLANT) || equalish(candidate,HYDROPONIC_MODE));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this->mSetting->pSensorMode->setDefaultValue(SENSOR_NONE);
|
||||||
|
this->mSetting->pSensorMode->setValidator([](long candidate) {
|
||||||
|
return candidate == SENSOR_NONE || candidate == SENSOR_CAPACITIVE_FREQUENCY_MOD || candidate == SENSOR_ANALOG_RESISTANCE_PROBE;
|
||||||
|
});
|
||||||
|
|
||||||
this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00
|
this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00
|
||||||
this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) {
|
this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) {
|
||||||
return ((candidate >= 0) && (candidate <= 23));
|
return ((candidate >= 0) && (candidate <= 23));
|
||||||
@ -76,47 +75,82 @@ void Plant::init(void)
|
|||||||
Serial.flush();
|
Serial.flush();
|
||||||
pinMode(this->mPinSensor, INPUT);
|
pinMode(this->mPinSensor, INPUT);
|
||||||
|
|
||||||
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){
|
||||||
pcnt_config_t pcnt_config = { }; // Instancia PCNT config
|
|
||||||
|
|
||||||
pcnt_config.pulse_gpio_num = this->mPinSensor; // Configura GPIO para entrada dos pulsos
|
|
||||||
pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED; // Configura GPIO para controle da contagem
|
|
||||||
pcnt_config.unit = unit; // Unidade de contagem PCNT - 0
|
|
||||||
pcnt_config.channel = PCNT_CHANNEL_0; // Canal de contagem PCNT - 0
|
|
||||||
pcnt_config.counter_h_lim = INT16_MAX; // Limite maximo de contagem - 20000
|
|
||||||
pcnt_config.pos_mode = PCNT_COUNT_INC; // Incrementa contagem na subida do pulso
|
|
||||||
pcnt_config.neg_mode = PCNT_COUNT_DIS; // Incrementa contagem na descida do pulso
|
|
||||||
pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // PCNT - modo lctrl desabilitado
|
|
||||||
pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // PCNT - modo hctrl - se HIGH conta incrementando
|
|
||||||
pcnt_unit_config(&pcnt_config); // Configura o contador PCNT
|
|
||||||
|
|
||||||
|
|
||||||
pcnt_counter_pause(unit); // Pausa o contador PCNT
|
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
||||||
pcnt_counter_clear(unit); // Zera o contador PCNT
|
pcnt_config_t pcnt_config = { }; // Instancia PCNT config
|
||||||
|
|
||||||
|
pcnt_config.pulse_gpio_num = this->mPinSensor; // Configura GPIO para entrada dos pulsos
|
||||||
|
pcnt_config.ctrl_gpio_num = PCNT_PIN_NOT_USED; // Configura GPIO para controle da contagem
|
||||||
|
pcnt_config.unit = unit; // Unidade de contagem PCNT - 0
|
||||||
|
pcnt_config.channel = PCNT_CHANNEL_0; // Canal de contagem PCNT - 0
|
||||||
|
pcnt_config.counter_h_lim = INT16_MAX; // Limite maximo de contagem - 20000
|
||||||
|
pcnt_config.pos_mode = PCNT_COUNT_INC; // Incrementa contagem na subida do pulso
|
||||||
|
pcnt_config.neg_mode = PCNT_COUNT_DIS; // Incrementa contagem na descida do pulso
|
||||||
|
pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // PCNT - modo lctrl desabilitado
|
||||||
|
pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // PCNT - modo hctrl - se HIGH conta incrementando
|
||||||
|
pcnt_unit_config(&pcnt_config); // Configura o contador PCNT
|
||||||
|
|
||||||
|
|
||||||
|
pcnt_counter_pause(unit); // Pausa o contador PCNT
|
||||||
|
pcnt_counter_clear(unit); // Zera o contador PCNT
|
||||||
|
|
||||||
|
Serial.println("Setup Counter " + String(mPinPump) + "=" + String(LOW));
|
||||||
|
} else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)){
|
||||||
|
adcAttachPin(this->mPinSensor);
|
||||||
|
} else if (isSensorMode(SENSOR_NONE)){
|
||||||
|
//nothing to do here
|
||||||
|
} else {
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
Serial.println("Setup Counter " + String(mPinPump) + "=" + String(LOW));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Plant::blockingMoistureMeasurement(void) {
|
||||||
|
if(isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE)){
|
||||||
|
for(int i = 0;i<ANALOG_REREADS;i++){
|
||||||
|
this->mMoisture_raw.add(analogReadMilliVolts(this->mPinSensor));
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
}else if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD) || isSensorMode(SENSOR_NONE)){
|
||||||
|
//nothing to do here
|
||||||
|
} else {
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Plant::startMoistureMeasurement(void) {
|
void Plant::startMoistureMeasurement(void) {
|
||||||
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){
|
||||||
pcnt_counter_resume(unit);
|
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
||||||
|
pcnt_counter_resume(unit);
|
||||||
|
} else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE) || isSensorMode(SENSOR_NONE)){
|
||||||
|
//nothing to do here
|
||||||
|
} else {
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plant::stopMoistureMeasurement(void) {
|
void Plant::stopMoistureMeasurement(void) {
|
||||||
int16_t pulses;
|
if(isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD)){
|
||||||
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
int16_t pulses;
|
||||||
pcnt_counter_pause(unit);
|
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
|
||||||
esp_err_t result = pcnt_get_counter_value(unit, &pulses);
|
pcnt_counter_pause(unit);
|
||||||
pcnt_counter_clear(unit);
|
esp_err_t result = pcnt_get_counter_value(unit, &pulses);
|
||||||
|
pcnt_counter_clear(unit);
|
||||||
|
if(result != ESP_OK){
|
||||||
if(result != ESP_OK){
|
log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE);
|
||||||
//FIXME log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE);
|
this-> mMoisture_raw.clear();
|
||||||
this -> mMoisture_freq = -1;
|
this -> mMoisture_raw.add(-1);
|
||||||
} else {
|
} else {
|
||||||
this->mMoisture_freq = pulses * (1000 / MOISTURE_MEASUREMENT_DURATION);
|
this->mMoisture_raw.add(pulses * (1000 / MOISTURE_MEASUREMENT_DURATION));
|
||||||
|
}
|
||||||
|
}else if (isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE) || isSensorMode(SENSOR_NONE)){
|
||||||
|
//nothing to do here
|
||||||
|
} else {
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plant::postMQTTconnection(void)
|
void Plant::postMQTTconnection(void)
|
||||||
@ -125,8 +159,10 @@ void Plant::postMQTTconnection(void)
|
|||||||
this->mConnected = true;
|
this->mConnected = true;
|
||||||
this->mPlant->setProperty("switch").send(OFF);
|
this->mPlant->setProperty("switch").send(OFF);
|
||||||
|
|
||||||
long raw = getCurrentMoisture();
|
float pct = getCurrentMoisturePCT();
|
||||||
double pct = mapf(raw, MOIST_SENSOR_MIN_FRQ, MOIST_SENSOR_MAX_FRQ, 100, 0);
|
float raw = getCurrentMoistureRaw();
|
||||||
|
Serial.println(pct);
|
||||||
|
Serial.println("..................");
|
||||||
if (equalish(raw, MISSING_SENSOR))
|
if (equalish(raw, MISSING_SENSOR))
|
||||||
{
|
{
|
||||||
pct = 0;
|
pct = 0;
|
||||||
@ -140,9 +176,9 @@ void Plant::postMQTTconnection(void)
|
|||||||
pct = 100;
|
pct = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mPlant->setProperty("moist").send(String(round(pct*10)/10));
|
this->mPlant->setProperty("moist").send(String(pct));
|
||||||
this->mPlant->setProperty("moistraw").send(String(raw));
|
this->mPlant->setProperty("moistraw").send(String(raw));
|
||||||
this->mPlant->setProperty("moisttrigger").send(String(getSetting2Moisture()));
|
this->mPlant->setProperty("moisttrigger").send(String(getTargetMoisturePCT()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plant::deactivatePump(void)
|
void Plant::deactivatePump(void)
|
||||||
|
@ -209,7 +209,7 @@ void readOneWireSensors()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[(sizeof(ds18b20Address) * 2)+1]; /* additional byte for trailing terminator */
|
char buf[(sizeof(ds18b20Address) * 2) + 1]; /* additional byte for trailing terminator */
|
||||||
snprintf(buf, sizeof(buf), "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",
|
snprintf(buf, sizeof(buf), "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",
|
||||||
ds18b20Address[0],
|
ds18b20Address[0],
|
||||||
ds18b20Address[1],
|
ds18b20Address[1],
|
||||||
@ -269,7 +269,27 @@ void readPowerSwitchedSensors()
|
|||||||
|
|
||||||
for (int i = 0; i < MAX_PLANTS; i++)
|
for (int i = 0; i < MAX_PLANTS; i++)
|
||||||
{
|
{
|
||||||
Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoisture() << " hz" << endl;
|
mPlants[i].blockingMoistureMeasurement();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PLANTS; i++)
|
||||||
|
{
|
||||||
|
if (mPlants[i].isSensorMode(SENSOR_CAPACITIVE_FREQUENCY_MOD))
|
||||||
|
{
|
||||||
|
Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " hz" << endl;
|
||||||
|
}
|
||||||
|
else if (mPlants[i].isSensorMode(SENSOR_ANALOG_RESISTANCE_PROBE))
|
||||||
|
{
|
||||||
|
Serial << "Plant " << i << " measurement: " << mPlants[i].getCurrentMoistureRaw() << " mV" << endl;
|
||||||
|
}
|
||||||
|
else if (mPlants[i].isSensorMode(SENSOR_NONE))
|
||||||
|
{
|
||||||
|
Serial << "Plant " << i << " measurement: no sensor configured" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log(LOG_LEVEL_ERROR, LOG_SENSORMODE_UNKNOWN, LOG_SENSORMODE_UNKNOWN_CODE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waterRawSensor.clear();
|
waterRawSensor.clear();
|
||||||
@ -408,7 +428,7 @@ int determineNextPump(bool isLowLight)
|
|||||||
}
|
}
|
||||||
if (!plant.isHydroponic())
|
if (!plant.isHydroponic())
|
||||||
{
|
{
|
||||||
if (equalish(plant.getCurrentMoisture(), MISSING_SENSOR))
|
if (equalish(plant.getCurrentMoistureRaw(), MISSING_SENSOR))
|
||||||
{
|
{
|
||||||
plant.publishState("nosensor");
|
plant.publishState("nosensor");
|
||||||
log(LOG_LEVEL_ERROR, String(String(i) + " No pump possible: missing sensor"), LOG_MISSING_PUMP);
|
log(LOG_LEVEL_ERROR, String(String(i) + " No pump possible: missing sensor"), LOG_MISSING_PUMP);
|
||||||
@ -631,7 +651,7 @@ void pumpActiveLoop()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
long pumpStarted = pumpTarget - (mPlants[pumpToRun].getPumpDuration() * 1000);
|
long pumpStarted = pumpTarget - (mPlants[pumpToRun].getPumpDuration() * 1000);
|
||||||
long duration = millis()-pumpStarted;
|
long duration = millis() - pumpStarted;
|
||||||
if (millis() > pumpTarget)
|
if (millis() > pumpTarget)
|
||||||
{
|
{
|
||||||
mPlants[pumpToRun].setProperty("watertime").send(String(duration));
|
mPlants[pumpToRun].setProperty("watertime").send(String(duration));
|
||||||
@ -704,33 +724,7 @@ void safeSetup()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************* Start One-Wire bus ***************/
|
/************************* Start Homie Framework ***************/
|
||||||
int tempInitStartTime = millis();
|
|
||||||
uint8_t sensorCount = 0U;
|
|
||||||
|
|
||||||
/* Required to read the temperature at least once */
|
|
||||||
while ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT)
|
|
||||||
{
|
|
||||||
sensors.begin();
|
|
||||||
battery.begin();
|
|
||||||
sensorCount = sensors.getDS18Count();
|
|
||||||
delay(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl;
|
|
||||||
Serial.flush();
|
|
||||||
/* Measure temperature TODO idea: move this into setup */
|
|
||||||
if (sensorCount > 0)
|
|
||||||
{
|
|
||||||
//sensors.setResolution(DS18B20_RESOLUTION);
|
|
||||||
sensors.requestTemperatures();
|
|
||||||
}
|
|
||||||
Serial << "Reading sensors start" << endl;
|
|
||||||
Serial.flush();
|
|
||||||
readPowerSwitchedSensors();
|
|
||||||
Serial << "Reading sensors end" << endl;
|
|
||||||
Serial.flush();
|
|
||||||
/************************* Start Homie Framework ***************/
|
|
||||||
Homie_setFirmware("PlantControl", FIRMWARE_VERSION);
|
Homie_setFirmware("PlantControl", FIRMWARE_VERSION);
|
||||||
Homie.disableLedFeedback();
|
Homie.disableLedFeedback();
|
||||||
Homie_setBrand("PlantControl");
|
Homie_setBrand("PlantControl");
|
||||||
@ -766,9 +760,36 @@ void safeSetup()
|
|||||||
|
|
||||||
Homie.setup();
|
Homie.setup();
|
||||||
|
|
||||||
|
/************************* Start One-Wire bus ***************/
|
||||||
|
int tempInitStartTime = millis();
|
||||||
|
uint8_t sensorCount = 0U;
|
||||||
|
|
||||||
|
/* Required to read the temperature at least once */
|
||||||
|
while ((sensorCount == 0 || !battery.isFound()) && millis() < tempInitStartTime + TEMPERATUR_TIMEOUT)
|
||||||
|
{
|
||||||
|
sensors.begin();
|
||||||
|
battery.begin();
|
||||||
|
sensorCount = sensors.getDS18Count();
|
||||||
|
delay(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial << "DS18S20 count: " << sensorCount << " found in " << (millis() - tempInitStartTime) << " ms" << endl;
|
||||||
|
Serial.flush();
|
||||||
|
/* Measure temperature TODO idea: move this into setup */
|
||||||
|
if (sensorCount > 0)
|
||||||
|
{
|
||||||
|
//sensors.setResolution(DS18B20_RESOLUTION);
|
||||||
|
sensors.requestTemperatures();
|
||||||
|
}
|
||||||
|
|
||||||
mConfigured = Homie.isConfigured();
|
mConfigured = Homie.isConfigured();
|
||||||
if (mConfigured)
|
if (mConfigured)
|
||||||
{
|
{
|
||||||
|
Serial << "Reading sensors start" << endl;
|
||||||
|
Serial.flush();
|
||||||
|
readPowerSwitchedSensors();
|
||||||
|
Serial << "Reading sensors end" << endl;
|
||||||
|
Serial.flush();
|
||||||
for (int i = 0; i < MAX_PLANTS; i++)
|
for (int i = 0; i < MAX_PLANTS; i++)
|
||||||
{
|
{
|
||||||
mPlants[i].advertise();
|
mPlants[i].advertise();
|
||||||
|
Loading…
Reference in New Issue
Block a user