mirror of
https://github.com/amperka/TroykaMQ.git
synced 2025-03-15 04:27:34 +03:00
update library
This commit is contained in:
parent
61dc0f9349
commit
4c7567255b
113
BaseMQ.cpp
113
BaseMQ.cpp
@ -1,113 +0,0 @@
|
|||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
BaseMQ::BaseMQ(uint8_t pin) :
|
|
||||||
_pin (pin) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseMQ::BaseMQ(uint8_t pin, uint8_t pinHeater) :
|
|
||||||
_pin (pin),
|
|
||||||
_pinHeater (pinHeater)
|
|
||||||
{
|
|
||||||
pinMode(_pinHeater, OUTPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// калибровка датчика
|
|
||||||
void BaseMQ::calibrate(float ro) {
|
|
||||||
_ro = ro;
|
|
||||||
_stateCalibrate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// калибровка датчика
|
|
||||||
void BaseMQ::calibrate() {
|
|
||||||
float ro = 0;
|
|
||||||
for (int i = 0; i < MQ_SAMPLE_TIMES; i++) {
|
|
||||||
ro += calculateResistance(analogRead(_pin));
|
|
||||||
delay(MQ_SAMPLE_INTERVAL);
|
|
||||||
}
|
|
||||||
ro = ro/MQ_SAMPLE_TIMES;
|
|
||||||
ro = ro/getRoInCleanAir();
|
|
||||||
calibrate (ro);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseMQ::heaterPwrHigh() {
|
|
||||||
digitalWrite(_pinHeater, HIGH);
|
|
||||||
_heater = true;
|
|
||||||
_prMillis = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseMQ::heaterPwrLow() {
|
|
||||||
analogWrite(_pinHeater, 75);
|
|
||||||
_heater = true;
|
|
||||||
_cooler = true;
|
|
||||||
_prMillis = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseMQ::heaterPwrOff() {
|
|
||||||
digitalWrite(_pinHeater, LOW);
|
|
||||||
_heater = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// сопротивление датчика
|
|
||||||
float BaseMQ::calculateResistance(int rawAdc) const {
|
|
||||||
float vrl = rawAdc*(5.0 / 1023);
|
|
||||||
float rsAir = (5.0 - vrl)/vrl*getRL();
|
|
||||||
return rsAir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// считывание датчика
|
|
||||||
float BaseMQ::readRs() const {
|
|
||||||
float rs = 0;
|
|
||||||
for (int i = 0; i < MQ_SAMPLE_TIMES; i++) {
|
|
||||||
rs += calculateResistance(analogRead(_pin));
|
|
||||||
delay(MQ_SAMPLE_INTERVAL);
|
|
||||||
}
|
|
||||||
rs = rs/MQ_SAMPLE_TIMES;
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long BaseMQ::readScaled(float a, float b) const {
|
|
||||||
float ratio = readRatio();
|
|
||||||
return exp((log(ratio)-b)/a);
|
|
||||||
}
|
|
||||||
|
|
||||||
float BaseMQ::readRatio() const {
|
|
||||||
return readRs()/getRo();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseMQ::heatingCompleted() const {
|
|
||||||
if ((_heater) && (!_cooler) && (millis() - _prMillis > 60000))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseMQ::coolanceCompleted() const {
|
|
||||||
if ((_heater) && (_cooler) && (millis() - _prMillis > 90000))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseMQ::cycleHeat() {
|
|
||||||
_heater = false;
|
|
||||||
_cooler = false;
|
|
||||||
heaterPwrHigh();
|
|
||||||
#ifdef MQDEBUG
|
|
||||||
Serial.println("Heated sensor");
|
|
||||||
#endif //MQDEBUG
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseMQ::atHeatCycleEnd() {
|
|
||||||
if (heatingCompleted()) {
|
|
||||||
heaterPwrLow();
|
|
||||||
#ifdef MQDEBUG
|
|
||||||
Serial.println("Cool sensor");
|
|
||||||
#endif //MQDEBUG
|
|
||||||
return false;
|
|
||||||
} else if (coolanceCompleted()) {
|
|
||||||
heaterPwrOff();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
47
BaseMQ.h
47
BaseMQ.h
@ -1,47 +0,0 @@
|
|||||||
#ifndef BaseMQ_H
|
|
||||||
#define BaseMQ_H
|
|
||||||
#include <Arduino.h>
|
|
||||||
// кол-во считываний значений в цикле
|
|
||||||
#define MQ_SAMPLE_TIMES 5
|
|
||||||
// задержка после каждого считывания датчика
|
|
||||||
#define MQ_SAMPLE_INTERVAL 20
|
|
||||||
|
|
||||||
class BaseMQ {
|
|
||||||
public:
|
|
||||||
BaseMQ(uint8_t pin);
|
|
||||||
BaseMQ(uint8_t pin, uint8_t pinHeater);
|
|
||||||
void calibrate();
|
|
||||||
void calibrate(float ro);
|
|
||||||
void heaterPwrHigh();
|
|
||||||
void heaterPwrLow();
|
|
||||||
void heaterPwrOff();
|
|
||||||
void cycleHeat();
|
|
||||||
bool atHeatCycleEnd();
|
|
||||||
bool heatingCompleted() const;
|
|
||||||
bool coolanceCompleted() const;
|
|
||||||
float readRatio() const;
|
|
||||||
inline bool isCalibrated() const {
|
|
||||||
return _stateCalibrate;
|
|
||||||
};
|
|
||||||
inline float getRo() const {
|
|
||||||
return _ro;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
unsigned long readScaled(float a, float b) const;
|
|
||||||
virtual float getRoInCleanAir() const = 0;
|
|
||||||
virtual int getRL() const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _heater = false;
|
|
||||||
bool _cooler = false;
|
|
||||||
bool _stateCalibrate = false;
|
|
||||||
unsigned long _prMillis = 0;
|
|
||||||
float _ro = 1.0f;
|
|
||||||
uint8_t _pin;
|
|
||||||
uint8_t _pinHeater;
|
|
||||||
float readRs() const;
|
|
||||||
float calculateResistance(int rawAdc) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
21
MQ2.h
21
MQ2.h
@ -1,21 +0,0 @@
|
|||||||
#ifndef MQ2_H_
|
|
||||||
#define MQ2_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ2 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ2(uint8_t pin);
|
|
||||||
MQ2(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readLPG();
|
|
||||||
unsigned long readMethane();
|
|
||||||
unsigned long readSmoke();
|
|
||||||
unsigned long readHydrogen();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 5; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 9.83; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ2_H_
|
|
19
MQ3.h
19
MQ3.h
@ -1,19 +0,0 @@
|
|||||||
#ifndef MQ3_H_
|
|
||||||
#define MQ3_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ3 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ3(uint8_t pin);
|
|
||||||
MQ3(uint8_t pin, uint8_t pinHeater);
|
|
||||||
float readAlcoholMgL();
|
|
||||||
float readAlcoholPpm();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 200; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 60; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ3_H_
|
|
18
MQ4.h
18
MQ4.h
@ -1,18 +0,0 @@
|
|||||||
#ifndef MQ4_H_
|
|
||||||
#define MQ4_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ4 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ4(uint8_t pin);
|
|
||||||
MQ4(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readMethane();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 20; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 4.4; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ4_H_
|
|
19
MQ5.h
19
MQ5.h
@ -1,19 +0,0 @@
|
|||||||
#ifndef MQ5_H_
|
|
||||||
#define MQ5_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ5 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ5(uint8_t pin);
|
|
||||||
MQ5(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readLPG();
|
|
||||||
unsigned long readMethane();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 20; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 6.5; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ5_H_
|
|
18
MQ6.h
18
MQ6.h
@ -1,18 +0,0 @@
|
|||||||
#ifndef MQ6_H_
|
|
||||||
#define MQ6_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ6 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ6(uint8_t pin);
|
|
||||||
MQ6(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readLPG();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 20; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 10; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ6_H_
|
|
18
MQ7.h
18
MQ7.h
@ -1,18 +0,0 @@
|
|||||||
#ifndef MQ7_H_
|
|
||||||
#define MQ7_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ7 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ7(uint8_t pin);
|
|
||||||
MQ7(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readCarbonMonoxide();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 10; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 27; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ7_H_
|
|
18
MQ8.h
18
MQ8.h
@ -1,18 +0,0 @@
|
|||||||
#ifndef MQ8_H_
|
|
||||||
#define MQ8_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ8 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ8(uint8_t pin);
|
|
||||||
MQ8(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readHydrogen();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 10; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 70; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ8_H_
|
|
20
MQ9.h
20
MQ9.h
@ -1,20 +0,0 @@
|
|||||||
#ifndef MQ9_H_
|
|
||||||
#define MQ9_H_
|
|
||||||
|
|
||||||
#include "BaseMQ.h"
|
|
||||||
|
|
||||||
class MQ9 : public BaseMQ {
|
|
||||||
public:
|
|
||||||
MQ9(uint8_t pin);
|
|
||||||
MQ9(uint8_t pin, uint8_t pinHeater);
|
|
||||||
unsigned long readLPG();
|
|
||||||
unsigned long readMethane();
|
|
||||||
unsigned long readCarbonMonoxide();
|
|
||||||
private:
|
|
||||||
// Резистор установленный на плату (кОм)
|
|
||||||
virtual int getRL() const { return 10; }
|
|
||||||
// коефициент чистого воздуха
|
|
||||||
virtual float getRoInCleanAir() const { return 9.8; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MQ9_H_
|
|
13
README.md
13
README.md
@ -25,3 +25,16 @@
|
|||||||
Подробности и примеры работы для [датчика MQ-8](http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq8).
|
Подробности и примеры работы для [датчика MQ-8](http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq8).
|
||||||
|
|
||||||
Подробности и примеры работы для [датчика MQ-9](http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq9).
|
Подробности и примеры работы для [датчика MQ-9](http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq9).
|
||||||
|
|
||||||
|
В библиотеки используются коэффициенты для поиска значений в ppm для каждого газа, которые были найдены путём линейной и логарифмической аппроксимации графика из даташита.
|
||||||
|
|
||||||
|
Скачать исходники:
|
||||||
|
[MQ-2](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq2:mq2_graph_factors.zip),
|
||||||
|
[MQ-3](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq3:mq3_graph_factors.zip),
|
||||||
|
[MQ-4](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq4:mq4_graph_factors.zip),
|
||||||
|
[MQ-5](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq5:mq5_graph_factors.zip),
|
||||||
|
[MQ-6](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq6:mq6_graph_factors.zip),
|
||||||
|
[MQ-7](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq7:mq7_graph_factors.zip),
|
||||||
|
[MQ-8](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq8:mq8_graph_factors.zip),
|
||||||
|
[MQ-9](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq9:mq9_graph_factors.zip),
|
||||||
|
[MQ-135](http://wiki.amperka.ru/_media/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:mq135:mq135_graph_factors.zip)
|
13
TroykaMQ.h
13
TroykaMQ.h
@ -1,13 +0,0 @@
|
|||||||
#ifndef TROYKAMQ_H_
|
|
||||||
#define TROYKAMQ_H_
|
|
||||||
|
|
||||||
#include "MQ2.h"
|
|
||||||
#include "MQ3.h"
|
|
||||||
#include "MQ4.h"
|
|
||||||
#include "MQ5.h"
|
|
||||||
#include "MQ6.h"
|
|
||||||
#include "MQ7.h"
|
|
||||||
#include "MQ8.h"
|
|
||||||
#include "MQ9.h"
|
|
||||||
|
|
||||||
#endif // TROYKAMQ_H_
|
|
36
examples/mq135/mq135/mq135.ino
Normal file
36
examples/mq135/mq135/mq135.ino
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// библиотека для работы с датчиками MQ (Troyka-модуль)
|
||||||
|
#include <TroykaMQ.h>
|
||||||
|
|
||||||
|
// имя для пина, к которому подключен датчик
|
||||||
|
#define PIN_MQ135 A0
|
||||||
|
// создаём объект для работы с датчиком и передаём ему номер пина
|
||||||
|
MQ135 mq135(PIN_MQ135);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// открываем последовательный порт
|
||||||
|
Serial.begin(9600);
|
||||||
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
|
mq135.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 160
|
||||||
|
// mq135.calibrate(160);
|
||||||
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
|
Serial.print("Ro = ");
|
||||||
|
Serial.println(mq135.getRo());
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// выводим отношения текущего сопротивление датчика
|
||||||
|
// к сопротивлению датчика в чистом воздухе (Rs/Ro)
|
||||||
|
Serial.print("Ratio: ");
|
||||||
|
Serial.print(mq135.readRatio());
|
||||||
|
// выводим значения газов в ppm
|
||||||
|
Serial.print("\tCO2: ");
|
||||||
|
Serial.print(mq135.readCO2());
|
||||||
|
Serial.println(" ppm");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
49
examples/mq135/mq135Heater/mq135Heater.ino
Normal file
49
examples/mq135/mq135Heater/mq135Heater.ino
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// библиотека для работы с датчиками MQ (Troyka-модуль)
|
||||||
|
#include <TroykaMQ.h>
|
||||||
|
|
||||||
|
// имя для пина, к которому подключен датчик
|
||||||
|
#define PIN_MQ135 A0
|
||||||
|
// имя для пина, к которому подключен нагреватель датчика
|
||||||
|
#define PIN_MQ135_HEATER 11
|
||||||
|
|
||||||
|
// создаём объект для работы с датчиком
|
||||||
|
// и передаём ему номер пина выходного сигнала и нагревателя
|
||||||
|
MQ135 mq135(PIN_MQ135);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// открываем последовательный порт
|
||||||
|
Serial.begin(9600);
|
||||||
|
// включаем нагреватель
|
||||||
|
mq135.heaterPwrHigh();
|
||||||
|
Serial.println("Heated sensor");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// если прошёл интервал нагрева датчика
|
||||||
|
// и калибровка не была совершена
|
||||||
|
if (!mq135.isCalibrated() && mq135.heatingCompleted()) {
|
||||||
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
|
mq135.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 160
|
||||||
|
// mq135.calibrate(160);
|
||||||
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
|
Serial.print("Ro = ");
|
||||||
|
Serial.println(mq135.getRo());
|
||||||
|
}
|
||||||
|
// если прошёл интевал нагрева датчика
|
||||||
|
// и калибровка была совершена
|
||||||
|
if (mq135.isCalibrated() && mq135.heatingCompleted()) {
|
||||||
|
// выводим отношения текущего сопротивление датчика
|
||||||
|
// к сопротивлению датчика в чистом воздухе (Rs/Ro)
|
||||||
|
Serial.print("Ratio: ");
|
||||||
|
Serial.print(mq135.readRatio());
|
||||||
|
// выводим значения газов в ppm
|
||||||
|
Serial.print("\tCO2: ");
|
||||||
|
Serial.print(mq135.readCO2());
|
||||||
|
Serial.println(" ppm");
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq2.calibrate();
|
mq2.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 3.2
|
||||||
|
// mq2.calibrate(3.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq2.getRo());
|
Serial.println(mq2.getRo());
|
||||||
@ -25,16 +28,16 @@ void loop()
|
|||||||
Serial.print("Ratio: ");
|
Serial.print("Ratio: ");
|
||||||
Serial.print(mq2.readRatio());
|
Serial.print(mq2.readRatio());
|
||||||
// выводим значения газов в ppm
|
// выводим значения газов в ppm
|
||||||
Serial.print("LPG: ");
|
Serial.print("\tLPG: ");
|
||||||
Serial.print(mq2.readLPG());
|
Serial.print(mq2.readLPG());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Methane: ");
|
Serial.print("\tMethane: ");
|
||||||
Serial.print(mq2.readMethane());
|
Serial.print(mq2.readMethane());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Smoke: ");
|
Serial.print("\tSmoke: ");
|
||||||
Serial.print(mq2.readSmoke());
|
Serial.print(mq2.readSmoke());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Hydrogen: ");
|
Serial.print("\tHydrogen: ");
|
||||||
Serial.print(mq2.readHydrogen());
|
Serial.print(mq2.readHydrogen());
|
||||||
Serial.println(" ppm");
|
Serial.println(" ppm");
|
||||||
delay(100);
|
delay(100);
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq2.isCalibrated() && mq2.heatingCompleted()) {
|
if (!mq2.isCalibrated() && mq2.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq2.calibrate();
|
mq2.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 3.2
|
||||||
|
// mq2.calibrate(3.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq2.getRo());
|
Serial.println(mq2.getRo());
|
||||||
@ -38,16 +41,16 @@ void loop()
|
|||||||
Serial.print("Ratio: ");
|
Serial.print("Ratio: ");
|
||||||
Serial.print(mq2.readRatio());
|
Serial.print(mq2.readRatio());
|
||||||
// выводим значения газов в ppm
|
// выводим значения газов в ppm
|
||||||
Serial.print("LPG: ");
|
Serial.print("\tLPG: ");
|
||||||
Serial.print(mq2.readLPG());
|
Serial.print(mq2.readLPG());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Methane: ");
|
Serial.print("\tMethane: ");
|
||||||
Serial.print(mq2.readMethane());
|
Serial.print(mq2.readMethane());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Smoke: ");
|
Serial.print("\tSmoke: ");
|
||||||
Serial.print(mq2.readSmoke());
|
Serial.print(mq2.readSmoke());
|
||||||
Serial.print(" ppm");
|
Serial.print(" ppm");
|
||||||
Serial.print(" Hydrogen: ");
|
Serial.print("\tHydrogen: ");
|
||||||
Serial.print(mq2.readHydrogen());
|
Serial.print(mq2.readHydrogen());
|
||||||
Serial.println(" ppm");
|
Serial.println(" ppm");
|
||||||
delay(100);
|
delay(100);
|
||||||
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq3.calibrate();
|
mq3.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 6.3
|
||||||
|
// mq3.calibrate(6.3);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq3.getRo());
|
Serial.println(mq3.getRo());
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq3.isCalibrated() && mq3.heatingCompleted()) {
|
if (!mq3.isCalibrated() && mq3.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq3.calibrate();
|
mq3.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 6.3
|
||||||
|
// mq3.calibrate(6.3);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq3.getRo());
|
Serial.println(mq3.getRo());
|
||||||
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq4.calibrate();
|
mq4.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 7.1
|
||||||
|
// mq4.calibrate(7.1);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq4.getRo());
|
Serial.println(mq4.getRo());
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq4.isCalibrated() && mq4.heatingCompleted()) {
|
if (!mq4.isCalibrated() && mq4.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq4.calibrate();
|
mq4.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 7.1
|
||||||
|
// mq4.calibrate(7.1);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq4.getRo());
|
Serial.println(mq4.getRo());
|
||||||
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq5.calibrate();
|
mq5.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 4.7
|
||||||
|
// mq5.calibrate(4.7);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq5.getRo());
|
Serial.println(mq5.getRo());
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq5.isCalibrated() && mq5.heatingCompleted()) {
|
if (!mq5.isCalibrated() && mq5.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq5.calibrate();
|
mq5.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 4.7
|
||||||
|
// mq5.calibrate(4.7);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq5.getRo());
|
Serial.println(mq5.getRo());
|
||||||
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq6.calibrate();
|
mq6.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 8.2
|
||||||
|
// mq6.calibrate(8.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq6.getRo());
|
Serial.println(mq6.getRo());
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq6.isCalibrated() && mq6.heatingCompleted()) {
|
if (!mq6.isCalibrated() && mq6.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq6.calibrate();
|
mq6.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 8.2
|
||||||
|
// mq6.calibrate(8.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq6.getRo());
|
Serial.println(mq6.getRo());
|
||||||
|
@ -27,6 +27,9 @@ void loop()
|
|||||||
if (!mq7.isCalibrated() && mq7.atHeatCycleEnd()) {
|
if (!mq7.isCalibrated() && mq7.atHeatCycleEnd()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq7.calibrate();
|
mq7.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 7.2
|
||||||
|
// mq7.calibrate(7.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq7.getRo());
|
Serial.println(mq7.getRo());
|
||||||
|
@ -13,6 +13,9 @@ void setup()
|
|||||||
// перед калибровкой датчика прогрейте его 60 секунд
|
// перед калибровкой датчика прогрейте его 60 секунд
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq8.calibrate();
|
mq8.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 6.1
|
||||||
|
// mq8.calibrate(6.1);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq8.getRo());
|
Serial.println(mq8.getRo());
|
||||||
|
@ -26,6 +26,9 @@ void loop()
|
|||||||
if (!mq8.isCalibrated() && mq8.heatingCompleted()) {
|
if (!mq8.isCalibrated() && mq8.heatingCompleted()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq8.calibrate();
|
mq8.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 6.1
|
||||||
|
// mq8.calibrate(6.1);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq8.getRo());
|
Serial.println(mq8.getRo());
|
||||||
|
@ -27,6 +27,9 @@ void loop()
|
|||||||
if (!mq9.isCalibrated() && mq9.atHeatCycleEnd()) {
|
if (!mq9.isCalibrated() && mq9.atHeatCycleEnd()) {
|
||||||
// выполняем калибровку датчика на чистом воздухе
|
// выполняем калибровку датчика на чистом воздухе
|
||||||
mq9.calibrate();
|
mq9.calibrate();
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
// можно его указать вручную, допустим 7.2
|
||||||
|
// mq9.calibrate(7.2);
|
||||||
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
// выводим сопротивление датчика в чистом воздухе (Ro) в serial-порт
|
||||||
Serial.print("Ro = ");
|
Serial.print("Ro = ");
|
||||||
Serial.println(mq9.getRo());
|
Serial.println(mq9.getRo());
|
||||||
|
40
keywords.txt
Normal file
40
keywords.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map TroykaMQ
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
MQ2 KEYWORD1 MQ2
|
||||||
|
MQ3 KEYWORD1 MQ3
|
||||||
|
MQ4 KEYWORD1 MQ4
|
||||||
|
MQ5 KEYWORD1 MQ5
|
||||||
|
MQ6 KEYWORD1 MQ6
|
||||||
|
MQ7 KEYWORD1 MQ7
|
||||||
|
MQ8 KEYWORD1 MQ8
|
||||||
|
MQ9 KEYWORD1 MQ9
|
||||||
|
MQ135 KEYWORD1 MQ135
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
calibrate KEYWORD2
|
||||||
|
heaterPwrHigh KEYWORD2
|
||||||
|
heaterPwrLow KEYWORD2
|
||||||
|
heaterPwrOff KEYWORD2
|
||||||
|
cycleHeat KEYWORD2
|
||||||
|
atHeatCycleEnd KEYWORD2
|
||||||
|
heatingCompleted KEYWORD2
|
||||||
|
coolanceCompleted KEYWORD2
|
||||||
|
readRatio KEYWORD2
|
||||||
|
isCalibrated KEYWORD2
|
||||||
|
getRo KEYWORD2
|
||||||
|
readLPG KEYWORD2
|
||||||
|
readMethane KEYWORD2
|
||||||
|
readSmoke KEYWORD2
|
||||||
|
readHydrogen KEYWORD2
|
||||||
|
readAlcoholMgL KEYWORD2
|
||||||
|
readAlcoholPpm KEYWORD2
|
||||||
|
readCarbonMonoxide KEYWORD2
|
||||||
|
readCO2 KEYWORD2
|
9
library.properties
Normal file
9
library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=TroykaMQ
|
||||||
|
version=1.1
|
||||||
|
author=Igor Dementiev, Amperka
|
||||||
|
maintainer=Amperka <amperka.ru>
|
||||||
|
sentence=Allows to read data from gas sensors of the MQx series in ppm.
|
||||||
|
paragraph=This library reads data from the MQx series sensors and displays the readings in ppm. Before reading the indicators, the sensor must be calibrated in clean air.
|
||||||
|
category=Sensors
|
||||||
|
url=https://github.com/amperka/TroykaMQ
|
||||||
|
architectures=*
|
122
src/BaseMQ.cpp
Normal file
122
src/BaseMQ.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/****************************************************************************/
|
||||||
|
// Function: cpp file for BaseMQ
|
||||||
|
// Hardware: MQ2, MQ3, MQ4, MQ5, MQ6, MQ7, MQ8, MQ9, MQ135
|
||||||
|
// Arduino IDE: Arduino 1.8.3
|
||||||
|
// Author: Igor Dementiev
|
||||||
|
// Date: Jan 19, 2018
|
||||||
|
// Version: v1.1
|
||||||
|
// by www.amperka.ru
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
BaseMQ::BaseMQ(uint8_t pin) {
|
||||||
|
_pin = pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseMQ::BaseMQ(uint8_t pin, uint8_t pinHeater) {
|
||||||
|
_pin = pin;
|
||||||
|
_pinHeater = pinHeater;
|
||||||
|
pinMode(_pinHeater, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// фиксированая калибровка датчика
|
||||||
|
// при знании сопративления датчика на чистом воздухе
|
||||||
|
void BaseMQ::calibrate(float ro) {
|
||||||
|
_ro = ro;
|
||||||
|
_stateCalibrate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// калибровка датчика
|
||||||
|
// считывания показаний сопративление датчика на чистом воздухе
|
||||||
|
// далее фиксированая калибровка датчика
|
||||||
|
void BaseMQ::calibrate() {
|
||||||
|
float rs = readRs();
|
||||||
|
float ro = rs / getRoInCleanAir();
|
||||||
|
calibrate(ro);
|
||||||
|
}
|
||||||
|
|
||||||
|
// включение нагревателя на 100%
|
||||||
|
void BaseMQ::heaterPwrHigh() {
|
||||||
|
digitalWrite(_pinHeater, HIGH);
|
||||||
|
_heater = true;
|
||||||
|
_prMillis = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// включение нагревателья на 20%
|
||||||
|
void BaseMQ::heaterPwrLow() {
|
||||||
|
analogWrite(_pinHeater, 75);
|
||||||
|
_heater = true;
|
||||||
|
_cooler = true;
|
||||||
|
_prMillis = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// выключение нагревателя
|
||||||
|
void BaseMQ::heaterPwrOff() {
|
||||||
|
digitalWrite(_pinHeater, LOW);
|
||||||
|
_heater = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// циклическое считывание сопративления датчика
|
||||||
|
float BaseMQ::readRs() const {
|
||||||
|
float rs = 0;
|
||||||
|
for (int i = 0; i < MQ_SAMPLE_TIMES; i++) {
|
||||||
|
rs += calculateResistance(analogRead(_pin));
|
||||||
|
delay(MQ_SAMPLE_INTERVAL);
|
||||||
|
}
|
||||||
|
rs = rs / MQ_SAMPLE_TIMES;
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// сопротивление датчика
|
||||||
|
float BaseMQ::calculateResistance(int sensorADC) const {
|
||||||
|
float sensorVoltage = sensorADC * (OPERATING_VOLTAGE / ADC_VALUE_MAX);
|
||||||
|
float sensorResistance = (OPERATING_VOLTAGE - sensorVoltage) / sensorVoltage * getRL();
|
||||||
|
return sensorResistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BaseMQ::readScaled(float a, float b) const {
|
||||||
|
float ratio = readRatio();
|
||||||
|
return exp((log(ratio) - b) / a);
|
||||||
|
}
|
||||||
|
|
||||||
|
float BaseMQ::readRatio() const {
|
||||||
|
return readRs() / getRo();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseMQ::heatingCompleted() const {
|
||||||
|
if ((_heater) && (!_cooler) && (millis() - _prMillis > MQ_HEATING_TIME)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseMQ::coolanceCompleted() const {
|
||||||
|
if ((_heater) && (_cooler) && (millis() - _prMillis > MQ_COOLANCE_TIME)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseMQ::cycleHeat() {
|
||||||
|
_heater = false;
|
||||||
|
_cooler = false;
|
||||||
|
heaterPwrHigh();
|
||||||
|
// Serial.println("Heated sensor");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseMQ::atHeatCycleEnd() {
|
||||||
|
if (heatingCompleted()) {
|
||||||
|
heaterPwrLow();
|
||||||
|
// Serial.println("Cool sensor");
|
||||||
|
return false;
|
||||||
|
} else if (coolanceCompleted()) {
|
||||||
|
heaterPwrOff();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
72
src/BaseMQ.h
Normal file
72
src/BaseMQ.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************/
|
||||||
|
// Function: Header file for BaseMQ
|
||||||
|
// Hardware: MQ2, MQ3, MQ4, MQ5, MQ6, MQ7, MQ8, MQ9, MQ135
|
||||||
|
// Arduino IDE: Arduino 1.8.3
|
||||||
|
// Author: Igor Dementiev
|
||||||
|
// Date: Jan 19, 2018
|
||||||
|
// Version: v1.1
|
||||||
|
// by www.amperka.ru
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef BaseMQ_H
|
||||||
|
#define BaseMQ_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
// кол-во считываний значений в цикле
|
||||||
|
#define MQ_SAMPLE_TIMES 5
|
||||||
|
// задержка после каждого считывания датчика
|
||||||
|
#define MQ_SAMPLE_INTERVAL 20
|
||||||
|
// время нагрева датчика
|
||||||
|
#define MQ_HEATING_TIME 6000
|
||||||
|
// время охлаждение датчика
|
||||||
|
#define MQ_COOLANCE_TIME 9000
|
||||||
|
// разрядность АЦП
|
||||||
|
#define ADC_BIT 10
|
||||||
|
// масимальное значение АЦП
|
||||||
|
#define ADC_VALUE_MAX pow(2, ADC_BIT)
|
||||||
|
|
||||||
|
#if defined(__AVR__)
|
||||||
|
#define OPERATING_VOLTAGE 5.0
|
||||||
|
|
||||||
|
#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__) || defined(__SAMD21G18A__)
|
||||||
|
#define OPERATING_VOLTAGE 3.3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class BaseMQ {
|
||||||
|
public:
|
||||||
|
BaseMQ(uint8_t pin);
|
||||||
|
BaseMQ(uint8_t pin, uint8_t pinHeater);
|
||||||
|
void calibrate();
|
||||||
|
void calibrate(float ro);
|
||||||
|
void heaterPwrHigh();
|
||||||
|
void heaterPwrLow();
|
||||||
|
void heaterPwrOff();
|
||||||
|
void cycleHeat();
|
||||||
|
bool atHeatCycleEnd();
|
||||||
|
bool heatingCompleted() const;
|
||||||
|
bool coolanceCompleted() const;
|
||||||
|
float readRatio() const;
|
||||||
|
inline bool isCalibrated() const {
|
||||||
|
return _stateCalibrate;
|
||||||
|
};
|
||||||
|
inline float getRo() const {
|
||||||
|
return _ro;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float readScaled(float a, float b) const;
|
||||||
|
virtual float getRoInCleanAir() const = 0;
|
||||||
|
virtual int getRL() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _heater = false;
|
||||||
|
bool _cooler = false;
|
||||||
|
bool _stateCalibrate = false;
|
||||||
|
unsigned long _prMillis = 0;
|
||||||
|
float _ro = 1.0f;
|
||||||
|
uint8_t _pin;
|
||||||
|
uint8_t _pinHeater;
|
||||||
|
float readRs() const;
|
||||||
|
float calculateResistance(int sensorADC) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
13
src/MQ135.cpp
Normal file
13
src/MQ135.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "MQ135.h"
|
||||||
|
|
||||||
|
MQ135::MQ135(uint8_t pin)
|
||||||
|
: BaseMQ(pin) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MQ135::MQ135(uint8_t pin, uint8_t pinHeater)
|
||||||
|
: BaseMQ(pin, pinHeater) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long MQ135::readCO2() {
|
||||||
|
return readScaled(-0.42 , 1.92);
|
||||||
|
}
|
26
src/MQ135.h
Normal file
26
src/MQ135.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef MQ135_H_
|
||||||
|
#define MQ135_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ135_RL_BOARD 10
|
||||||
|
|
||||||
|
// концентрация углекислого газа в сухом воздухе
|
||||||
|
#define PPM_CO2_IN_CLEAR_AIR 397.13
|
||||||
|
|
||||||
|
class MQ135 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ135(uint8_t pin);
|
||||||
|
MQ135(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readCO2();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const {
|
||||||
|
return MQ135_RL_BOARD;
|
||||||
|
}
|
||||||
|
virtual float getRoInCleanAir() const {
|
||||||
|
return exp((log(PPM_CO2_IN_CLEAR_AIR) * -0.42) + 1.92);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ135_H_
|
24
src/MQ2.h
Normal file
24
src/MQ2.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef MQ2_H_
|
||||||
|
#define MQ2_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ2_RL_BOARD 5
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ2_RO_IN_CLEAR_AIR 9.83
|
||||||
|
|
||||||
|
class MQ2 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ2(uint8_t pin);
|
||||||
|
MQ2(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readLPG();
|
||||||
|
unsigned long readMethane();
|
||||||
|
unsigned long readSmoke();
|
||||||
|
unsigned long readHydrogen();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ2_RL_BOARD; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ2_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ2_H_
|
22
src/MQ3.h
Normal file
22
src/MQ3.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef MQ3_H_
|
||||||
|
#define MQ3_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ3_RL_BOARD 200
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ3_RO_IN_CLEAR_AIR 60
|
||||||
|
|
||||||
|
class MQ3 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ3(uint8_t pin);
|
||||||
|
MQ3(uint8_t pin, uint8_t pinHeater);
|
||||||
|
float readAlcoholMgL();
|
||||||
|
float readAlcoholPpm();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ3_RL_BOARD; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ3_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ3_H_
|
21
src/MQ4.h
Normal file
21
src/MQ4.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MQ4_H_
|
||||||
|
#define MQ4_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ4_RL_BOARD 20
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ4_RO_IN_CLEAR_AIR 4.4
|
||||||
|
|
||||||
|
class MQ4 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ4(uint8_t pin);
|
||||||
|
MQ4(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readMethane();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ4_RL_BOARD ; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ4_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ4_H_
|
22
src/MQ5.h
Normal file
22
src/MQ5.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef MQ5_H_
|
||||||
|
#define MQ5_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ5_RL_BOARD 20
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ5_RO_IN_CLEAR_AIR 6.5
|
||||||
|
|
||||||
|
class MQ5 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ5(uint8_t pin);
|
||||||
|
MQ5(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readLPG();
|
||||||
|
unsigned long readMethane();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ5_RL_BOARD; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ5_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ5_H_
|
21
src/MQ6.h
Normal file
21
src/MQ6.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MQ6_H_
|
||||||
|
#define MQ6_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ6_RL_BOARD 20
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ6_RO_IN_CLEAR_AIR 10
|
||||||
|
|
||||||
|
class MQ6 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ6(uint8_t pin);
|
||||||
|
MQ6(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readLPG();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ6_RL_BOARD ; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ6_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ6_H_
|
21
src/MQ7.h
Normal file
21
src/MQ7.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MQ7_H_
|
||||||
|
#define MQ7_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ7_RL_BOARD 10
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ7_RO_IN_CLEAR_AIR 27
|
||||||
|
|
||||||
|
class MQ7 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ7(uint8_t pin);
|
||||||
|
MQ7(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readCarbonMonoxide();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ7_RL_BOARD; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ7_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ7_H_
|
21
src/MQ8.h
Normal file
21
src/MQ8.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MQ8_H_
|
||||||
|
#define MQ8_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ8_RL_BOARD 10
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ8_RO_IN_CLEAR_AIR 27
|
||||||
|
|
||||||
|
class MQ8 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ8(uint8_t pin);
|
||||||
|
MQ8(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readHydrogen();
|
||||||
|
private:
|
||||||
|
virtual int getRL() const { return MQ8_RL_BOARD; }
|
||||||
|
virtual float getRoInCleanAir() const { return MQ8_RO_IN_CLEAR_AIR ; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ8_H_
|
25
src/MQ9.h
Normal file
25
src/MQ9.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef MQ9_H_
|
||||||
|
#define MQ9_H_
|
||||||
|
|
||||||
|
#include "BaseMQ.h"
|
||||||
|
|
||||||
|
// резистор установленный на плату (кОм)
|
||||||
|
#define MQ9_RL_BOARD 10
|
||||||
|
// коефициент чистого воздуха из графика
|
||||||
|
#define MQ9_RO_IN_CLEAR_AIR 9.8
|
||||||
|
|
||||||
|
class MQ9 : public BaseMQ {
|
||||||
|
public:
|
||||||
|
MQ9(uint8_t pin);
|
||||||
|
MQ9(uint8_t pin, uint8_t pinHeater);
|
||||||
|
unsigned long readLPG();
|
||||||
|
unsigned long readMethane();
|
||||||
|
unsigned long readCarbonMonoxide();
|
||||||
|
private:
|
||||||
|
// Резистор установленный на плату (кОм)
|
||||||
|
virtual int getRL() const { return MQ9_RL_BOARD; }
|
||||||
|
// коефициент чистого воздуха
|
||||||
|
virtual float getRoInCleanAir() const { return MQ9_RO_IN_CLEAR_AIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MQ9_H_
|
23
src/TroykaMQ.h
Normal file
23
src/TroykaMQ.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/****************************************************************************/
|
||||||
|
// Function: Header file for TroykaMQ
|
||||||
|
// Hardware: MQ2, MQ3, MQ4, MQ5, MQ6, MQ7, MQ8, MQ9, MQ135
|
||||||
|
// Arduino IDE: Arduino 1.8.3
|
||||||
|
// Author: Igor Dementiev
|
||||||
|
// Date: Jan 19, 2018
|
||||||
|
// Version: v1.1
|
||||||
|
// by www.amperka.ru
|
||||||
|
/****************************************************************************/
|
||||||
|
#ifndef TROYKAMQ_H_
|
||||||
|
#define TROYKAMQ_H_
|
||||||
|
|
||||||
|
#include "MQ2.h"
|
||||||
|
#include "MQ3.h"
|
||||||
|
#include "MQ4.h"
|
||||||
|
#include "MQ5.h"
|
||||||
|
#include "MQ6.h"
|
||||||
|
#include "MQ7.h"
|
||||||
|
#include "MQ8.h"
|
||||||
|
#include "MQ9.h"
|
||||||
|
#include "MQ135.h"
|
||||||
|
|
||||||
|
#endif // TROYKAMQ_H_
|
Loading…
x
Reference in New Issue
Block a user