Компоненты · 14 мин чтения

Датчик пламени и Arduino: подключение, код и пожарная сигнализация

Датчик пламени и Arduino: подключение, выходы DO и AO, настройка чувствительности, дальность и угол, пожарная сигнализация с зуммером, работа с MQ-2, защита от ложных срабатываний, код для ESP32 и Pico.

Датчик пламени — дешёвый модуль, который улавливает инфракрасный свет от зажигалки, свечи или горящей бумаги; с Arduino он работает всего в несколько строк кода. Библиотека для него не нужна: пин DO модуля меняет состояние, когда видит пламя, а пин AO у 4-пиновых версий выдаёт напряжение, которое меняется вместе с интенсивностью пламени. Это один из самых популярных датчиков для пожарной сигнализации, роботов-пожарных, систем безопасности на кухне и школьных проектов.

В этом руководстве ты узнаешь, что находится внутри датчика пламени и почему он реагирует только на свет от 760 до 1100 нм, чем отличаются цифровой и аналоговый выходы, как правильно настроить потенциометр чувствительности и какие у датчика дальность и угол обнаружения. Затем соберёшь пожарную сигнализацию с зуммером и светодиодом, объединишь датчик с газовым датчиком MQ-2, программно уменьшишь число ложных срабатываний от солнечного света, пультов и других источников, отправишь уведомление в Telegram на телефон с ESP32 и запустишь ту же схему на Raspberry Pi Pico с MicroPython.

Модуль датчика пламени (LM393, 3 пина)
3-пиновый модуль датчика пламени: слева чёрный ИК-приёмник, в центре синий потенциометр чувствительности и компаратор LM393, справа пины VCC, GND и DO, а также светодиоды питания и тревоги.

Что такое датчик пламени и как он работает?

Чёрная деталь на конце модуля, похожая на светодиод, на самом деле — инфракрасный фототранзистор (на некоторых платах фотодиод); распространённый пример — YG1006. Чёрный эпоксидный корпус отсекает большую часть видимого света и пропускает только ближний инфракрасный свет примерно от 760 до 1100 нм, с пиком чувствительности около 940 нм. Верхняя граница задана самим кремнием: при ширине запрещённой зоны 1,12 эВ кремний не может поглощать фотоны с длиной волны больше примерно 1100 нм. Горячие частицы сажи в пламени тоже излучают в этом диапазоне, поэтому ток через фототранзистор растёт по мере приближения пламени. Делитель напряжения на плате превращает этот ток в напряжение, а компаратор LM393 сравнивает его с порогом, заданным потенциометром, и определяет состояние пина DO.

ПараметрЗначение
Улавливаемая длина волны760–1100 нм (пик чувствительности ~940 нм)
Угол обнаруженияОколо 60° (~30° в каждую сторону от оси)
Дальность обнаруженияОбычно до 80 см для пламени зажигалки; для пламени побольше — дальше
Напряжение питания3,3–5 V
КомпараторLM393; порог задаётся многооборотным потенциометром
ВыходыDO (цифровой, на всех моделях), AO (аналоговый, на 4-пиновых моделях)
Логика DOРаспространённые синие модули: пламя = LOW, светодиод DO горит; KY-026: обычно пламя = HIGH
Время реакцииНамного меньше миллисекунды; фототранзистор реагирует за микросекунды
Рабочая температура приёмникаПримерно от −25 до +85 °C

Одну и ту же задачу выполняют несколько разных плат датчика пламени. 3-пиновые модули, как на фото выше, имеют только цифровой выход; 4-пиновые добавляют к нему аналоговый. KY-026, знакомый по наборам датчиков, работает так же, но его выход DO обычно инвертирован. В роботах-пожарных используют многоканальные платы с пятью приёмниками, расположенными веером. Датчик пламени пассивный, то есть не излучает собственного света; этим он отличается от ИК-датчика TCRT5000, в котором есть и излучатель, и приёмник.

МодельПиныОсобенностьКогда выбирать
3-пиновый модульVCC, GND, DOТолько «есть пламя / нет пламени»Простая пожарная сигнализация, первые опыты
4-пиновый модульVCC, GND, DO, AOПороговый выход + интенсивность пламениМногоуровневая тревога, фильтрация ложных срабатываний
KY-026A0, G, +, D0Как у 4-пинового модуля; DO при пламени обычно HIGHПроекты из наборов датчиков
5-канальный модульVCC, GND и отдельный выход для каждого приёмникаШирокий обзор около 120°Роботы, которые находят направление на пламя

Цифровой (DO) и аналоговый (AO) выход

Пин DO даёт ответ «да/нет»: он меняет состояние, когда инфракрасный свет превышает порог, заданный потенциометром. На распространённых синих платах этот пин обычно в состоянии HIGH, при виде пламени переходит в LOW, и загорается светодиод DO; на некоторых платах, например KY-026, всё наоборот. Поэтому первым делом проверь свой модуль зажигалкой и посмотри, что показывает монитор порта. Пин AO выдаёт сырой сигнал. У большинства модулей это значение уменьшается по мере приближения пламени: значение analogRead 900–1020 в комнате без огня может упасть до нескольких сотен рядом с зажигалкой. Потенциометр меняет только порог DO и на AO не влияет.

ПараметрDO (цифровой)AO (аналоговый)
Читаемое значениеHIGH или LOW0–1023 на Arduino Uno
ПорогПотенциометр на платеЗадаёшь в коде
ИнформацияЕсть пламя или нетИнтенсивность пламени, примерное расстояние и мерцание
Какой пин использоватьЛюбой цифровой пинАналоговый пин (АЦП)
Лучше всего дляПростая сигнализация, мгновенная реакция через прерываниеМногоуровневая тревога, фильтрация ложных срабатываний, поиск направления

Как настроить потенциометр чувствительности

  1. Подай питание на модуль и установи датчик там, где он будет работать, направив его туда, куда он будет смотреть; всегда делай эту настройку в реальных условиях.
  2. Когда пламени нет, поверни синий потенциометр маленькой отвёрткой и найди точку, где светодиод DO переключается между «горит» и «не горит».
  3. От этой точки поверни ещё на пол-оборота или на оборот в ту сторону, где светодиод остаётся выключенным. Так небольшие изменения окружающего освещения не вызовут тревогу.
  4. Поднеси зажигалку к датчику на самом большом расстоянии, на котором нужно обнаруживать пламя, и проверь, что светодиод загорается. Если нет, сделай настройку чуть чувствительнее и попробуй снова.
  5. Убедись, что датчик не смотрит на солнечное окно или лампу накаливания, и через несколько часов проверь настройку ещё раз при другом освещении.
Синий потенциометр на этих модулях — обычно многооборотный подстроечный резистор типа 3296, которому нужно около 25 оборотов от одного края до другого. Если после нескольких оборотов ничего не меняется, он не сломан — просто нужно крутить дальше. LM393, настроенный очень близко к порогу, может быстро включаться и выключаться при мерцании пламени; чуть позже это исправит время удержания в коде. Как работает потенциометр, можно прочитать в статье что такое потенциометр.

Дальность и угол обнаружения

Цифры вроде 80 см, которые указывают производители, относятся к стандартному пламени зажигалки; реальная дальность зависит от размера пламени, настройки потенциометра и окружающего освещения. Здесь действует простой закон физики: интенсивность света от небольшого источника падает пропорционально квадрату расстояния. Если удвоить расстояние, инфракрасного света до датчика дойдёт вчетверо меньше. Если посмотреть с другой стороны, пламя, излучающее в четыре раза больше света, можно обнаружить с вдвое большего расстояния, а в сто раз более сильное — с десятикратного. Поэтому пламя свечи обнаруживается на меньшем расстоянии, чем пламя зажигалки, а горящую кучу бумаги видно за несколько метров.

РасстояниеСвет, доходящий до датчика (20 см = 100%)
20 см100%
40 см25%
60 см11%
80 см6%
1 м4%

Угол обнаружения — около 60 градусов, то есть датчик видит пламя внутри конуса примерно по 30 градусов в каждую сторону от оси, и сигнал быстро слабеет, когда пламя смещается к краю конуса. У приёмника длинные ножки, поэтому его можно аккуратно отогнуть в любую сторону, но если много раз гнуть место, где ножки входят в корпус, они сломаются. Чтобы сузить поле зрения, надень на приёмник матовую чёрную трубку: трубка с внутренним диаметром 6 мм и длиной 2 см уменьшает угол примерно до 30 градусов и отсекает солнечный или ламповый свет сбоку. Поле зрения должно быть ровно таким, чтобы охватывать нужную зону; всё, что шире, лишь добавляет новые источники ложных срабатываний.

Подключение датчика пламени: Arduino Uno, ESP32 и Pico

ПодключениеArduino UnoESP32Raspberry Pi Pico
VCC модуля5V3V33V3(OUT), пин 36
GND модуляGNDGNDGND, пин 38
DO модуляD2GPIO 27GP15, пин 20
AO модуля (4 пина)A0GPIO 34 (ADC1)GP26 / ADC0, пин 31
Активный зуммер (+)D8GPIO 25GP14, пин 19
Красный светодиод (с 220 Ω)D7GPIO 26GP13, пин 17
Пины ESP32 и Pico рассчитаны на 3,3 V. На этих платах питай датчик пламени от пина 3V3, а не от 5V, VIN или VBUS: если модуль работает от 5 V, его выходы DO и AO могут выдавать до 5 V и повредить входной пин. В этом важное отличие от MQ-2: датчик пламени нормально работает от 3,3 V, поэтому делитель напряжения не нужен. Перед подключением всегда читай надписи VCC и GND на плате: порядок пинов у разных моделей разный, а питание, поданное с обратной полярностью, может вывести LM393 из строя.

Пошагово: пожарная сигнализация на Arduino с датчиком пламени

  1. Подключи пин VCC модуля к пину 5V Arduino, GND — к GND, DO — к D2.
  2. Длинную (+) ножку активного зуммера подключи к D8, короткую — к GND.
  3. Длинную ножку красного светодиода подключи к D7 через резистор 220 Ω, короткую — к GND. Если светодиод другой, номинал резистора можно рассчитать в калькуляторе резистора для светодиода.
  4. Загрузи код ниже, открой монитор порта на скорости 9600 бод и ненадолго поднеси зажигалку к датчику на расстояние 20–30 см.
  5. Если зуммер звучит и светодиод горит, схема работает; если тревога звучит без пламени и замолкает при пламени, поменяй в коде значение FLAME_ACTIVE на HIGH.
C++ (Arduino IDE)
1// Alev sensörü ile basit yangın alarmı / Simple fire alarm with a flame sensor
2const int FLAME_DO = 2;          // modülün DO pini / module DO pin
3const int BUZZER = 8;            // aktif buzzer / active buzzer
4const int LED = 7;               // kırmızı LED (220 Ω ile) / red LED (with 220 Ω)
5const int FLAME_ACTIVE = LOW;    // çoğu modülde alev = LOW, KY-026'da HIGH / most modules: flame = LOW, KY-026: HIGH
6
7void setup() {
8  Serial.begin(9600);
9  pinMode(FLAME_DO, INPUT);
10  pinMode(BUZZER, OUTPUT);
11  pinMode(LED, OUTPUT);
12}
13
14void loop() {
15  bool flame = digitalRead(FLAME_DO) == FLAME_ACTIVE;
16
17  if (flame) {
18    Serial.println(F("ALEV ALGILANDI! / FLAME DETECTED!"));
19    digitalWrite(LED, HIGH);
20    digitalWrite(BUZZER, HIGH);  // kesik kesik alarm sesi / beeping alarm
21    delay(150);
22    digitalWrite(BUZZER, LOW);
23    delay(150);
24  } else {
25    digitalWrite(LED, LOW);
26    digitalWrite(BUZZER, LOW);
27    delay(50);
28  }
29}

На каждом проходе код читает пин DO и сравнивает результат с константой FLAME_ACTIVE. Благодаря ей один и тот же код работает и с синими модулями, которые при пламени выдают LOW, и с KY-026, который выдаёт HIGH. Пока пламя видно, светодиод горит, а зуммер включается и выключается каждые 150 мс, издавая прерывистый сигнал, который привлекает внимание. У активного зуммера есть собственный генератор, поэтому ему нужны только HIGH и LOW; если у тебя пассивный зуммер, используй tone() вместо digitalWrite, как объяснено в статье что такое зуммер. Есть и ещё одна причина, по которой пин DO подключён именно к D2: на Uno D2 — один из двух пинов с поддержкой прерываний, так что с attachInterrupt пламя можно поймать, не дожидаясь окончания остального цикла.

Аналоговое чтение: интенсивность пламени и примерное расстояние

Если у тебя 4-пиновый модуль, выход AO позволяет сделать гораздо больше. Сырое значение в каждой обстановке своё, поэтому вместо фиксированного порога используй такой метод: при запуске, когда пламени нет, измерь базовый уровень (baseline), а затем смотри, насколько каждое новое показание от него отклоняется. Код ниже усредняет 16 измерений, чтобы снизить шум, вычисляет отклонение как силу пламени и примерно сообщает, близко пламя или далеко. Если у твоего модуля значение AO при пламени растёт, просто задай DROPS_WITH_FLAME равным false.

C++ (Arduino IDE)
1// AO ile alev gücü ve yaklaşık mesafe / Flame strength and rough distance via AO
2const int FLAME_AO = A0;             // 4 pinli modülün AO pini / AO pin of the 4-pin module
3const bool DROPS_WITH_FLAME = true;  // çoğu modülde alev yaklaşınca değer düşer / on most modules the value falls as the flame approaches
4int baseline;                        // alevsiz ortam değeri / flame-free ambient value
5
6int readAverage() {
7  long sum = 0;
8  for (int i = 0; i < 16; i++) {     // 16 ölçümün ortalaması / average of 16 readings
9    sum += analogRead(FLAME_AO);
10    delay(2);
11  }
12  return sum / 16;
13}
14
15void setup() {
16  Serial.begin(9600);
17  delay(1000);                       // açılışta ortamda alev olmamalı / no flame at start-up
18  baseline = readAverage();
19  Serial.print(F("Taban / Baseline: "));
20  Serial.println(baseline);
21}
22
23void loop() {
24  int value = readAverage();
25  int strength = DROPS_WITH_FLAME ? baseline - value : value - baseline;  // alev gücü / flame strength
26  if (strength < 0) strength = 0;
27
28  Serial.print(F("AO: "));
29  Serial.print(value);
30  Serial.print(F("  Guc / Strength: "));
31  Serial.print(strength);
32
33  if (strength > 400) {
34    Serial.println(F("  -> YAKIN ALEV / CLOSE FLAME"));
35  } else if (strength > 100) {
36    Serial.println(F("  -> UZAK ALEV / DISTANT FLAME"));
37  } else {
38    Serial.println(F("  -> alev yok / no flame"));
39  }
40  delay(250);
41}

Пороги 100 и 400 в коде — лишь отправная точка. Чтобы подобрать их под свой датчик, загрузи код, открой монитор порта и запиши силу пламени, держа зажигалку на расстоянии 10, 30 и 60 см; из-за закона обратных квадратов будет видно, что вблизи значение меняется очень быстро, а вдали медленно. Поэтому по аналоговому значению нельзя вычислить точное расстояние в сантиметрах: одно и то же значение может дать и маленькое пламя рядом, и большое вдали. Как АЦП получает сырое значение, рассказано в статье аналого-цифровое преобразование, а тонкости монитора порта — в статье монитор порта Arduino.

Солнечный свет и другие источники ложных срабатываний

Датчик пламени видит не огонь, а инфракрасный свет в определённом диапазоне, и сработать его может заставить всё, что светит в этом диапазоне. Какие источники доставят проблемы, объясняет закон смещения Вина: длина волны, на которой горячее тело излучает сильнее всего, примерно равна 2898 / T микрометров (T — температура в кельвинах). Солнце и лампы накаливания сильно излучают как раз в диапазоне датчика, а человеческое тело для этого слишком холодное, так что датчик тебя вообще не видит. Именно поэтому для обнаружения движения нужен PIR-датчик, который смотрит на гораздо более длинные волны.

ИсточникПримерная температураДлина волны максимума излученияВлияние на датчик пламени
Солнце5800 К0,5 мкмОчень сильное; прямое солнце или его отражение от стекла может ослепить датчик
Лампы накаливания и галогенные лампы2700–3000 К~1 мкмСильное; большая часть их света приходится как раз на диапазон датчика
Пламя свечи и зажигалки (частицы сажи)~1500 К~1,9 мкмИсточник, который нужно обнаружить; часть излучения попадает в диапазон
Раскалённая спираль обогревателя, печь~1100 К~2,6 мкмМожет вызвать срабатывание с близкого расстояния
Пульт от телевизора-0,94 мкм (узкая полоса)Вызывает срабатывание короткими импульсами
Светодиодные и люминесцентные лампы-Видимый диапазонИнфракрасного излучения почти нет, обычно проблем не создают
Человеческое тело310 К~9,3 мкмДатчик его не видит

Большинство ложных срабатываний можно предотвратить аппаратно: размести датчик так, чтобы он не смотрел на окно, освещённую солнцем стену или лампу накаливания, лучше всего вниз и внутрь помещения, сузь поле зрения чёрной трубкой и настрой потенциометр при реальном освещении. Помни, что сильный солнечный свет не только вызывает ложные срабатывания, но и может ослепить датчик, насытив его: если значение AO на солнце уже упало до минимума, при появлении настоящего пламени меняться уже нечему. Профессиональные инфракрасные извещатели пламени решают эту проблему тремя способами: смотрят на диапазон 4,3 мкм, где излучает горячий углекислый газ, а солнечный свет в основном поглощается атмосферой, сравнивают несколько длин волн и анализируют мерцание пламени. Первые два приёма твоему модулю недоступны, но анализ мерцания и подтверждение по времени можно сымитировать программно.

Программная защита от ложных срабатываний: подтверждение по времени и анализ мерцания

Настоящее пламя никогда не горит ровно: из-за потоков воздуха и поднимающихся горячих газов его яркость колеблется примерно от 1 до 20 раз в секунду. А вот солнечный свет и свет лампы накаливания на коротких промежутках почти постоянны, а импульсы пульта длятся лишь миллисекунды. Код ниже использует эти различия по трём правилам: сила пламени должна заметно превышать базовый уровень, значение за последнюю секунду должно колебаться сильнее заданной величины, и оба условия должны выполняться без перерыва не менее двух секунд. Кроме того, каждое измерение — это среднее из 20 отсчётов за 10 мс. В сети 50 Hz лампы слегка мерцают 100 раз в секунду; усреднение за 10 мс, ровно один период мерцания, гасит эти пульсации, и лампа не принимается за мерцающее пламя.

C++ (Arduino IDE)
1// Süre doğrulamalı ve titreşim analizli alev alarmı / Flame alarm with time confirmation and flicker analysis
2const int FLAME_AO = A0;
3const int BUZZER = 8;
4const int LED = 7;
5const int STRENGTH_LIMIT = 150;          // tabandan en az bu kadar sapma / minimum deviation from the baseline
6const int FLICKER_LIMIT = 20;            // 1 sn içindeki en az dalgalanma / minimum swing within 1 s
7const unsigned long CONFIRM_MS = 2000;   // koşul bu kadar kesintisiz sürmeli / condition must hold this long
8
9float baseline;
10int winMin = 1023, winMax = 0;
11bool flickering = false;
12unsigned long windowStart = 0;
13unsigned long candidateSince = 0;
14
15// 10 ms boyunca 20 ölçüm: 100 Hz lamba titreşimini siler / 20 samples over 10 ms: cancels 100 Hz lamp flicker
16int readFiltered() {
17  long sum = 0;
18  for (int i = 0; i < 20; i++) {
19    sum += analogRead(FLAME_AO);         // yaklaşık 0,11 ms sürer / takes about 0.11 ms
20    delayMicroseconds(390);
21  }
22  return sum / 20;
23}
24
25void setup() {
26  Serial.begin(9600);
27  pinMode(BUZZER, OUTPUT);
28  pinMode(LED, OUTPUT);
29  baseline = readFiltered();             // açılışta ortamda alev olmamalı / no flame at start-up
30}
31
32void loop() {
33  int value = readFiltered();
34  int strength = (int)baseline - value;  // AO alevle artıyorsa: value - baseline / if AO rises with flame: value - baseline
35  unsigned long now = millis();
36
37  if (value < winMin) winMin = value;
38  if (value > winMax) winMax = value;
39
40  if (now - windowStart >= 1000) {       // her saniye pencereyi değerlendir / evaluate the window every second
41    int swing = winMax - winMin;
42    flickering = swing > FLICKER_LIMIT;  // alev titrer, güneş sabittir / flames flicker, sunlight is steady
43    if (strength < STRENGTH_LIMIT / 2) {
44      baseline += (value - baseline) * 0.05;  // ortam ışığını yavaşça izle / slowly follow ambient light
45    }
46    Serial.print(F("Guc / Strength: "));
47    Serial.print(strength);
48    Serial.print(F("  Dalgalanma / Swing: "));
49    Serial.println(swing);
50    winMin = 1023;
51    winMax = 0;
52    windowStart = now;
53  }
54
55  bool candidate = strength > STRENGTH_LIMIT && flickering;
56  if (!candidate) candidateSince = now;  // koşul bozulunca sayaç sıfırlanır / timer resets when the condition breaks
57  bool alarm = now - candidateSince >= CONFIRM_MS;
58
59  digitalWrite(LED, alarm ? HIGH : LOW);
60  digitalWrite(BUZZER, (alarm && (now / 200) % 2) ? HIGH : LOW);  // kesik siren / beeping siren
61}

Код отсчитывает время через millis(), а не delay(), поэтому продолжает измерять, даже пока звучит тревога; подробности этого подхода — в статье millis вместо delay. Базовый уровень тоже не стоит на месте: когда пламени нет, он раз в секунду сдвигается на 5 процентов к последнему показанию и медленно следует за освещением, которое меняется в течение дня. Чтобы подобрать хороший FLICKER_LIMIT, посмотри в мониторе порта на размах колебаний за одну секунду сначала у ровного источника света, затем у пламени свечи, и поставь порог между ними. Метод не идеален: солнечный свет, пробивающийся сквозь качающиеся на ветру листья, тоже мерцает. Другие приёмы, например скользящее среднее и медианный фильтр, описаны в статье фильтрация данных датчиков.

Совместное использование с газовым датчиком MQ-2

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

Датчик газа и дыма MQ-2
Датчик газа и дыма MQ-2
Зуммер
Зуммер
Датчик пламениMQ-2РешениеРеакция
НетНормаНормаСветодиод и зуммер выключены
ЕстьНормаПредупреждение: это может быть солнце, лампа или только начинающийся пожарСветодиод мигает, короткий сигнал каждые 2 секунды
НетВысокийПредупреждение: дым, утечка газа или пожар вне поля зренияСветодиод мигает, короткий сигнал каждые 2 секунды
ЕстьВысокийПожарСветодиод горит постоянно, частая прерывистая сирена
C++ (Arduino IDE)
1// Alev sensörü + MQ-2 ile iki kademeli yangın alarmı / Two-level fire alarm with a flame sensor + MQ-2
2const int FLAME_DO = 2;
3const int MQ2_AO = A1;                   // MQ-2 analog çıkışı / MQ-2 analog output
4const int BUZZER = 8;
5const int LED = 7;
6const int FLAME_ACTIVE = LOW;            // KY-026 kullanıyorsan HIGH / HIGH if you use a KY-026
7const int SMOKE_LIMIT = 400;             // temiz hava değerinin belirgin üstü / well above the clean-air value
8const unsigned long WARMUP_MS = 60000;   // MQ-2 ön ısıtma süresi / MQ-2 warm-up time
9const unsigned long HOLD_MS = 300;       // DO'daki kısa kesintileri yok say / ignore short gaps on DO
10
11unsigned long lastFlame = 0;
12unsigned long lastPrint = 0;
13
14void setup() {
15  Serial.begin(9600);
16  pinMode(FLAME_DO, INPUT);
17  pinMode(BUZZER, OUTPUT);
18  pinMode(LED, OUTPUT);
19}
20
21void loop() {
22  unsigned long now = millis();
23  if (digitalRead(FLAME_DO) == FLAME_ACTIVE) lastFlame = now;
24  bool flame = lastFlame > 0 && now - lastFlame < HOLD_MS;
25
26  int gas = analogRead(MQ2_AO);
27  bool smoke = now > WARMUP_MS && gas > SMOKE_LIMIT;  // ısınana kadar dumanı yok say / ignore smoke until warmed up
28
29  int level = 0;                         // 0 normal, 1 uyarı / warning, 2 yangın / fire
30  if (flame && smoke) level = 2;
31  else if (flame || smoke) level = 1;
32
33  if (level == 2) {
34    digitalWrite(LED, HIGH);
35    digitalWrite(BUZZER, (now / 150) % 2 ? HIGH : LOW);     // hızlı siren / fast siren
36  } else if (level == 1) {
37    digitalWrite(LED, (now / 500) % 2 ? HIGH : LOW);        // yanıp sönen LED / blinking LED
38    digitalWrite(BUZZER, (now % 2000) < 100 ? HIGH : LOW);  // 2 sn'de bir kısa bip / short beep every 2 s
39  } else {
40    digitalWrite(LED, LOW);
41    digitalWrite(BUZZER, LOW);
42  }
43
44  if (now - lastPrint >= 1000) {
45    lastPrint = now;
46    Serial.print(F("Alev / Flame: "));
47    Serial.print(flame ? 1 : 0);
48    Serial.print(F("  MQ-2: "));
49    Serial.print(gas);
50    Serial.print(F("  Seviye / Level: "));
51    Serial.println(level);
52  }
53}

Подключи выход AO датчика MQ-2 к A1 и питай модуль от 5V; датчик пламени может остаться на D2. Задай SMOKE_LIMIT заметно выше значения, которое показывает датчик после нескольких минут работы на чистом воздухе, как описано в руководстве по MQ-2. Первые 60 секунд условие дыма игнорируется, потому что холодный MQ-2 стартует с высоких показаний. Время удержания 300 мс для сигнала пламени (HOLD_MS) превращает короткие переключения выхода DO, вызванные мерцанием пламени, в одно непрерывное обнаружение. Если эту связку нужно перенести на ESP32, учти: MQ-2 нужно 5 V, и его выход AO может выдавать до 5 V, поэтому на его выход обязательно нужен делитель напряжения, а датчик пламени работает напрямую от 3V3.

Уведомления о пожаре на телефон с ESP32 (Telegram)

Чтобы сигнализация предупреждала не только тех, кто в комнате, но и тебя, когда тебя нет дома, можно использовать ESP32. Проще всего это сделать с ботами Telegram: они бесплатны, не требуют своего сервера, а сообщение мгновенно приходит на телефон в виде уведомления. Код ниже включает зуммер и отправляет сообщение в Telegram, когда пламя видно 1,5 секунды, а между сообщениями выжидает не меньше минуты, чтобы телефон не засыпало сообщениями об одном и том же пожаре. Настройку бота и двустороннее управление командами подробно разбираем в статье Telegram-бот на ESP32.

  1. В Telegram напиши @BotFather, отправь команду /newbot, дай боту имя и скопируй выданный токен.
  2. Открой бот для получения ID, например @userinfobot, и нажми Start («Запустить»); в ответ он пришлёт твой chat ID.
  3. Найди своего нового бота в Telegram и нажми Start; без этого шага бот не сможет присылать тебе сообщения.
  4. В Arduino IDE установи через «Менеджер библиотек» библиотеки UniversalTelegramBot и ArduinoJson.
  5. Замени в коде имя сети Wi-Fi, пароль, токен и chat ID на свои, выбери плату ESP32 и загрузи код.
C++ (Arduino IDE)
1// ESP32 alev alarmı + Telegram bildirimi / ESP32 flame alarm + Telegram notification
2#include <WiFi.h>
3#include <WiFiClientSecure.h>
4#include <UniversalTelegramBot.h>        // ArduinoJson kütüphanesi de gerekir / also needs the ArduinoJson library
5
6const char* WIFI_SSID = "WIFI_ADI";      // Wi-Fi ağının adı / your Wi-Fi name
7const char* WIFI_PASS = "WIFI_SIFRESI";  // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:ABCdefGhIJKlmNoPQRstuVWXyz"  // BotFather'dan / from BotFather
9#define CHAT_ID "123456789"              // senin chat ID'n / your chat ID
10
11const int FLAME_DO = 27;                 // modülün DO pini / module DO pin
12const int BUZZER = 25;                   // aktif buzzer / active buzzer
13const int LED = 26;                      // kırmızı LED (220 Ω ile) / red LED (with 220 Ω)
14const int FLAME_ACTIVE = LOW;
15const unsigned long HOLD_MS = 300;       // DO'daki kısa kesintileri yok say / ignore short gaps on DO
16const unsigned long CONFIRM_MS = 1500;   // alev bu kadar sürmeli / flame must last this long
17const unsigned long COOLDOWN_MS = 60000; // iki mesaj arası en az 1 dk / at least 1 min between messages
18
19WiFiClientSecure client;
20UniversalTelegramBot bot(BOT_TOKEN, client);
21
22unsigned long lastFlame = 0;
23unsigned long flameStart = 0;
24unsigned long lastMessage = 0;
25bool messageSent = false;
26
27void setup() {
28  Serial.begin(115200);
29  pinMode(FLAME_DO, INPUT);
30  pinMode(BUZZER, OUTPUT);
31  pinMode(LED, OUTPUT);
32
33  WiFi.mode(WIFI_STA);
34  WiFi.begin(WIFI_SSID, WIFI_PASS);
35  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);  // api.telegram.org kök sertifikası / root certificate
36  unsigned long start = millis();
37  while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) {  // en fazla 15 sn bekle / wait up to 15 s
38    delay(500);
39    Serial.print(".");
40  }
41  if (WiFi.status() == WL_CONNECTED) {
42    Serial.println(WiFi.localIP());
43    bot.sendMessage(CHAT_ID, "Yangin alarmi devrede / Fire alarm is online", "");
44  }
45}
46
47void loop() {
48  unsigned long now = millis();
49  if (digitalRead(FLAME_DO) == FLAME_ACTIVE) lastFlame = now;
50  bool flame = lastFlame > 0 && now - lastFlame < HOLD_MS;
51  if (!flame) flameStart = now;          // alev yoksa sayaç sıfırlanır / timer resets without flame
52  bool alarm = now - flameStart >= CONFIRM_MS;
53
54  digitalWrite(LED, alarm ? HIGH : LOW);
55  digitalWrite(BUZZER, (alarm && (now / 200) % 2) ? HIGH : LOW);  // kesik siren / beeping siren
56
57  if (alarm && (!messageSent || now - lastMessage >= COOLDOWN_MS)) {
58    if (WiFi.status() == WL_CONNECTED) {
59      bool ok = bot.sendMessage(CHAT_ID, "ALEV ALGILANDI! / FLAME DETECTED!", "");
60      Serial.println(ok ? "Mesaj gitti / Message sent" : "Gonderilemedi / Send failed");
61    } else {
62      WiFi.reconnect();                  // bağlantı koptuysa yeniden dene / reconnect if the link dropped
63    }
64    lastMessage = now;                   // başarısızsa 1 dk sonra yeniden dener / retries after 1 min if it failed
65    messageSent = true;
66  }
67  delay(10);
68}

Вызов sendMessage() открывает защищённое HTTPS-соединение, поэтому может занять секунду-две; в это время ритм сигнала зуммера ненадолго замирает, и это нормально. При запуске код до 15 секунд пытается подключиться к Wi-Fi; если подключения нет, сигнализация продолжает работать локально, а неотправленное сообщение повторяется через минуту, так что зуммер звучит и без интернета. Если на ESP32 нужно читать ещё и выход AO, всегда подключай его к пину ADC1 (GPIO 32–39), потому что пины ADC2 нельзя использовать при включённом Wi-Fi; поэтому в таблице выбран GPIO 34. Безопасные пины своей платы можно посмотреть в утилите распиновки. Если активный зуммер на 5 V звучит слабо от пина 3,3 V, управляй им от 5 V через транзистор. Для сарая или дачи без Wi-Fi ту же сигнализацию можно сделать с отправкой SMS через GSM-модуль SIM800L.

Датчик пламени с Raspberry Pi Pico и MicroPython

На Raspberry Pi Pico действует та же логика. Питай модуль от пина 3V3(OUT), подключи DO к GP15, а AO, если он есть, — к GP26. На линии DO у модуля есть свой подтягивающий резистор, поэтому встроенная подтяжка Pico не нужна. АЦП у Pico 12-битный, но read_u16() в MicroPython масштабирует результат до 0–65535, так что аналогом 1023 на Arduino здесь будет примерно 65535. Код использует время удержания 300 мс, которое прощает короткие пропадания сигнала на DO, и подтверждение за 1,5 секунды:

MicroPython
1# Raspberry Pi Pico alev alarmı / Raspberry Pi Pico flame alarm
2from machine import Pin, ADC
3import time
4
5flame_do = Pin(15, Pin.IN)      # modülün DO pini / module DO pin
6flame_ao = ADC(26)              # GP26 = ADC0, 4 pinli modülde AO / AO on the 4-pin module
7buzzer = Pin(14, Pin.OUT)       # aktif buzzer / active buzzer
8led = Pin(13, Pin.OUT)          # kırmızı LED (220 Ω ile) / red LED (with 220 Ω)
9
10FLAME_ACTIVE = 0                # çoğu modülde alev = 0, KY-026'da 1 / most modules: flame = 0, KY-026: 1
11HOLD_MS = 300                   # DO'daki kısa kesintileri yok say / ignore short gaps on DO
12CONFIRM_MS = 1500               # alev bu kadar sürmeli / flame must last this long
13
14last_flame = None
15flame_start = time.ticks_ms()
16last_print = time.ticks_ms()
17
18while True:
19    now = time.ticks_ms()
20    if flame_do.value() == FLAME_ACTIVE:
21        last_flame = now
22    flame = last_flame is not None and time.ticks_diff(now, last_flame) < HOLD_MS
23    if not flame:
24        flame_start = now       # alev yoksa sayaç sıfırlanır / timer resets without flame
25    alarm = time.ticks_diff(now, flame_start) >= CONFIRM_MS
26
27    led.value(1 if alarm else 0)
28    buzzer.value(1 if alarm and (now // 200) % 2 else 0)   # kesik siren / beeping siren
29
30    if time.ticks_diff(now, last_print) >= 500:   # yarım saniyede bir yaz / print every half second
31        last_print = now
32        print(flame_ao.read_u16(), "ALARM" if alarm else "-")
33    time.sleep_ms(10)

При запуске кода в Thonny значение AO и состояние тревоги видны в окне Shell (оболочка); если открыть плоттер (Plotter) через меню «Вид» (View), значения можно наблюдать в виде графика. Чтобы программа запускалась автоматически при подаче питания на Pico, сохрани файл на Pico под именем main.py. Для отсчёта времени важно использовать time.ticks_diff(), потому что счётчик ticks_ms() после определённого значения начинает отсчёт заново, и простое вычитание в этот момент даёт неверный результат.

Идеи проектов с датчиком пламени

  • Пожарная сигнализация для кухни: собери сигнализацию с датчиком пламени, направленным на варочную панель, и MQ-2 по двухуровневой логике, описанной выше.
  • Напоминание о забытой плите: если пламя видно непрерывно дольше 30 минут, пусть звучит зуммер и на телефон уходит сообщение.
  • Робот-пожарный: найди направление на пламя 5-канальным датчиком, веди робота к нему с помощью L298N и DC-моторов и потуши свечу мини-насосом для воды.
  • Сканер направления пламени: закрепи один датчик на сервоприводе, проведи его от 0 до 180 градусов и выведи на экран угол с самым сильным сигналом.
  • Панель безопасности умного дома: объедини датчики пламени, газа и движения на одной плате; подробности — в статье умный дом на Arduino.
  • Сторож мастерской: когда рядом с паяльной станцией появляется неожиданное пламя, включай сигнальную лампу через реле.
  • Соревнование по тушению свечи: как на школьных соревнованиях роботов, сделай робота, который как можно быстрее находит и тушит свечу в лабиринте; для начала хватит одного датчика пламени.

Частые ошибки и их решение

СимптомВероятная причинаРешение
Светодиод DO горит постоянно, тревога не прекращаетсяПорог слишком чувствительный, или датчик смотрит на солнце или лампу накаливанияБез пламени крути потенциометр, пока светодиод не погаснет, и отверни датчик от источника света
Зажигалка не вызывает никакой реакцииПорог слишком высокий, или пламя вне поля зрения 60 градусов, или слишком далекоПоверни потенциометр на несколько оборотов в сторону большей чувствительности и поднеси пламя ближе, прямо перед датчиком
Тревога звучит без пламени и замолкает при пламениВыход DO модуля активен при HIGH (например, KY-026)Поменяй в коде значение FLAME_ACTIVE на HIGH
Светодиод DO мерцает перед пламенемКомпаратор очень близко к порогу, и мерцание пламени переключает выходИспользуй в коде время удержания (HOLD_MS) или сделай порог чуть чувствительнее
Аналоговое значение не меняетсяУ 3-пинового модуля нет AO, или к аналоговому входу подключён пин DOВозьми 4-пиновый модуль и подключи его пин AO к аналоговому входу
Нажатие кнопки пульта вызывает тревогуИК-светодиод пульта от телевизора на 940 нмВключай тревогу только после подтверждения по времени не менее 1–2 секунд
Днём у окна ложные срабатывания, или пламя не видно вовсеСолнечный свет вызывает срабатывание или насыщает датчикРазмести датчик так, чтобы он не смотрел на солнце, используй чёрную трубку и добавь анализ мерцания
На ESP32 значение AO портится после включения Wi-FiAO подключён к пину ADC2Подключи AO к пину ADC1 в диапазоне GPIO 32–39
Зуммер очень тихий на ESP32 или PicoАктивный зуммер на 5 V управляется от пина 3,3 VВозьми зуммер на 3,3 V или управляй зуммером от 5 V через транзистор
Есть безопасный способ проверить датчик, не зажигая огня: направь на него пульт от телевизора с расстояния в несколько сантиметров и нажми кнопку. Если ИК-светодиод пульта на 940 нм заставляет мигать светодиод DO, датчик и подключение работают. Не путай этот модуль с ИК-приёмником, который декодирует сигналы пульта: ИК-приёмник реагирует только на сигнал, модулированный частотой 38 kHz, а датчик пламени измеряет сырое количество инфракрасного света.
Сигнализация на датчике пламени — это учебный проект, а не сертифицированный пожарный извещатель. Для защиты жизни дома используй дымовой извещатель, соответствующий EN 14604, а свою схему считай дополнительной системой к нему. При испытаниях используй только небольшое контролируемое пламя, например зажигалку или свечу, держи горючие материалы подальше, никогда не оставляй пламя без присмотра, а детям и подросткам лучше проводить опыт вместе со взрослыми. Не ставь датчик вплотную к пламени: рабочая температура приёмника ограничена примерно 85 °C, и перегретый корпус может необратимо повредиться.

Датчик пламени — дешёвая, но поучительная деталь, которая сразу учит физике инфракрасного света, схемам на компараторах и борьбе с ложными срабатываниями. Начни с простой сигнализации на DO, а затем шаг за шагом усиливай систему аналоговым чтением, анализом мерцания и MQ-2; для более полной охранной системы загляни в статью охранная сигнализация на Arduino. В приложении BlueGrays есть проекты «Датчик пламени», «Сигнализация с датчиками пламени и газа», «Детектор дыма на ESP32 и MQ-2» и «Охранная система на ESP32 с уведомлениями в Telegram» — с пошаговыми схемами подключения и готовым кодом.

Частые вопросы

На каком расстоянии датчик пламени обнаруживает огонь?

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

Влияет ли солнечный свет на датчик пламени?

Да. Солнечный свет очень силён в диапазоне 760–1100 нм, на который реагирует датчик; прямое солнце или его отражение от стекла вызывает ложные срабатывания и может ослепить датчик, так что настоящее пламя он пропустит. Размести датчик так, чтобы он не смотрел на солнце, сузь его поле зрения чёрной трубкой и используй программное подтверждение по времени и анализ мерцания.

Что выдаёт датчик пламени при обнаружении огня: LOW или HIGH?

На распространённых синих модулях с LM393 пин DO обычно в состоянии HIGH, при виде пламени переходит в LOW, и загорается светодиод DO. На некоторых платах, например KY-026, при обнаружении пламени выход переходит в HIGH. Проверь свой модуль зажигалкой и настрой сравнение в коде по значению в мониторе порта.

Работает ли датчик пламени от 3,3 V?

Да, эти модули работают от 3,3 до 5 V. На ESP32 или Raspberry Pi Pico питание модуля от пина 3V3 удерживает выходы DO и AO ниже 3,3 V, поэтому их можно подключать к пинам напрямую. Если питать модуль от 5 V, для этих плат на выходах нужны делители напряжения.

Как настроить чувствительность датчика пламени?

Когда пламени нет, поверни синий многооборотный потенциометр на плате до точки, где светодиод DO только что погас, затем ещё на пол-оборота в сторону меньшей чувствительности. Потом проверь датчик зажигалкой на самом большом расстоянии, на котором нужно обнаруживать пламя. Потенциометр меняет только порог DO; для AO порог задаётся в коде.

Может ли датчик пламени заменить пожарный извещатель?

Нет. Любительский датчик пламени можно обмануть солнечным светом, лампами накаливания и пультами, он не видит пожар вне поля зрения или тление без пламени и не испытан ни по какому стандарту. Для защиты жизни используй дымовой извещатель, соответствующий EN 14604, а свою схему считай дополнительной системой оповещения.

Все проекты
Работа с зуммером
#13Новичок

Работа с зуммером

Интересно, как дверной звонок или сигнализация издают звук? Arduino заставляет маленький зуммер пищать через короткие промежутки: пик, пауза, пик, пауза. Ты видишь, как электричество превращается в зв

4.7(89)
161
Измерение освещённости с LDR
#11Новичок

Измерение освещённости с LDR

Хочешь увидеть яркость своей комнаты в виде числа? LDR — маленькая деталь, реагирующая на свет, — измеряет освещённость вокруг, а Arduino каждые полсекунды выводит значение на экран компьютера. Закрой

4.6(81)
139
Работа с датчиком пламени
#50Средний
Premium

Работа с датчиком пламени

Маленький страж, который замечает огонь на кухне или в мастерской раньше тебя. Датчик пламени улавливает невидимый свет, который испускает огонь; пока всё в порядке, горит зелёный светодиод, а когда о

4.6(33)
44
Сигнализация пламени и газа
#52Продвинутый
Premium

Сигнализация пламени и газа

Маленький страж, который сразу предупреждает, когда где-то утекает газ или появляется пламя. Датчик газа следит за газом в воздухе, а датчик пламени — за светом огня; пока всё в порядке, горит зелёный

4.8(52)
67
Работа с датчиком газа
#51Новичок
Premium

Работа с датчиком газа

Маленький страж, который замечает утечку газа на кухне раньше тебя. Датчик газа всё время «принюхивается» к воздуху; пока всё в порядке, горит зелёный светодиод, а когда газа в воздухе становится боль

4.6(37)
50
Сигнализация газа и дыма MQ-2 на ESP32
#122Средний

Сигнализация газа и дыма MQ-2 на ESP32

В этом проекте модуль датчика газа MQ-2 обнаруживает горючие газы (сжиженный газ, метан, пропан) и дым, а при обнаружении пассивный зуммер играет тревогу, похожую на сирену. Цифровой пороговый выход датчика (DO) подключён к GPIO 4 у ESP32; когда газ или дым превышают порог, DO переходит в LOW, и срабатывает тревога. Чувствительность настраивается потенциометром модуля. Пассивный зуммер управляется через tone() и даёт сирену на двух частотах.

4.7(28)
43
Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)
#145Продвинутый
Premium

Сигнализация движения на ESP32 (PIR + зуммер + светодиод + Telegram)

Умная охранная сигнализация, которая при обнаружении движения PIR-датчиком включает зуммер и светодиод и одновременно сразу отправляет владельцу уведомление в Telegram. В ней есть 30-секундная пауза, ограничивающая частоту повторных тревог; этот механизм не проверяет срабатывания PIR и не устраняет ложные тревоги. Подходит для дома, гаража, склада или мастерской. С ESP32-CAM можно добавить уведомления с фото, а с обычной ESP32 DevKit V1 приходят текстовые.

0.0(0)
9