A Flame Sensor With AO and DO Outputs: an Alarm With a Buzzer
An IR flame sensor sees a lighter flame a metre away, but it "sees" the sun just as well. We look at the analog and digital outputs of the LM393 comparator module, set the threshold, and build an alarm that does not shriek at a patch of sunlight.
About the project
A flame sensor module is an IR phototransistor sensitive to 760–1100 nm plus an LM393 comparator. An open flame radiates exactly in that range, so the module notices a lighter or a candle up to a metre away. It is a learning sensor, not a fire protection system: a home needs certified smoke alarms. But as an extra "guard" for a 3D printer, a soldering station or a barbecue it is great.
What you need
- ESP32 DevKit
- A flame sensor module (4 pins: AO, GND, VCC, DO)
- An active or passive buzzer
Wiring
| Module | ESP32 |
|---|---|
| AO | GPIO34 (ADC1) |
| GND | GND |
| VCC (+) | 3V3 |
| DO | GPIO27 |
| Buzzer + | GPIO25 |
| Buzzer − | GND |
Two outputs
- AO is the analog signal from the phototransistor. More IR means a lower voltage: about VCC with no flame, almost 0 with a fire right next to it.
- DO is the comparator output: LOW when there is a flame (the signal is above the threshold). The blue trimmer sets the threshold, and the green LED on the board lights when it trips.
DO is handy for an interrupt or simple logic; AO tells you how close the fire is and lets you set the threshold in code.
Code
// Fire alarm: flame sensor (AO + DO) and a buzzer
const int FLAME_AO = 34; // analog: lower = more IR
const int FLAME_DO = 27; // digital: LOW = flame (threshold set by the trimmer)
const int BUZZER = 25;
void setup() {
Serial.begin(115200);
pinMode(FLAME_DO, INPUT);
}
void loop() {
int raw = analogRead(FLAME_AO);
int level = map(raw, 4095, 0, 0, 100); // 0 % = nothing, 100 % = a flame right at the sensor
bool flame = digitalRead(FLAME_DO) == LOW;
if (flame) tone(BUZZER, 2000);
else noTone(BUZZER);
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 500) {
lastPrint = millis();
Serial.printf("IR %3d %% %s\n", level, flame ? "FIRE!" : "ok");
}
delay(20);
}
In the simulator raise "Flame" in the sensor properties — somewhere past 50 % DO trips and the buzzer sounds. Try switching on "Direct sunlight": the alarm goes off without any fire.
Not being scared by the sun
- A tube. Limit the sensor's field of view with a black tube — sunlight from the window stops reaching it.
- Flicker. A flame flickers at 1–15 Hz, while the sun and incandescent bulbs shine steadily. Take 50 AO readings per second and look at the spread: a fire makes it swing.
- A second sensor. Put a thermistor or an MQ-2 (smoke/gas) next to the flame sensor and sound the alarm only when both agree.
- A passive buzzer sounds with
tone(), an active one simply with HIGH. For an active buzzer replacetone()withdigitalWrite(BUZZER, HIGH).