Датчики газа серия MQ (Trema-модуль v2.0). Кое-что о погоде на Марсе или датчик качества воздуха MQ135 Подключение mq 135 к lcd arduino

Один из факторов влияющих на эффективность работы является концентрация CO 2 в воздухе. Для оценки качества воздуха в помещениях есть готовые решения, но нам было интересно разработать свое решение и интегрировать его в используемую систему мониторинга Zabbix .

За основу была взята плата NodeMCU на базе микроконтроллера ESP8266 . Данное решение "из коробки" позволяет подключиться к сети Wi-Fi и организовать прием/передачу данных.

Для определения CO 2 используется недорогое [и не точное] решение - датчик MQ-135 . Данный датчик чувствителен к ряду газов в т.ч. и к CO 2 , библиотека для Arduino IDE содержит в себе функции для пересчета показаний датчика в ppm . Изыскания показали, что вычисляемые значения ppm с реальной концентрацией ничего общего не имеет, соответственно для оценки качества воздуха целесообразно использовать значения на аналоговом выходе модуля MQ-135, которые растут по мере повышения концентрации газов в воздухе. Показания этого датчика чувствительны к питанию, датчик необходимо продержать включенным не менее суток для прокаливания и есть основания предполагать, что выдаваемые значения будут различными для разных экземпляров датчика. Так же показания датчика зависят от температуры и влажности окружающей среды.

Для передачи данных в Zabbix без использования агента используется функция мониторинга веб-страниц, которая позволяет обратиться по заданному URL, получить код ответа и проверить наличие на странице определенного текста. При этом производится замер времени передачи данных и скорость. Единственный простой способ передачи данных от NodeMCU без использования агента на отдельном ПК, это передача значений в коде ответа веб-страницы:

  1. http://ip/ - URL возвращает HTML-страницу с текущими значениями параметров, страница автоматически обновляется с заданным интервалом;
  2. http://ip/a - URL возвращает значение с датчика MQ135;
  3. http://ip/t - URL возвращает значение с датчика DHT11/22;
  4. http://ip/h - URL возвращает значение с датчика DHT11/22.
Код ответа "HTTP/1.1 [значение] OK"
HTTP/1.1 235 OK

Что позволило нам построить графики и поставить триггеры на выход параметров за пределы пороговых.

Подключение MQ135 и DHT-11 к NodeMCU

Изначально стоит определится с питанием. Исходя из информации в Сети и опыта работы MQ135 в силу необходимости нагрева чувствительного элемента потребляет ток до 800 мА, при этом его рабочее напряжение 5 В. NodeMCU работает с напряжением в 3.3 В, использует 3 В логику и выдает максимум 12 мА на пин. Текущая реализация показала, что используемые модули толерантны к логике на 3 В.

Приведенный ниже код основан на примере NodeMCU Server.

Библиотека MQ135 содержит функцию расчета скорректированного значения показаний датчика с поправкой на влажность и температуру. При реальном использовании выяснилось, что при включении увлажнителя в помещении с увеличением влажности росли и показания датчика, что приводило к срабатыванию триггера в Zabbix. Расчет поправочного коэффициента производится по формуле:
k=CORA * t * t - CORB * t + CORC - (h-33.)*CORD , где CORA, CORB, CORC и CORD постоянные, заданные в начале программы.

#include #include #include "DHT.h" #include "Wire.h" #define CORA 0.00035 #define CORB 0.02718 #define CORC 1.39538 #define CORD 0.0018 #define DHTPIN 4 #define DHTTYPE DHT22 #define MQ135APIN A0 #define SOUNDPIN 5 #define LIMIT 360 DHT dht(DHTPIN, DHTTYPE); const char* ssid = "SSID"; const char* password = "PASSWORD"; const boolean debug = 1; float t = 0; float h = 0; float ppmRaw = 0; int timeOut = 0; int count = 0; String header = ""; String footer = ""; String s = ""; WiFiServer server(80); extern "C" { #include "user_interface.h" bool wifi_set_sleep_type(sleep_type_t); sleep_type_t wifi_get_sleep_type(void); } void setup() { pinMode(SOUNDPIN, OUTPUT); if (debug==1) { Serial.begin(115200); delay(10); }; Wire.begin(2, 0); delay(10); dht.begin(); delay(10); if (debug==1) { Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); }; WiFi.mode(WIFI_STA); wifi_set_sleep_type(NONE_SLEEP_T); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); if (debug==1) Serial.print("."); } server.begin(); if (debug==1) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("Server started"); Serial.println(WiFi.localIP()); }; header = "HTTP/1.1 200 OK\r\n"; header = header + "Content-Type: text/html\r\n\r\n"; header = header + " \r\n"; header = header + " \r\n"; header = header + " \r\n"; header = header + " "; header = header + " NodeMCU \r\n"; header = header + " \r\n"; header = header + " \r\n"; footer = " \r\n"; footer = footer + " \r\n"; } void loop() { h = dht.readHumidity(); t = dht.readTemperature(); if (h == 0.00 or isnan(h)) { h = dht.readHumidity(); }; if (t == 0.00 or isnan(t)) { t = dht.readTemperature(); }; ppmRaw = analogRead(MQ135APIN)*(CORA * t * t - CORB * t + CORC - (h-33.)*CORD); if (ppmRaw>LIMIT) { tone(SOUNDPIN, 100, 10); }; if (debug==1) { Serial.print("H: "); Serial.println(h); Serial.print("t: "); Serial.println(t); Serial.print("Air: "); Serial.println(ppmRaw); Serial.println(WiFi.status()); }; WiFiClient client = server.available(); if (!client) { delay(1000); return; }; if (debug == 1) Serial.println("new client"); while(!client.available()){ delay(1); timeOut = timeOut +1; if (timeOut>=15) { // 500 client.stop(); client.flush(); timeOut = 0; return; // break }; } String req = client.readStringUntil("\r"); if (debug==1) { Serial.println(req); } client.flush(); float heap = ESP.getFreeHeap(); if (req.indexOf("/favicon.ico") != -1) { s = "HTTP/1.1 404 Not found\r\n"; client.print(s); } else if (req.indexOf("/t") != -1) { String answer="HTTP/1.1 " + String(t) + " OK\r\n"; client.print(answer); } else if (req.indexOf("/h") != -1) { String answer="HTTP/1.1 " + String(h) + " OK\r\n"; client.print(answer); } else if (req.indexOf("/a") != -1) { String answer="HTTP/1.1 " + String(ppmRaw) + " OK\r\n"; client.print(answer); } else { client.print(header); client.print(t); client.println("°"); if (h "); client.print(h); client.print(""); } else { client.print(h); }; client.println("%"); client.print(" Air "); client.println(ppmRaw); client.println(footer); client.stop(); client.flush(); return; } delay(1); if (debug==1) Serial.println("Client disonnected"); };

7 мая 2017
Версия 0.3 Денис Пак , генеральный директор

Способны определять концентрацию широкого спектра газов в воздухе (природные газы, углекислый и угарный газ, углеводороды, дым, пары спирта и бензина).

  • Аналоговый выход модуля «S» (Signal) - подключается к любому аналоговому входу Arduino и предназначен для снятия показаний модуля.
  • Цифровой вход модуля «EN» (Enable) - подключается к любому выходу Arduino и предназначен для управления режимами работы модуля («1» - активный режим, «0» - режим энергосбережения).
  • Если вход «EN» оставить неподключённым, то модуль будет находиться в активном режиме пока есть питание.

Модуль удобно подключать 3 способами, в зависимости от ситуации:

Способ - 1: Используя проводной шлейф и Piranha UNO

Используя провода «Папа - Мама », подключаем напрямую к контроллеру Piranha UNO.


Способ - 2: Используя Trema Set Shield

Модуль можно подключить к любому из аналоговых входов Trema Set Shield.



Способ - 3: Используя проводной шлейф и Shield

Используя 3-х проводной шлейф, к Trema Shield, Trema-Power Shield, Motor Shield, Trema Shield NANO и тд.



Питание:

Входное напряжение питания 5 В постоянного тока, подаётся на выводы «V» (Vcc) и «G» (GND) модуля.

Подробнее о модуле:

Уровень напряжения на аналоговом выходе «S» (Signal) прямо пропорционален концентрации детектируемых газов. Цифровой вход «EN» (Enable) можно не использовать - тогда модуль будет работать постоянно.

Если подключить вход модуля «EN» к любому выходу Arduino, то модулем можно управлять: логическая «1» подключит нагревательный элемент датчика к шине питания и модуль будет регистрировать концентрацию газов, логический «0» отключит нагревательный элемент и модуль перейдёт в режим энергосбережения.

Примеры:

Пример для Типа подключения 1:

int8_t gasPin = A0; // Определяем номер вывода, к которому подключен модуль void setup() { Serial.begin(9600); // Инициируем передачу данных на скорости 9600 бит/сек pinMode(gasPin, INPUT); // назначаем вывод, к которому подключен датчик, работать в режиме входа } void loop() { Serial.print("Gas volume: "); // выводим текст в монитор порта Serial.println(analogRead(gasPin)); // выводим значение с датчика delay(1000); // ждём секунду }

Пример для Типа подключения 2:

int8_t gasPin = A0; // Определяем номер вывода, к которому подключен модуль int8_t gasPwr = 8; // Определяем номер вывода, к которому подключено управление нагревателя модуля void setup() { Serial.begin(9600); // Инициируем передачу данных на скорости 9600 бит/сек pinMode(gasPin, INPUT); // назначаем вывод, к которому подключен датчик, работать в режиме входа } void loop() { if (analogRead(gasPin) < 550) { // если значение с датчика ниже порога, то digitalWrite(gasPwr, LOW); // выключаем питание с нагревателя и Serial.println("GasPwr OFF"); // выводим текст в монитор порта } else { // если значение с датчика выше порога, то digitalWrite(gasPwr, HIGH); // включаем питание нагревателя, Serial.print("Gas volume: "); // выводим текст в монитор порта Serial.println(analogRead(gasPin)); // выводим значение с датчика } delay(1000); // ждём секунду }

Химический полупроводниковый сенсор - слой чувствительного полупроводника (обычно это оксиды переходных металлов) на инертной подложке, поверхность которого умеет селективно захватывать какие-то летучие вещества из газа. В результате такой хемосорбции полупроводник приобретает заряд и меняет свои свойства: обычно следят за его сопротивлением. Полупроводниковые сенсоры практически всегда требуют нагрева для нормальной работы.

Пару слов о том, зачем мне это понадобилось. Я всегда с тоской вспоминаю походы с палаткой - потому что только там я мог нормально, полноценно спать благодаря совершенно свежему воздуху. Несмотря на то что в Москве я живу в своеобразном зелёном острове, всё равно духота часто мучает меня по ночам. Вообще, эта моя история очень похожа на историю BarsMonster`а с Хабра, который в поисках причин быстрого утомления ставил кислородный концентратор, вешал мощнейшую люстру на 10 тысяч люмен, и делал прочие хаотичные штуки. Я пошёл по его пути, тоже поставил такую люстру, но особой разницы не заметил. В итоге мы оба дошли до идеи измерить концентрацию углекислого газа в воздухе - его избыток вызывает мгновенное закисление крови и нарушение процессов обмена.

Именно для этих измерений я купил в Китае датчик MQ-135.

В нём чувствительный слой из диоксида олова (с золотыми контактными площадками) нанесён на сапфировую подложку с нихромовым нагревателем, и электроды грелки (H-H) вместе с платиновыми электродами от чувствительного слоя (A/B-B/A) выведены наружу. Измерять сопротивление можно на любых двух из них, A-B или B-A.

Он очень дешёвый и доступный, и может служить элементом домашней метеостанции. Помимо углекислого газа, датчик также реагирует на присутствие других газов: угарного газа, аммиака, бензола, оксидов азота и паров спирта. В даташите приведена зависимость относительного сопротивления датчика от парциального давления разных газов - таким образом, из сопротивления можно вычислить концентрацию газа в воздухе.

Кстати, одна из его модификаций, с обострённой чувствительностью к спирту, стоит в полицейских датчиках спирта, которым «дышат в трубку».

Попробуем подключить его к STM32!

Схема подключения

Для начала давайте рассмотрим схему включения.

Всё просто: нагреватель питается от 5 вольт, а чтобы измерить сопротивление сенсора - он включается в состав резистивного делителя, и измеряется напряжение на выходе этого резистора. При известном сопротивлении резистора и напряжении питания сопротивление сенсора рассчитывается как r1 = r2*(u/uout-1).

Конкретно у меня датчик распаян на плате, которая содержит этот дополнительный резистор - она выдаёт наружу сразу нужное напряжение. Чтобы измерить это напряжение с помощью STM32, нам потребуется модуль АЦП. Программа практически повторяет код из той статьи.

Void adc_init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //ADC settings ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_Cmd(ADC1, ENABLE); //Channel settings ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)); } uint16_t getCO2Level() { ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); return ADC_GetConversionValue(ADC1); } int main() { adc_init(); uint16_t co2; while(1) { co2 = getCO2Level(); delay(10000000); } }

Особенности

Во время работы датчик заметно греется, и это его нормальное состояние; вряд ли он способен что-то поджечь, но всё-таки не стоит его ничем накрывать. Да и доступ воздуха ему нужно обеспечить, поэтому просто разместите его на каком-нибудь открытом пространстве. Гемфри Дэви придумал окружать шахтёрские лампы металлической сеткой во избежание взрыва газа - так и здесь, вокруг датчика находится металлическая сетка, благодаря которой сенсор можно использовать даже в помещениях с высокой концентрацией метана или других горючих газов.

Датчик очень медленно выходит на режим. В первый раз его обязательно нужно прогреть не менее 24 часов. При следующих включениях требуется хотя бы 10-минутный прогрев.

Параметры датчика немного деградируют с ростом влажности воздуха. При точных измерениях необходимо следить за влажностью, например с помощью датчика DHT-22.

На моей плате дополнительно размещён ОУ с переменным резистором - к ним подключен светодиод и вывод «DOUT». Это простой настраиваемый пороговый индикатор, светодиод загорится когда концентрация углекислого газа превысит заданное значение.

Post Views: 609

Собственно, нестерпимое желание приобрести именно этот датчик у меня появилось после чтения пламенных . С одной стороны, прибор, конечно, хорош, но стоит на пару порядков дороже MQ135 - а это, как мы знаем, решающий фактор, когда хочется просто поиграться, а потом поставить игрушечку на полку.

К тому же, я решил, что мне вполне достаточно иметь под руками некоторую синтетическую оценку качества воздуха (более-менее соотносящуюся с реальностью), тогда как без абсолютных показателей как-нибудь обойдусь.

Датчик присылают в обычном антистатическом пакетике, который до этих дней не сохранился - да и было бы что сохранять, если уж задуматься. А то, что называют датчиком, здесь на самом деле датчик, размещенный на плате со всей необходимой (и не слишком необходимой) обвязкой.

По поводу необходимой обвязки нам говорит, что достаточно всего одного сопротивления:

На практике же схема выглядит очень похожей на найденную на просторах этого нашего интернета:

Разница, как видите, в том, что нагреватель включен через резистор, вместо подстроечника на выходе - постоянное сопротивление, ну и добавлен операционный усилитель, который, насколько я понял, используется в качестве компаратора. Порог срабатывания компаратора изменяется с помощью подстроечного резистора, а срабатывание при превышении порога (допустимой концентрации регистрируемых газов) отображается свечением зеленого светодиода.

Питается датчик от 5В, потребляет (по документации) менее 800 мВт. При этом надо понимать, что кушает он прилично, и львиная доля потребляемого тока идет на подогрев чувствительного элемента. Температура которого после нескольких часов работы выше предела регистрации бытовым термометром (т.е. больше 42C), на ощупь датчик теплый, но не обжигающий.

Несмотря на невысокую температуру корпуса, датчик прикрыт специальной сеточкой, предназначенной исключать возможность взрыва или возгорания горючих газов. Похожая защита в свое время применялась в шахтерских лампах.

Исходя из вышесказанного понятно, что в автономных системах применять датчик нецелесообразно: будучи постоянно включенным вместе с Arduino Mega, MQ135 этой модификации скушал аккумулятор в 10 Ач (ну, плюс-минус китайских Ач) менее чем за сутки. И, конечно, понятно, что если особенно прижмет сделать «автономку», включаться можно эпизодически - так это пожалуйста, я не запрещаю.

Но ест он все равно много. Измеренный мультиметром потребляемый ток составляет около 130 мА.

Размеры датчика (примерно) (ВхШхГ): 22х20х32 мм. Ноги датчика, как видите, по какой-то причине не обкусаны:

Как эта штуковина работает? Вот честно, я не знаю. Наверное, там какая-то магия и радужные единороги, но в документации почему-то говорится о том, что регистрируемые датчиком газы влияют на сопротивление принудительно подогреваемого измерительного элемента. Который подходит для обнаружения (согласно документации): аммиака (NH3), окисей азота (NOx), алкоголя (не указано какого, можно думать о всех спиртах), бензола, CO2, дыма и, как принято - etc.

Результат выдается в аналоговом виде на пин A0 и в дискретном (после компаратора) - на пин D0.

Отсюда вывод: аналоговый выход датчика подходит для наблюдения динамики качества воздуха, тогда как цифровой (D0) - для оповещения о превышении некоторого порога.

Второй вывод: теоретически для использования датчика не нужны вообще никакие библиотеки. Просто подключаем его, например, к Arduino и читаем состояние аналогового и/или цифрового выхода.

Ну вот хоть так:

#define analogPin A0 // аналоговый выход MQ135 подключен к пину A0 Arduino #define digitalPin 3 // цифровой выход подключен к пину 3 float analogValue; // для аналогового значения byte digitalValue; // для цифрового значения, можно, кстати и boolean, но не суть void setup() { Serial.begin(9600); // инициализация последовательного порта pinMode(analogPin, INPUT); // режим работы аналогового пина pinMode(digitalPin, INPUT); // режим работы цифрового пина delay(1000); // устаканимся } void loop() { analogValue = analogRead(analogPin); // чтение аналогового значения digitalValue = digitalRead(3); // чтение цифрового значения Serial.print("Current value: "); // вывод аналогового значения в последовательный порт Serial.println(analogValue); Serial.print("Threshold: "); // вывод цифрового значения в аналоговый порт Serial.println(digitalValue); delay(5000); // задержка, чтобы не мельтешило перед глазами }

Кроме того, прямо на плате есть и светодиод, показывающий работу компаратора, что, опять же чисто теоретически позволяет использовать датчик вообще без каких-либо контроллеров. Если, конечно, удастся подобрать нужный порог срабатывания компаратора.

Внимательный читатель может догадаться, что в первую очередь я подключил MQ135 к плате Arduino Mega и посмотрел, что там на аналоговом и цифровом выходах. Там, в общем, никаких особых сюрпризов. Ну, кроме того, что когда светодиод компаратора горит, на цифровом выходе на самом деле 0. Особой роли это не играет, но перфекционистам придется туго.

Показания аналогового выхода в нормальной атмосфере, судя по всему, находятся в нижней трети диапазона измерений ЦАП Arduino. Состояние цифрового выхода зависит от положения подстроечного резистора и, конечно, качества воздуха.

Вот так выглядит «подышать в трубочку»:

А так как аппетит приходит во время еды, то следующим делом я поискал библиотеку, которая позволила получить хотя бы примерную концентрацию CO2 в воздухе. Нашел .

Теория, которая стоит за библиотекой гласит следующее: диоксид углерода, он же CO2 - четвертый по распространенности газ в атмосфере Земли. Остальные регистрируемые датчиком вещества в газообразном состоянии встречаются (на наше счастье) гораздо, гораздо реже. Но при этом чувствительность ко всем этим газам у MQ135 примерно одинаковая, что, в принципе, позволяет использовать его в первую очередь как датчик CO2.

В результате пользоваться библиотекой очень просто, но есть нюансы. Первый вытекает из той же документации по датчику, которая настаивает на 24-часовом прогреве датчика перед его реальным использованием. Второй же заключается в том, что по умолчанию библиотека рассчитана на нагрузочное сопротивление в 10 кОм, тогда как мой экземпляр платы укомплектован резистором в 1 кОм.

По счастью, второе легко решается редактированием кода библиотеки - спасибо Георгу Крокеру, что он подумал и о такой мелочи. Я же замечу, что калибровать следует только после того, как убедитесь, что в коде библиотеки задано верное значение сопротивления, иначе калибровочные данные вас удивят.

Итак, датчик прогрет, сопротивление задано верно. Что дальше? Дальше его нужно откалибровать, для чего пишем небольшой код, который набирает статистику по калибровочным данным и выставляем всю конструкцию на свежий воздух, при предпочтительной температуре около 20С на полчаса или около того.

Вот комбинированный код, чтобы посмотреть текущие и/или калибровочные данные:

#include // подключение библиотеки #define analogPin A0 // аналоговый выход MQ135 подключен к пину A0 Arduino MQ135 gasSensor = MQ135(analogPin); // инициализация объекта датчика void setup() { Serial.begin(9600); // последовательный порт для отображения данных delay(1000); // устаканимся } void loop() { float ppm = gasSensor.getPPM(); // чтение данных концентрации CO2 Serial.println(ppm); // выдача в последовательный порт float rzero = gasSensor.getRZero(); // чтение калибровочных данных Serial.println(rzero); // выдача в последовательный порт delay(5000); // просто задержка, чтобы не мельтешило перед глазами }

Затем усредняем полученные (калибровочные) показатели, добавляем их в ту же библиотеку (заменив оригинальное значение калибровки) и наслаждаемся показаниями, заявленными близкими ко всеми любимым ppm, но не забываем про магию и радужных единорогов.

На всякий случай сообщаю, что «добавляем в библиотеку» означает редактирование приведенных ниже строк в файле MQ135.h библиотеки MQ135:

/// The load resistance on the board #define RLOAD 1.0 /// Calibration resistance at atmospheric CO2 level #define RZERO 396.57

Здесь, например, уже задано актуальное для платы сопротивление и полученный опытным путем индекс калибровки. Индекс настоятельно рекомендую посчитать, поскольку он может быть разным для разных экземпляров датчика.

К великому сожалению, узнать, насколько актуальны показания получившейся системы, я не могу: специального прибора у меня нет, а на сайте данные о концентрации CO2 в моем районе не приводятся. Да и вообще особо не приводятся, поскольку этот газ, похоже, не считается загрязняющим.

Но хочу заметить, что датчик выдает довольно стабильные показания, которые также очень неплохо соотносятся с происходящим. К примеру, на приведенной ниже иллюстрации видно, как показания довольно резко пошли наверх, когда в комнате закрыли окно (около 18:00), и как они не менее стремительно стали снижаться, когда окно открыли (около 20:00):

Что касается цифрового выхода и компаратора, то его работа мне не очень понравилась, поскольку в обычных условиях он начинает срабатывать уже в самом начале (или конце - как посмотреть) диапазона регулировки подстроечного резистора.

Если найти какой-нибудь нормированный генератор CO2, тогда можно еще поиграться с настройкой, но где же такую фиговину найдешь? Другое дело - ненормированный, в качестве которого можно использовать себя любимого: дыхнешь - лампочка загорелась.

И хотя может показаться, что именно так я и планирую развлекать себя в ближайшее время, но нет. Пока что строю амбициозные планы на прибор для автоматического проветривания на основе температуры внутри/снаружи и качества воздуха внутри помещения.

Если удастся найти подходящий привод окна и справиться с управлением - доложу отдельно.

Ps. как обычно, в комментариях приветствуются чад кутежа и всяческий угар ссылки на более интересную цену, любопытные аналоги с учетом заявленной цели, ваши изделия, мысли о том, как лучше откалибровать MQ135 и предложения одолжить для этой благородной задачи ваш измерительный прибор. Ну и вообще.

Планирую купить +50 Добавить в избранное Обзор понравился +44 +76

Познакомимся с простым датчиком MQ-135, который поможет определить уровень вредных веществ в воздухе. Подключим анализатор газов MQ-135 к Raspberry Pi используя АЦП PCF8591, напишем простую тестовую программу для наблюдения за сигналом из датчика, а также для выполнения определенного действия при достижении установленного критического уровня.

Анализатор газов MQ-135

MQ-135 - достаточно компактный и недорогой датчик, который умеет анализировать уровень вредных веществ в воздухе. Он поможет определить в воздухе наличие следующих веществ:

  • Углекислый газ (в нормальных условиях это бесцветный газ, без запаха, двуоксид углерода - CO 2);
  • Угарный газ (бесцветный ядовитый газ без вкуса и запаха, монооксид углерода - CO);
  • Аммиак (в нормальных условиях это бесцветный газ с резким характерным запахом, нитрид водорода - NH 3);
  • Бензол (жидкость без цвета со специфическим сладковатым запахом, органическое соединение - C 6 H 6);
  • Оксид азота (бесцветный газ который незначительно растворим в воде, монооксид азота - NO);
  • Пары спирта (органические соединения, существует целый класс спиртов, спирт содержат алкогольные напитки);
  • Дым (газ выдкляющийся при сгорании различных веществ, прохождения химических реакций);
  • и другие...

Рис. 1. Внешний вид датчика MQ-135.

Детектор газов MQ-135 может применяться в системах безопасности и контроля, для анализа состояния воздуха в вентиляционных установках, в медицине и других сферах где нужно выполнять контроль за чистотой воздуха и окружающей среды.

Основные технические характеристики и плюсы датчика:

  • Высокая чувствительность;
  • Высокая скорость реакции;
  • Стабильность и долговечность;
  • Питание нагревательного элемента от 5В;
  • Сопротивление нагревательного элемента - 33 Ом;
  • Ток потребляемый нагревателем от источника питания 5В - 150мА (мощность 800 мВт);
  • Небольшие размеры (18мм в диаметре, 17мм в высоту + 6мм высота пинов).

Датчик содержит 6 ножек - две из них используются для питания нагревателя, а остальные 4 для снятия сигнала с сенсора.

Рис. 2. Структура и принцип работы датчика газов MQ-135, на рисунке обозначены:

  • 1 - чувствительный к газам слой (SnO 2);
  • 2 - электрод (Au);
  • 3 - токопроводящие линии для соединения с электродом (Pt);
  • 4 - катушка нагревателя (Ni-Cr);
  • 5 - керамическая трубка (Al 2 O 3);
  • 6 - сетка из стальных проводников для защиты в случае взрыва внутри датчика;
  • 7 - сжимающее кольцо (никелированная медь);
  • 8 - резиновая основа;
  • 9 - пины для подключения датчика (никелированная медь).

Нагревательный элемент необходим для обеспечения кондиционного режима работы чувствительного слоя, воздух с содержащимися в нем веществами попадая на чувствительный слой и в зависимости от концентрации этих веществ спровоцирует изменение значения электрического потенциала между электродами (смотри схему на рисунке 2).

Этот электрический потенциал мы снимаем с электродов и анализируем его уровень при помощи дополнительных электронных схем.

Подключаем датчик MQ-135

Для экспериментов использован готовый модуль, который содержит датчик MQ-135 и небольшой компаратор, парочку светодиодов и штырьки для подключения.

Рис. 3. Внешний вид модуля с датчиком MQ-135 и схемой сравнения.

Модуль содержит 4 вывода:

  • VCC - питание 5В;
  • GND - земля (минус);
  • AO - аналоговый выход датчика (Analog Output);
  • DO - цифровой выход датчика (Digital Output).

Цифровой выход датчика подключен к компаратору, при помощи которого мы можем оценить значение с датчика и получить на выходе низкий (0В) или высокий (5В) уровень. Для регулировки порога срабатывания на платке установлен переменный резистор.

Аналоговый выход датчика предназначен для подключения к самодельным компараторам и анализаторам, а также к АЦП (Аналого-Цифровым Преобразователям).

В эксперименте я буду использовать аналоговый выход датчика MQ-135, подключенный к АЦП на основе PCF8591, работу с которым я описывал в прошлой статье. Анализировать данные работы АЦП будет мини-компьютер Raspberry Pi .

Модуль MQ-135 должен питаться от напряжения +5В, соответственно на его цифровом и аналоговом выходах уровень напряжения может достигать +5В.

Аналоговый выход MQ-135 можно было бы подключить напрямую к аналоговому входу PCF8591 если питать последний также от напряжения +5В, но в таком случае понадобится собирать двунаправленный конвертер уровней напряжения для шины I 2 C.

Конвертация уровней напряжения здесь нужна, поскольку:

  1. Пины GPIO в Raspberry Pi (используемые нами здесь для интерфейса I 2 C) рассчитаны на максимальное входное/выходное напряжение +3,3В;
  2. При питании PCF8591 от +5В, напряжения +3,3В на выводах шины I 2 C может быть не достаточно чтобы получить высокий уровень (логическая 1). Обмен данными по шине станет невозможным;
  3. На модуле PCF8591 установлены подтягивающие (pull-up) резисторы, которые пытаются выставить при логической единице на каждом из выводов шины I 2 C напряжение +5В (питание PCF8591). Это не безопасно для входов GPIO в Raspberry Pi, расчитанных на +3,3В.

Чтобы не собирать конвертер уровней напряжения здесь все же можно выкрутиться следующим образом: питать модуль PCF8591 от напряжения +3,3В (в даташите указан диапазон питающих напряжений 2,6В-6В), а чтобы не спалить его аналоговый вход (теперь туда можно подавать максимум +3,3В) напряжением с аналогового выхода MQ-135 (достигающее +5В), соединяем эти модули через резистивный делитель напряжения : 5В - в 3В.

Вот такая получилась схема подключения модулей:

Рис. 4. Принципиальная схема подключения модулей MQ-135 и PCF8591 к Raspberry Pi.

Добавлю несколько слов о первом подключении модуля MQ-135. При первом влючении нового, только что распакованного модуля с датчиком, в воздухе кратковременно появится небольшой запах гари, не стоит волноваться - это первый раз раскалился нагревательный элемент датчика.

Перед долговременным применением датчика, для адаптации и стабилизации параметров, его стоит оставить с подключенным к нагревателю напряжением на 24 часа (рекомендация из даташита).

Ток потребления модуля MQ-135 (по большей части нагревателя в нем) составляет примерно 150мА (I=U/R=5В/33Ом=0,151А), поэтому питание можно взять с пина 2 (+5В) на разъеме GPIO.

Важно помнить что линию питания 5В в Raspberry Pi нельзя перегружать, если нужно питать какой-то модуль от 5В и с потребляемым током более 0,3А-0,5А то лучше не пожалеть пару центов и собрать отдельный стабилизатор напряжения, например на микросхеме L7805 (розничная стоимость менее 0,5$).

ВНИМАНИЕ! На показанном ниже фото, ранее в качестве эксперимента, я подключил все модули к питанию +5В, выход датчика соединил с входом АЦП напрямую и не использовал резистивного делителя напряжения. Старайтесь так не делать, а собирать безопасную схему, как на рисунке 4.

Рис. 5. Внешний вид подключенных модулей MQ-135 и PCF8591 к Raspberry Pi.

Думал удалить эту картинку, но оставил ее и решил расписать что происходит при подобном не безопасном подключении. Почему же схема в такой конфигурации работает и Raspberry Pi не выходит из строя? - Давайте с этим разберемся.

Такое подключение работает, но все же есть риск нанесения вреда контроллеру GPIO в Raspberry Pi. Это может случиться если на какой-то из пинов попадет напряжение +5В (явно превышающее +3,3В) и с током достаточным чтобы пожечь внутренние ключи на пинах GPIO.

Дело в том, что на модуле PCF8591 между каждой из двух линий (SCL, SDA) шины I 2 C и шиной питания стоят подтягивающие резисторы с сопротивлением 4,7кОм (это подключение можно увидеть на схеме модуля).

Генерация сигналов в шине I 2 C базируется на "прижимании" (подключении через внутренние транзисторы в устройстве) линий данных к земле (логический 0) и их "отпускании" (логическая 1). В последнем случае за установку высокого уровня отвечают как раз те самые подтягивающие резисторы.

Получается, что при логической единице на одной из линий, напряжение питания модуля (+5В) через резистор 4,7кОм идет на вывод GPIO, а знаем что позволенный максимум на нем - 3,3В. Порт не выгорает здесь только потому, что ток через эту цепочку достаточно мал, он гасится на этом же резисторе и порт остается цел.

Что же там за ток может быть, давайте попробуем посчитать:

  1. При логическом "0" (через внутренний транзистор порт подключил вывод GPIO к земле): I = U/R = 5V/4700R = 0,00106A = 1mA
  2. При логической "1" (через внутренний транзистор порт подключил вывод GPIO к +3,3В): I = U/R = (5V-3,3V)/4700R = 0,00036A = 0,36mA.

Принцип работы шины I 2 C таков, что при генерации высокого уровня пин порта не подключается к линии питания ("висит в воздухе"), поэтому пункт 2 в расчетах можно и не учитывать.

В итоге, в самом крайнем случае, мы имеем напряжение +5В при токе 1мА на пине GPIO, чего явно не достаточно чтобы спалить порт на гребенке Raspberry Pi.

А что будет если подтягивающие резисторы в модуле PCF8591 отпаять от +5В и припаять к +3,3В? - скорее всего, передача данных по шине I2C перестанет осуществляться, напряжения +3,3В будет не достаточно для интерпретации модулем PCF8591 (питающимся от +5В) сигнала напряжением +3,3В как высокого уровня (логической "1").

А теперь давайте подумаем что получится если подключить 3-5 разных модулей с питанием +5В к шине I2C Raspberry Pi. В зависимости от сопротивлений подтягивающих резисторов на модулях (если эти резисторы впаяны, их сопротивления просуммируются как при параллельном включении резисторов) ток может достичь 5-10мА при напряжении +5В, что уже может нести более значительную опасность для портов GPIO.

Поэтому, нужно всегда придерживаться правил:

  1. На пины GPIO в Raspberry Pi нельзя допускать попадания напряжений, превышающих 3,3В!
  2. При подключении к шине I2C устройств с разными напряжениями питания (2,5В, 3В, 5В...) нужно использовать схему конвертера уровней напряжения !

Программа для анализа состояния датчика MQ-135

Программа написана на языке программирования Python и является модифицированной версией той, которую я приводил в статье где разбирали работу с модулем PCF8591, там же описано как активировать шину I 2 C .

Суть работы новой версии программы заключается вот в чем:

  • Постоянно выводим в консоль текущее значение с датчика газов (числа от 0 до 255, от меньшей концентрации до большой);
  • При достижении некоторого установленного значения концентрации газов - зажигаем светодиод D1.

Создадим новый файл для программы на Питоне и откроем его в редакторе nano:

Nano /tmp/mq-135-pcf8591-test.py

Скопируем приведенный ниже код в файл:

#!/usr/bin/env python # Program for gas sensor MQ135 + ADC-DAC PCF8591P # 2016 http://сайт import os import time from smbus import SMBus DEV_ADDR = 0x48 adc_channel = 0b1000010 # 0x42 (input AIN2 for ADC + use DAC) dac_channel = 0b1000000 # 0x40 bus = SMBus(1) # 1 - I2C bus address for RPi rev.2 while(1): os.system("clear") print("Press Ctrl C to stop...\n") # read sensor value from ADC bus.write_byte(DEV_ADDR, adc_channel) bus.read_byte(DEV_ADDR) bus.read_byte(DEV_ADDR) value = bus.read_byte(DEV_ADDR) print "AIN value = " + str(value) # compare value from ADC and set value in DAC if value > 120: bus.write_byte_data(DEV_ADDR, dac_channel, 220) else: bus.write_byte_data(DEV_ADDR, dac_channel, 0) # pause 100 milliseconds time.sleep(0.1)

Для выхода из редактора (возможно кто-то еще не знает этого): жмем CTRL+X, для подтверждения сохранения файла жмем Y и ЕНТЕР.

Запускаем программу командой в консоли:

Python /tmp/mq-135-pcf8591-test.py

Рис. 6. Вывод выполняющейся программы в окне консоли.

Теперь можете поэкспериментировать с датчиком, поднося к нему на разном расстоянии разнообразные вещества - спирт, растворитель, бензин и другие. В консоли можно будет наблюдать как изменяется значение на выходе датчика.

Чтобы изменить числовой порог свечения светодиода, к примеру для значения 70, нужно изменить строчку кода "if value > 120:" на "if value > 70:" - теперь программа будет реагировать на превышение значения 70 на входе AIN2 АЦП свечением светодиода.

Используя мультиметр в режиме измерения напряжения до 20В можно понаблюдать за изменением напряжения на аналоговом выходе датчика MQ-135 при изменении уровня испарений газов около него.

Засветить светодиод - это очень просто, что можно еще придумать? - например, настроить отправку электронного письма (или электронных писем) в случае достижения заданного порога вредных газов в воздухе, включить воспроизведение какого-то MP3-файла на Raspberry Pi и много других вещей.

Заключение

Ниже приведено видео работы модуля с MQ-135, подключенного к малинке и АЦП PCF8591 (старый не безопасный вариант, без делителя напряжения на резисторах).

Для теста срабатывания датчика использован дихлорэтан (клей для пластмассы и оргстекла), вернее его капелька нанесенная на кончик маленькой отвертки, этих испарений вполне достаточно чтобы датчик зафиксировал наличие в воздухе ядовитого вещества.

gastroguru © 2017