mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 01:24:04 +00:00
P145 plugin updates & refactoring
This commit is contained in:
+33
-6
@@ -59,12 +59,12 @@
|
||||
// P145_PCONFIG_RLOAD PCONFIG_FLOAT(0) RLOAD [Ohm]
|
||||
// P145_PCONFIG_RZERO PCONFIG_FLOAT(1) RZERO [Ohm]
|
||||
// P145_PCONFIG_REF PCONFIG_FLOAT(2) REF. level [ppm]
|
||||
// P145_PCONFIG_FLAGS PCONFIG(0) Enable compensation & Enable Calibration & use low Vcc
|
||||
// P145_PCONFIG_TEMP_TASK PCONFIG(1) Temperature compensation task
|
||||
// P145_PCONFIG_TEMP_VAL PCONFIG(2) Temperature compensation value
|
||||
// P145_PCONFIG_HUM_TASK PCONFIG(3) Humidity compensation task
|
||||
// P145_PCONFIG_HUM_VAL PCONFIG(4) Humidity compensation value
|
||||
// P145_PCONFIG_SENSORT PCONFIG(5) Sensor type
|
||||
// P145_PCONFIG_FLAGS PCONFIG(0) Enable compensation & Enable Calibration & use low Vcc
|
||||
// P145_PCONFIG_TEMP_TASK PCONFIG(1) Temperature compensation task
|
||||
// P145_PCONFIG_TEMP_VAL PCONFIG(2) Temperature compensation value
|
||||
// P145_PCONFIG_HUM_TASK PCONFIG(3) Humidity compensation task
|
||||
// P145_PCONFIG_HUM_VAL PCONFIG(4) Humidity compensation value
|
||||
// P145_PCONFIG_SENSORT PCONFIG(5) Sensor type
|
||||
//#######################################################################################################
|
||||
|
||||
#include "_Plugin_Helper.h"
|
||||
@@ -119,6 +119,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
switch (function)
|
||||
{
|
||||
// Make the plugin known with its options
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_145;
|
||||
@@ -135,18 +136,39 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the DEVICENAME for this plugin
|
||||
case PLUGIN_GET_DEVICENAME:
|
||||
{
|
||||
string = F(PLUGIN_NAME_145);
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup the value names for the task
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_145));
|
||||
break;
|
||||
}
|
||||
|
||||
// Add custom GPIO description on device overview page
|
||||
case PLUGIN_WEBFORM_SHOW_GPIO_DESCR:
|
||||
{
|
||||
string = F("AIN: ");
|
||||
# ifdef ESP32
|
||||
string += formatGpioLabel(P145_CONFIG_PIN_AIN, false);
|
||||
#else
|
||||
string += F("ADC (TOUT)");
|
||||
#endif
|
||||
if (validGpio(P145_CONFIG_PIN_HEATER))
|
||||
{
|
||||
string += F("<BR>HEAT: ");
|
||||
string += formatGpioLabel(P145_CONFIG_PIN_HEATER, false);
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Setup the web form for the task
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
bool compensate = P145_PCONFIG_FLAGS & 0x0001; // Compensation enable flag
|
||||
@@ -226,6 +248,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Save setting from web form for the task
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
P145_PCONFIG_SENSORT = getFormItemInt(F(P145_GUID_TYPE));
|
||||
@@ -256,6 +279,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the task
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
P145_data_struct *P145_data = static_cast<P145_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
@@ -275,6 +299,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Execute at 10Hz
|
||||
case PLUGIN_TEN_PER_SECOND:
|
||||
{
|
||||
P145_data_struct *P145_data = static_cast<P145_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
@@ -285,6 +310,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Read fresh data from the task
|
||||
case PLUGIN_READ:
|
||||
{
|
||||
P145_data_struct *P145_data = static_cast<P145_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
@@ -305,6 +331,7 @@ boolean Plugin_145(byte function, struct EventStruct *event, String& string)
|
||||
break;
|
||||
}
|
||||
|
||||
// Execute each second
|
||||
case PLUGIN_ONCE_A_SECOND:
|
||||
{
|
||||
P145_data_struct *P145_data = static_cast<P145_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
|
||||
@@ -21,24 +21,24 @@
|
||||
// Below the defines used to represent these enums
|
||||
|
||||
// Gas type identifiers used to condense the sensorDefs table to fixed format
|
||||
#define GAS_USER 0
|
||||
#define GAS_CO2 1
|
||||
#define GAS_H2 2
|
||||
#define GAS_ALCOHOL 3
|
||||
#define GAS_CH4 4
|
||||
#define GAS_LPG 5
|
||||
#define GAS_CO 6
|
||||
#define P145_GASUSER 0
|
||||
#define P145_GASCO2 1
|
||||
#define P145_GASH2 2
|
||||
#define P145_GASALCOHOL 3
|
||||
#define P145_GASCH4 4
|
||||
#define P145_GASLPG 5
|
||||
#define P145_GASCO 6
|
||||
|
||||
// Sensor type identifier used to condense the SensorDefs table to fixed format
|
||||
#define SENS_USER 0
|
||||
#define SENS_MQ135 1
|
||||
#define SENS_MQ2 2
|
||||
#define SENS_MQ3 3
|
||||
#define SENS_MQ4 4
|
||||
#define SENS_MQ5 5
|
||||
#define SENS_MQ6 6
|
||||
#define SENS_MQ7 7
|
||||
#define SENS_MQ8 8
|
||||
#define P145_SENSUSER 0
|
||||
#define P145_SENSMQ135 1
|
||||
#define P145_SENSMQ2 2
|
||||
#define P145_SENSMQ3 3
|
||||
#define P145_SENSMQ4 4
|
||||
#define P145_SENSMQ5 5
|
||||
#define P145_SENSMQ6 6
|
||||
#define P145_SENSMQ7 7
|
||||
#define P145_SENSMQ8 8
|
||||
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgNone, // preferred/tuned algorithm
|
||||
SENS_USER, // Name
|
||||
GAS_USER, // gas
|
||||
P145_SENSUSER, // Name
|
||||
P145_GASUSER, // gas
|
||||
},
|
||||
// *** MQ-135 - CO2 ***
|
||||
{
|
||||
@@ -78,8 +78,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
-0.001923077f,// CORF
|
||||
1.130128205f, // CORG
|
||||
p145AlgA, // preferred/tuned algorithm
|
||||
SENS_MQ135, // Name
|
||||
GAS_CO2, // gas
|
||||
P145_SENSMQ135, // Name
|
||||
P145_GASCO2, // gas
|
||||
},
|
||||
// *** MQ-2 - H2 ***
|
||||
{
|
||||
@@ -94,8 +94,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ2, // Name
|
||||
GAS_H2, // gas
|
||||
P145_SENSMQ2, // Name
|
||||
P145_GASH2, // gas
|
||||
},
|
||||
// *** MQ-3 - alcohol ***
|
||||
{
|
||||
@@ -110,8 +110,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ3, // Name
|
||||
GAS_ALCOHOL, // gas
|
||||
P145_SENSMQ3, // Name
|
||||
P145_GASALCOHOL, // gas
|
||||
},
|
||||
// *** MQ-4 - CH4 ***
|
||||
{
|
||||
@@ -126,8 +126,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ4, // Name
|
||||
GAS_CH4, // gas
|
||||
P145_SENSMQ4, // Name
|
||||
P145_GASCH4, // gas
|
||||
},
|
||||
// *** MQ-5 - H2 ***
|
||||
{
|
||||
@@ -142,8 +142,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ5, // Name
|
||||
GAS_CH4, // gas
|
||||
P145_SENSMQ5, // Name
|
||||
P145_GASCH4, // gas
|
||||
},
|
||||
// *** MQ-5 - LPG ***
|
||||
{
|
||||
@@ -158,8 +158,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ5, // Name
|
||||
GAS_LPG, // gas
|
||||
P145_SENSMQ5, // Name
|
||||
P145_GASLPG, // gas
|
||||
},
|
||||
// *** MQ-6 - LPG ***
|
||||
{
|
||||
@@ -174,8 +174,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ6, // Name
|
||||
GAS_LPG, // gas
|
||||
P145_SENSMQ6, // Name
|
||||
P145_GASLPG, // gas
|
||||
},
|
||||
// *** MQ-7 - CO ***
|
||||
{
|
||||
@@ -190,8 +190,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ7, // Name
|
||||
GAS_CO, // gas
|
||||
P145_SENSMQ7, // Name
|
||||
P145_GASCO, // gas
|
||||
},
|
||||
// *** MQ-8 - H2 ***
|
||||
{
|
||||
@@ -206,8 +206,8 @@ const struct P145_SENSORDEF sensorDefs[] PROGMEM =
|
||||
0.0f, // CORF
|
||||
0.0f, // CORG
|
||||
p145AlgB, // preferred/tuned algorithm
|
||||
SENS_MQ8, // Name
|
||||
GAS_H2, // gas
|
||||
P145_SENSMQ8, // Name
|
||||
P145_GASH2, // gas
|
||||
}
|
||||
};
|
||||
/// @brief The number of types stored in the sensorDefs[] table
|
||||
@@ -223,47 +223,6 @@ constexpr const int nbrOfTypes = (int)(sizeof(sensorDefs) / sizeof(struct P145_S
|
||||
#define HEATER_OFF_TIME (60*1000)
|
||||
#define HEATER_MEAS_TIME (30*1000)
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
@brief Perform the calibration algorithm
|
||||
@param[in] currentRcal Value for Rzero determined with current measurement
|
||||
@return Void
|
||||
@note Collect the highest Rzero during the calibration period
|
||||
At the end of the period take mean value of current and calculated Rzero
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
void P145_data_struct::calibrate (float currentRcal)
|
||||
{
|
||||
unsigned long now = millis();
|
||||
long time = timePassedSince(last_cal);
|
||||
float lastRcal = cal_data; // Last calculated Rcal this calibration sequence
|
||||
|
||||
if ((currentRcal > lastRcal) || lastRcal <= 0.0f)
|
||||
{
|
||||
cal_data = currentRcal;
|
||||
}
|
||||
const bool doit = (time > P145_CALIBRATION_INTERVAL) && (cal_data > 0.0f);
|
||||
if (doit)
|
||||
{
|
||||
rzero = cal_data; // Update Rzero as determined by calibration
|
||||
cal_data = 0.0f; // Restart calibration cycle with no value
|
||||
last_cal = now; // Remember calibration moment
|
||||
}
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO))
|
||||
{
|
||||
#ifdef P145_DEBUG
|
||||
// Calculated Rzero if calibration concentration is applied
|
||||
// Rcal as calculated previous sample
|
||||
addLog(LOG_LEVEL_INFO, concat(concat(F("MQ-xx: Calibration with Rcal = "), currentRcal), concat(F(" Rlast = "), lastRcal)));
|
||||
#endif
|
||||
if (doit)
|
||||
{
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: ***Calibrating*** Rzero = "), cal_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
@brief Get the resistance of the sensor, ie. the property to be measured
|
||||
@@ -347,21 +306,8 @@ float P145_data_struct::getRZero(float rSensor) const
|
||||
/*****************************************************************************/
|
||||
float P145_data_struct::getCorrectedRZero(float rSensor, float temperature, float humidity) const
|
||||
{
|
||||
float c; // Correction factor
|
||||
|
||||
if (sensordef.cora <= 0.0f)
|
||||
{
|
||||
return (getRZero(rSensor));
|
||||
}
|
||||
else if (temperature < 20.0f) //TODO this is an ugly constant associated with the MQ-135 sensor only
|
||||
{
|
||||
c = sensordef.cora * temperature * temperature - sensordef.corb * temperature + sensordef.corc - (humidity - 33.0f) * sensordef.cord;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = sensordef.core * temperature + sensordef.corf * humidity + sensordef.corg;
|
||||
}
|
||||
return (rSensor / c) * powf((refLevel / sensordef.para), (1.0f / sensordef.parb));
|
||||
float c = getTempHumCorrection(temperature, humidity);
|
||||
return getRZero(rSensor/c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -407,31 +353,48 @@ float P145_data_struct::getPPM(float rSensor)
|
||||
/*****************************************************************************/
|
||||
float P145_data_struct::getCorrectedPPM(float rSensor, float temperature, float humidity)
|
||||
{
|
||||
float c = 1.0f; // Correction factor
|
||||
switch (algorithm)
|
||||
float c = getTempHumCorrection(temperature, humidity);
|
||||
return getPPM(rSensor/c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
@brief Get the correction factor for temperature & humidity correction
|
||||
@param[in] temperature The ambient air temperature
|
||||
@param[in] humidity The relative humidity
|
||||
@return The correction factor for Rzero to compensate temperature & humidity
|
||||
@note Datasheet suggests temp & hum relation to Rzero is a multiplication factor c
|
||||
here we try to calculate this factor.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
float P145_data_struct::getTempHumCorrection(float temperature, float humidity) const
|
||||
{
|
||||
float c = 1.0f; // Correction factor, default no correction, factor is 1.0
|
||||
if (compensation)
|
||||
{
|
||||
case p145AlgA:
|
||||
if (temperature < 20.0f)
|
||||
{
|
||||
c = sensordef.cora * temperature * temperature - sensordef.corb * temperature + sensordef.corc - (humidity - 33.0f) * sensordef.cord;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = sensordef.core * temperature + sensordef.corf * humidity + sensordef.corg;
|
||||
}
|
||||
break;
|
||||
case p145AlgB:
|
||||
case p145AlgC:
|
||||
// Assume a 2nd order polynomial for temperature and 1st order poynomial for humidit
|
||||
// A + B*t + C*t*t + D*h
|
||||
c = (((sensordef.corc * temperature ) + sensordef.corb) * temperature) + sensordef.cora + (sensordef.cord * humidity);
|
||||
break;
|
||||
case p145AlgNone:
|
||||
// no correction
|
||||
break;
|
||||
default:
|
||||
// No correction
|
||||
c = 1.0f;
|
||||
switch (algorithm)
|
||||
{
|
||||
case p145AlgA:
|
||||
if (temperature < 20.0f)
|
||||
{
|
||||
c = sensordef.cora * temperature * temperature - sensordef.corb * temperature + sensordef.corc - (humidity - 33.0f) * sensordef.cord;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = sensordef.core * temperature + sensordef.corf * humidity + sensordef.corg;
|
||||
}
|
||||
break;
|
||||
case p145AlgB:
|
||||
case p145AlgC:
|
||||
// Assume a 2nd order polynomial for temperature and 1st order poynomial for humidit
|
||||
// A + B*t + C*t*t + D*h
|
||||
c = (((sensordef.corc * temperature ) + sensordef.corb) * temperature) + sensordef.cora + (sensordef.cord * humidity);
|
||||
break;
|
||||
case p145AlgNone:
|
||||
default:
|
||||
// No correction
|
||||
c = 1.0f;
|
||||
}
|
||||
}
|
||||
if (c <=0.0f) // In case no or wrong correction factors are specified disable correction (multiplier = 1.0)
|
||||
{
|
||||
@@ -440,7 +403,7 @@ float P145_data_struct::getCorrectedPPM(float rSensor, float temperature, float
|
||||
#ifdef P145_DEBUG
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: correction= "), c));
|
||||
#endif
|
||||
return getPPM(rSensor/c); // Default value should never be returned
|
||||
return c;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -487,8 +450,8 @@ float P145_data_struct::getAnalogValue()
|
||||
/*****************************************************************************/
|
||||
void P145_data_struct::setSensorData(int stype, bool comp, bool cal, bool vcclow, float load, float zero, float ref)
|
||||
{
|
||||
/* Each MQ-xxx sensor comes with its own set cof constants */
|
||||
/* Copy the correct set from program meory space */
|
||||
/* Each MQ-xxx sensor comes with its own set of constants */
|
||||
/* Copy the correct set from program meory space */
|
||||
if ((stype != sensorType) && (stype < nbrOfTypes) && (stype >= 0))
|
||||
{
|
||||
memcpy_P(&sensordef, &sensorDefs[stype], sizeof(struct P145_SENSORDEF));
|
||||
@@ -501,13 +464,15 @@ void P145_data_struct::setSensorData(int stype, bool comp, bool cal, bool vcclow
|
||||
rload = load; // Rload, load resistor [Ohm]
|
||||
rzero = zero; // R0, reference resistance [Ohm]
|
||||
refLevel = ref; // Reference level for calibration [ppm]
|
||||
rcal_act = 0.0f; // Reset Rzero estimation
|
||||
cal_data = 0.0f; // Reset autocalibration
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
@brief Set the connection pins for the sensor
|
||||
@param[in] analogPin Analog pin for the analog sensor input value
|
||||
@param[in] heaterPin Ootput pin for heater control
|
||||
@param[in] aPin Analog pin for the analog sensor input value
|
||||
@param[in] hPin Ootput pin for heater control
|
||||
@note These values must be set before the plugin can measure the level
|
||||
They are determined by the plugin configuration
|
||||
/*****************************************************************************/
|
||||
@@ -535,7 +500,9 @@ float P145_data_struct::readValue(float temperature, float humidity)
|
||||
float ain = 0.0f; // Analog measured and filtered data
|
||||
float rSensor = 0.0f; // Sensor resistance Rs
|
||||
float value = 0.0f; // Return value
|
||||
|
||||
#ifdef P145_DEBUG
|
||||
uint ovs = 0; // Oversampling count (for debugging)
|
||||
#endif
|
||||
#ifdef P145_TEST
|
||||
static float injector = 50.0f;
|
||||
static float injstep = 50.0f;
|
||||
@@ -557,27 +524,24 @@ float P145_data_struct::readValue(float temperature, float humidity)
|
||||
else
|
||||
{
|
||||
ain = getAnalogValue(); // Use acually being measured value
|
||||
#ifdef P145_DEBUG
|
||||
ovs = ovs_cnt;
|
||||
#endif
|
||||
resetOversampling(); // Reset the oversampling variables.
|
||||
}
|
||||
#endif
|
||||
rSensor = getResistance(ain); // Convert to Rsensor value
|
||||
if (compensation) // Check if temperature/Humidity compensation is selected
|
||||
if (ain > 0.0f) // Skip unsuccesful measurements
|
||||
{
|
||||
value = getCorrectedPPM(rSensor, temperature, humidity);
|
||||
rcal_act = getCorrectedRZero(rSensor, temperature, humidity);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = getPPM(rSensor);
|
||||
rcal_act = getRZero(rSensor);
|
||||
}
|
||||
rSensor = getResistance(ain); // Convert to Rsensor value
|
||||
value = getCorrectedPPM(rSensor, temperature, humidity);
|
||||
rcal_act = getCorrectedRZero(rSensor, temperature, humidity);
|
||||
|
||||
// Perform calibration if functionality is enabled
|
||||
if (calibration && (rcal_act < 1.0e6f))
|
||||
{
|
||||
// Perform calibration if functionality is enabled
|
||||
if (calibration && (rcal_act < 1.0e6f))
|
||||
{
|
||||
calibrate(rcal_act);
|
||||
}
|
||||
}
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO))
|
||||
{
|
||||
#ifdef P145_DEBUG
|
||||
@@ -593,7 +557,7 @@ float P145_data_struct::readValue(float temperature, float humidity)
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: Temp= "), temperature)); // Temperature for compensation algorithm
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: Hum= "), humidity)); // Humidity for compensation algorithm
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: ain= "), ain)); // Measured analog input value
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: ovs= "), ovs_cnt)); // Oversampling count
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: ovs= "), ovs)); // Oversampling count
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: algorithm= "), algorithm)); // Conversion algorithm
|
||||
if (calibration)
|
||||
{
|
||||
@@ -718,6 +682,7 @@ void P145_data_struct::dump() const
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: CORF "), sensordef.corf));
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: CORG "), sensordef.corg));
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: rzero "), rzero));
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: rcal "), rcal_act));
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: analog PIN: "), analogPin));
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: heater PIN: "), heaterPin));
|
||||
}
|
||||
@@ -736,16 +701,16 @@ const String P145_data_struct::getTypeName(int stype)
|
||||
{
|
||||
switch (sensorDefs[stype].name)
|
||||
{
|
||||
case SENS_MQ135: return F("MQ135");
|
||||
case SENS_MQ2: return F("MQ-2");
|
||||
case SENS_MQ3: return F("MQ-3");
|
||||
case SENS_MQ4: return F("MQ-4");
|
||||
case SENS_MQ5: return F("MQ-5");
|
||||
case SENS_MQ6: return F("MQ-6");
|
||||
case SENS_MQ7: return F("MQ-7");
|
||||
case SENS_MQ8: return F("MQ-8");
|
||||
case SENS_USER: return F("user");
|
||||
default: return F("invalid");
|
||||
case P145_SENSMQ135: return F("MQ135");
|
||||
case P145_SENSMQ2: return F("MQ-2");
|
||||
case P145_SENSMQ3: return F("MQ-3");
|
||||
case P145_SENSMQ4: return F("MQ-4");
|
||||
case P145_SENSMQ5: return F("MQ-5");
|
||||
case P145_SENSMQ6: return F("MQ-6");
|
||||
case P145_SENSMQ7: return F("MQ-7");
|
||||
case P145_SENSMQ8: return F("MQ-8");
|
||||
case P145_SENSUSER: return F("user");
|
||||
default: return F("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,14 +726,14 @@ const String P145_data_struct::getGasName(int stype)
|
||||
{
|
||||
switch (sensorDefs[stype].gas)
|
||||
{
|
||||
case GAS_USER: return F("user");
|
||||
case GAS_CH4: return F("CH4");
|
||||
case GAS_CO2: return F("CO2");
|
||||
case GAS_CO: return F("CO");
|
||||
case GAS_H2: return F("H2");
|
||||
case GAS_LPG: return F("LPG");
|
||||
case GAS_ALCOHOL: return F("alcohol");
|
||||
default: return F("invalid");
|
||||
case P145_GASUSER: return F("user");
|
||||
case P145_GASCH4: return F("CH4");
|
||||
case P145_GASCO2: return F("CO2");
|
||||
case P145_GASCO: return F("CO");
|
||||
case P145_GASH2: return F("H2");
|
||||
case P145_GASLPG: return F("LPG");
|
||||
case P145_GASALCOHOL: return F("alcohol");
|
||||
default: return F("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,6 +748,47 @@ int P145_data_struct::getNbrOfTypes()
|
||||
return nbrOfTypes;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
@brief Perform the calibration algorithm
|
||||
@param[in] currentRcal Value for Rzero determined with current measurement
|
||||
@return Void
|
||||
@note Collect the highest Rzero during the calibration period
|
||||
At the end of the period use it to set the Rzero for next calculations
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
void P145_data_struct::calibrate (float currentRcal)
|
||||
{
|
||||
unsigned long now = millis();
|
||||
long time = timePassedSince(last_cal);
|
||||
float lastRcal = cal_data; // Last calculated Rcal this calibration sequence
|
||||
|
||||
if (currentRcal > lastRcal)
|
||||
{
|
||||
cal_data = currentRcal; // Remember highest estimated Rzero during calibration period
|
||||
}
|
||||
const bool doit = (time > P145_CALIBRATION_INTERVAL) && (cal_data > 0.0f);
|
||||
if (doit)
|
||||
{
|
||||
rzero = cal_data; // Update Rzero as determined by calibration
|
||||
cal_data = 0.0f; // Restart calibration cycle with no value
|
||||
last_cal = now; // Remember calibration moment
|
||||
}
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO))
|
||||
{
|
||||
#ifdef P145_DEBUG
|
||||
// Calculated Rzero if calibration concentration is applied
|
||||
// Rcal as calculated previous sample
|
||||
addLog(LOG_LEVEL_INFO, concat(concat(F("MQ-xx: Calibration with Rcal = "), currentRcal), concat(F(" Rlast = "), lastRcal)));
|
||||
#endif
|
||||
if (doit)
|
||||
{
|
||||
addLog(LOG_LEVEL_INFO, concat(F("MQ-xx: ***Calibrating*** Rzero = "), cal_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* @brief Evaluate the heater control algorithm
|
||||
@return void
|
||||
|
||||
@@ -117,6 +117,7 @@ struct P145_data_struct : public PluginTaskData_base
|
||||
float getAnalogValue();
|
||||
float getResistance(float val) const;
|
||||
float getRZero(float rSensor) const;
|
||||
float getTempHumCorrection(float temperature, float humidity) const;
|
||||
float getCorrectedRZero(float rSensor, float temperature, float humidity) const;
|
||||
float getPPM(float rSensor);
|
||||
float getCorrectedPPM(float rSensor, float temperature, float humidity);
|
||||
|
||||
Reference in New Issue
Block a user