diff --git a/MQ135.cpp b/MQ135.cpp index ef235f7..5e6ca01 100644 --- a/MQ135.cpp +++ b/MQ135.cpp @@ -9,6 +9,10 @@ double MQ135::getVoltage() { return (double)analogRead(pin) * VStep; } +double MQ135::getCorrectionFactor(float temparature, float humidity) { + return (CorrA * pow(temparature, 3) + CorrB * pow(temparature, 2) - CorrC * temparature + CorrD - (CorrE * humidity - CorrE * 33)); +} + double MQ135::getResistance() { double voltage = getVoltage(); double rs = ((VIn * RL) / voltage) - RL; @@ -18,6 +22,10 @@ double MQ135::getResistance() { return rs; } +double MQ135::getCorrectedResistance(float temparature, float humidity) { + return getResistance() / getCorrectionFactor(temparature, humidity); +} + double MQ135::getPPM(float a, float b) { double ratio = getResistance() / R0; double ppm = a * pow(ratio, b); @@ -27,6 +35,15 @@ double MQ135::getPPM(float a, float b) { return ppm; } +double MQ135::getCorrectedPPM(float a, float b, float temparature, float humidity) { + double ratio = getCorrectedResistance(temparature, humidity) / R0; + double ppm = a * pow(ratio, b); + if (ppm < 0) { + ppm = 0; + } + return ppm; +} + double MQ135::getPPMLinear(float a, float b) { double ratio = getResistance() / R0; double ppm_log = (log10(ratio) - b) / a; @@ -41,32 +58,61 @@ double MQ135::getAcetona() { return getPPM(34.668, -3.369); } +double MQ135::getCorrectedAcetona(float temparature, float humidity) { + return getCorrectedPPM(34.668, -3.369, temparature, humidity); +} + double MQ135::getAlcohol() { return getPPM(77.255, -3.18); } +double MQ135::getCorrectedAlcohol(float temparature, float humidity) { + return getCorrectedPPM(77.255, -3.18, temparature, humidity); +} + double MQ135::getCO2() { // return getPPMLinear(-0.3525, 0.7142) + ATMOCO2; return getPPM(110.47, -2.862) + ATMOCO2; } +double MQ135::getCorrectedCO2(float temparature, float humidity) { + return getCorrectedPPM(110.47, -2.862, temparature, humidity) + ATMOCO2; +} + double MQ135::getCO() { return getPPM(605.18, -3.937); } +double MQ135::getCorrectedCO(float temparature, float humidity) { + return getCorrectedPPM(605.18, -3.937, temparature, humidity); +} + double MQ135::getNH4() { return getPPM(102.2, -2.473); } +double MQ135::getCorrectedNH4(float temparature, float humidity) { + return getCorrectedPPM(102.2, -2.473, temparature, humidity); +} + double MQ135::getTolueno() { return getPPM(44.947, -3.445); } +double MQ135::getCorrectedTolueno(float temparature, float humidity) { + return getCorrectedPPM(44.947, -3.445, temparature, humidity); +} + float MQ135::getR0() { double r0 = getResistance() / 3.6; return r0; } +float MQ135::getCorrectedR0(float temparature, float humidity) { + double r0 = getCorrectedResistance(temparature, humidity) / 3.6; + return r0; +} + double MQ135::getR0ByCO2Level(float ppm) { if (ppm > ATMOCO2) { ppm -= ATMOCO2; @@ -78,6 +124,17 @@ double MQ135::getR0ByCO2Level(float ppm) { return pow(10, tmp); } +double MQ135::getCorrectedR0ByCO2Level(float ppm, float temparature, float humidity) { + if (ppm > ATMOCO2) { + ppm -= ATMOCO2; + } + else { + return NAN; + } + double tmp = -(log10(ppm / 110.47) / -2.862) + log10(getCorrectedResistance(temparature, humidity)); + return pow(10, tmp); +} + void MQ135::setR0(float r0) { R0 = r0; } diff --git a/MQ135.h b/MQ135.h index 795bad1..597f6d1 100644 --- a/MQ135.h +++ b/MQ135.h @@ -16,6 +16,13 @@ /// CO2 Level in Atmosphere #define ATMOCO2 397.13 +//Correction Values +#define CorrA -0.000002469136 +#define CorrB 0.00048148148 +#define CorrC 0.0274074074 +#define CorrD 1.37530864197 +#define CorrE 0.0019230769 + /// Helper to calculate Voltage from Input /// Voltage = input * Vin / (Resolution - 1) const double VStep = (double)VIn / (Resolution - 1); @@ -33,34 +40,48 @@ class MQ135 { /// Get R0 in default conditions for calibration purposes. /// Assume CO2 Level is the default Atmospheric Level (~400ppm) float getR0(); + float getCorrectedR0(float temparature, float humidity); /// Get R0 in custom conditions for calibration purposes. /// Can be used, if you know the current CO2 Level. double getR0ByCO2Level(float ppm); + double getCorrectedR0ByCO2Level(float ppm, float temparature, float humidity); /// Set R0 Value for calibration. void setR0(float r0); - + /// Gets the resolved sensor voltage double getVoltage(); + + /// Calculate Correction Factor depending on temparature and humidity + double getCorrectionFactor(float temparature, float humidity); + /// Calculates the Resistance of the Sensor double getResistance(); + double getCorrectedResistance(float temparature, float humidity); /// Calculates ppm on a exponential curve /// (Different Gases have different curves) double getPPM(float a, float b); + double getCorrectedPPM(float a, float b, float temparature, float humidity); /// Calculates ppm on a linear curve /// (Different Gases have different curves) double getPPMLinear(float a, float b); /// Gets ppm of Acetona in Air (C3H6O) double getAcetona(); + double getCorrectedAcetona(float temparature, float humidity); /// Gets ppm of Alcohol in Air double getAlcohol(); + double getCorrectedAlcohol(float temparature, float humidity); /// Gets ppm of CO in Air double getCO(); + double getCorrectedCO(float temparature, float humidit); /// Gets ppm of CO2 in Air double getCO2(); + double getCorrectedCO2(float temparature, float humidit); /// Gets ppm of NH4 in Air double getNH4(); + double getCorrectedNH4(float temparature, float humidit); /// Gets ppm of Tolueno in Air (CH3) double getTolueno(); + double getCorrectedTolueno(float temparature, float humidit); }; #endif