initial flowmeter logic and calculation

This commit is contained in:
c3ma 2021-10-06 21:24:34 +02:00
parent b5569aa8ab
commit 2cd0a0f48b
4 changed files with 78 additions and 33 deletions

View File

@ -85,6 +85,10 @@
#define FIRMWARE_VERSION "sw 1.4 hw 0.10" #define FIRMWARE_VERSION "sw 1.4 hw 0.10"
#define TIMED_LIGHT_PIN CUSTOM1_PIN5 #define TIMED_LIGHT_PIN CUSTOM1_PIN5
#define FLOWMETER_PIN CUSTOM1_PIN1
#ifdef FLOWMETER_PIN
#define FLOWMETER_FLOWFACTOR 22 /** F = 22 * Q;Q = L/min */
#endif
#define MOIST_SENSOR_MAX_FRQ 60000 // 60kHz (500Hz margin) #define MOIST_SENSOR_MAX_FRQ 60000 // 60kHz (500Hz margin)
#define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin) #define MOIST_SENSOR_MIN_FRQ 1000 // 1kHz (500Hz margin)

View File

@ -17,6 +17,9 @@
#define LOG_PUMP_BUTNOTANK_MESSAGE "Want to pump but no water" #define LOG_PUMP_BUTNOTANK_MESSAGE "Want to pump but no water"
#define LOG_PUMP_BUTNOTANK_CODE -3 #define LOG_PUMP_BUTNOTANK_CODE -3
#define LOG_HARDWARECOUNTER_ERROR_MESSAGE "PCNR returned error"
#define LOG_HARDWARECOUNTER_ERROR_CODE -4
#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

View File

@ -97,12 +97,19 @@ void Plant::stopMoistureMeasurement(void) {
int16_t pulses; int16_t pulses;
pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId); pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_0 + this->mPlantId);
pcnt_counter_pause(unit); pcnt_counter_pause(unit);
pcnt_get_counter_value(unit, &pulses); esp_err_t result = pcnt_get_counter_value(unit, &pulses);
pcnt_counter_clear(unit); pcnt_counter_clear(unit);
if(result != ESP_OK){
//FIXME log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE);
this -> mMoisture_freq = -1;
} else {
this->mMoisture_freq = pulses * (1000 / MOISTURE_MEASUREMENT_DURATION); this->mMoisture_freq = pulses * (1000 / MOISTURE_MEASUREMENT_DURATION);
} }
}
void Plant::postMQTTconnection(void) void Plant::postMQTTconnection(void)
{ {
const String OFF = String("OFF"); const String OFF = String("OFF");

View File

@ -33,6 +33,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include <Wire.h> #include <Wire.h>
#include <VL53L0X.h> #include <VL53L0X.h>
#include "driver/pcnt.h"
/****************************************************************************** /******************************************************************************
* DEFINES * DEFINES
@ -92,7 +93,7 @@ unsigned long setupFinishedTimestamp;
bool pumpStarted = false; bool pumpStarted = false;
long pumpTarget = -1; long pumpTarget = -1;
#ifdef FLOWMETER #ifdef FLOWMETER_PIN
long pumpTargetMl = -1; long pumpTargetMl = -1;
#endif #endif
@ -591,13 +592,30 @@ bool switch7(const HomieRange &range, const String &value)
return mPlants[6].switchHandler(range, value); return mPlants[6].switchHandler(range, value);
} }
void initPumpLogic()
void pumpActiveLoop()
{ {
bool targetReached = false; //set targets
pumpTarget = millis() + (mPlants[pumpToRun].getPumpDuration() * 1000);
#ifdef FLOWMETER_PIN
pumpTargetMl = mPlants[pumpToRun].getPumpDuration();
if (!pumpStarted) //0-6 are used for moisture measurment
{ pcnt_unit_t unit = (pcnt_unit_t)(PCNT_UNIT_7);
pcnt_config_t pcnt_config = {}; // Instancia PCNT config
pcnt_config.pulse_gpio_num = FLOWMETER_PIN; // 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_DIS; // Incrementa contagem na subida do pulso
pcnt_config.neg_mode = PCNT_COUNT_INC; // 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_clear(unit); // Zera o contador PCNT
pcnt_counter_resume(unit);
#endif
//enable power //enable power
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
digitalWrite(OUTPUT_ENABLE_PUMP, HIGH); digitalWrite(OUTPUT_ENABLE_PUMP, HIGH);
@ -605,21 +623,38 @@ void pumpActiveLoop()
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1);
mPlants[pumpToRun].activatePump(); mPlants[pumpToRun].activatePump();
//set targets }
pumpTarget = millis() + (mPlants[pumpToRun].getPumpDuration() * 1000);
#ifdef FLOWMETER void pumpActiveLoop()
pumpTargetMl = mPlants[pumpToRun].getPumpDuration(); {
#endif bool targetReached = false;
if (!pumpStarted)
{
initPumpLogic();
pumpStarted = true; pumpStarted = true;
} }
#ifdef FLOWMETER #ifdef FLOWMETER_PIN
long pumped = //readFlowMeterCounter * ratio; int16_t pulses;
if(pumped >= pumpTargetMl)) pcnt_unit_t unit = (pcnt_unit_t) (PCNT_UNIT_7);
esp_err_t result = pcnt_get_counter_value(unit, &pulses);
if(result != ESP_OK){
log(LOG_LEVEL_ERROR, LOG_HARDWARECOUNTER_ERROR_MESSAGE, LOG_HARDWARECOUNTER_ERROR_CODE);
targetReached = true;
} else {
/**FLOWMETER_FLOWFACTOR * (L/Min) = F;
given 1L/min -> FLOWMETER_FLOWFACTOR*60 pulses per liter
-> 1000/result -> ml pro pulse;
-> result * pulses ->*/
long pumped = (FLOWMETER_FLOWFACTOR * 60) * pulses / 1000;
if(pumped >= pumpTargetMl)
{ {
targetReached = true; targetReached = true;
pcnt_counter_pause(unit);
} }
mPlants[pumpToRun].setProperty("waterusage").send(String(pumped)); mPlants[pumpToRun].setProperty("waterusage").send(String(pumped));
}
#else #else
if (millis() > pumpTarget) if (millis() > pumpTarget)
{ {
@ -629,6 +664,7 @@ void pumpActiveLoop()
if (targetReached) if (targetReached)
{ {
//disable all //disable all
digitalWrite(OUTPUT_ENABLE_PUMP, LOW); digitalWrite(OUTPUT_ENABLE_PUMP, LOW);
for (int i = 0; i < MAX_PLANTS; i++) for (int i = 0; i < MAX_PLANTS; i++)
@ -724,8 +760,7 @@ void setup()
// Set default values // Set default values
//in seconds //in seconds
deepSleepTime.setDefaultValue(600).setValidator([](long candidate) deepSleepTime.setDefaultValue(600).setValidator([](long candidate) { return (candidate > 0) && (candidate < (60 * 60 * 2) /** 2h max sleep */); });
{ return (candidate > 0) && (candidate < (60 * 60 * 2) /** 2h max sleep */); });
deepSleepNightTime.setDefaultValue(600); deepSleepNightTime.setDefaultValue(600);
ntpServer.setDefaultValue("pool.ntp.org"); ntpServer.setDefaultValue("pool.ntp.org");
@ -735,17 +770,13 @@ void setup()
waterLevelVol.setDefaultValue(5000); /* 5l in ml */ waterLevelVol.setDefaultValue(5000); /* 5l in ml */
lipoSensorAddr.setDefaultValue(""); lipoSensorAddr.setDefaultValue("");
waterSensorAddr.setDefaultValue(""); waterSensorAddr.setDefaultValue("");
pumpIneffectiveWarning.setDefaultValue(5).setValidator([](long candidate) pumpIneffectiveWarning.setDefaultValue(5).setValidator([](long candidate) { return (candidate > 0) && (candidate < (20)); });
{ return (candidate > 0) && (candidate < (20)); });
#if defined(TIMED_LIGHT_PIN) #if defined(TIMED_LIGHT_PIN)
timedLightStart.setDefaultValue(18).setValidator([](long candidate) timedLightStart.setDefaultValue(18).setValidator([](long candidate) { return (candidate > 0) && (candidate < (25)); });
{ return (candidate > 0) && (candidate < (25)); }); timedLightEnd.setDefaultValue(23).setValidator([](long candidate) { return (candidate > 0) && (candidate < (24)); });
timedLightEnd.setDefaultValue(23).setValidator([](long candidate)
{ return (candidate > 0) && (candidate < (24)); });
timedLightOnlyWhenDark.setDefaultValue(true); timedLightOnlyWhenDark.setDefaultValue(true);
timedLightVoltageCutoff.setDefaultValue(3.8).setValidator([](double candidate) timedLightVoltageCutoff.setDefaultValue(3.8).setValidator([](double candidate) { return (candidate > 3.3) && (candidate < (4.2)); });
{ return (candidate > 3.3) && (candidate < (4.2)); });
#endif // TIMED_LIGHT_PIN #endif // TIMED_LIGHT_PIN
Homie.setLoopFunction(homieLoop); Homie.setLoopFunction(homieLoop);