From b57b22fdea226576c734f9a3344d1c39e4d91d74 Mon Sep 17 00:00:00 2001 From: GrafZeppelin Date: Mon, 5 Apr 2021 16:10:16 +0200 Subject: [PATCH] init --- MQ135.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ MQ135.h | 66 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 MQ135.cpp create mode 100644 MQ135.h diff --git a/MQ135.cpp b/MQ135.cpp new file mode 100644 index 0000000..ef235f7 --- /dev/null +++ b/MQ135.cpp @@ -0,0 +1,83 @@ +#include "MQ135.h" + +MQ135::MQ135(uint8_t pin) { + this->pin = pin; + pinMode(pin, INPUT); +} + +double MQ135::getVoltage() { + return (double)analogRead(pin) * VStep; +} + +double MQ135::getResistance() { + double voltage = getVoltage(); + double rs = ((VIn * RL) / voltage) - RL; + if (rs < 0) { + rs = 0; + } + return rs; +} + +double MQ135::getPPM(float a, float b) { + double ratio = getResistance() / 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; + double ppm = pow(10, ppm_log); + if (ppm < 0) { + ppm = 0; + } + return ppm; +} + +double MQ135::getAcetona() { + return getPPM(34.668, -3.369); +} + +double MQ135::getAlcohol() { + return getPPM(77.255, -3.18); +} + +double MQ135::getCO2() { + // return getPPMLinear(-0.3525, 0.7142) + ATMOCO2; + return getPPM(110.47, -2.862) + ATMOCO2; +} + +double MQ135::getCO() { + return getPPM(605.18, -3.937); +} + +double MQ135::getNH4() { + return getPPM(102.2, -2.473); +} + +double MQ135::getTolueno() { + return getPPM(44.947, -3.445); +} + +float MQ135::getR0() { + double r0 = getResistance() / 3.6; + return r0; +} + +double MQ135::getR0ByCO2Level(float ppm) { + if (ppm > ATMOCO2) { + ppm -= ATMOCO2; + } + else { + return NAN; + } + double tmp = -(log10(ppm / 110.47) / -2.862) + log10(getResistance()); + return pow(10, tmp); +} + +void MQ135::setR0(float r0) { + R0 = r0; +} diff --git a/MQ135.h b/MQ135.h new file mode 100644 index 0000000..4f3d0fe --- /dev/null +++ b/MQ135.h @@ -0,0 +1,66 @@ +#ifndef MQ135New_H +#define MQ135New_H + +#include "Arduino.h" + +/// Resistor on Sensor in kΩ +#define RL 10 + +/// Voltage on Sensor in V +#define VIn 5 + +/// Board analog Input Resolution +/// Default: 2^10 +#define Resolution 1024 + +/// CO2 Level in Atmosphere +#define ATMOCO2 397.13 + +/// Helper to calculate Voltage from Input +/// Voltage = input * Vin / (Resolution - 1) +const double VStep = (double)VIn / (Resolution - 1); + +class MQ135 { + private: + /// input pin + uint8_t pin; + /// calibration Resistance + float R0; + + public: + /// Constructor with analog input Pin + MQ135(uint8_t pin); + /// Get R0 in default conditions for calibration purposes. + /// Assume CO2 Level is the default Atmospheric Level (~400ppm) + float getR0(); + /// Get R0 in custom conditions for calibration purposes. + /// Can be used, if you know the current CO2 Level. + double getR0ByCO2Level(float ppm); + /// Set R0 Value for calibration. + void setR0(float r0); + + /// Gets the resolved sensor voltage + double getVoltage(); + /// Calculates the Resistance of the Sensor + double getResistance(); + /// Calculates ppm on a exponential curve + /// (Different Gases have different curves) + double getPPM(float a, float b); + /// 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(); + /// Gets ppm of Alcohol in Air + double getAlcohol(); + /// Gets ppm of CO in Air + double getCO(); + /// Gets ppm of CO2 in Air + double getCO2(); + /// Gets ppm of NH4 in Air + double getNH4(); + /// Gets ppm of Tolueno in Air (CH3) + double getTolueno(); +}; +#endif