DIY ELECTRONICSTR

← All projects

Flame-Sensing Fire Alarm

Beginner30 min

A fire alarm that recognises a flame by the infrared light it gives off: when the flame sensor sees a lighter or a candle flame, the buzzer plays a rising siren and the red and blue LEDs flash in turn like a fire engine's lights. While idle, the blue LED blinks briefly every 2 seconds to show the alarm is on watch. The alarm does not sound until a flame has lasted half a second, so a single spark or glint does not set it off, and it keeps sounding for 3 seconds after the flame is out. It teaches smoothing the on-and-off digital signal of a flickering flame, filtering out short flashes with a time condition, and playing a siren with millis() while reading the sensor. No extra library is needed. This is a learning project; it does not replace an approved smoke detector at home.

Build it step by step in the app

What you need

Wiring steps

  1. 1

    Connect the power rails (5V and GND)

    Connect the power rails (5V and GND)

    In this project every part sits in the top half of the breadboard (rows F–J) and on the top power rails. The Arduino's power header is at its bottom edge, so the power goes to the bottom rails first and from there to the top ones. Connect one of the GND pins on the Arduino's power header to the breadboard's bottom blue (−) rail with a black male-male wire, and the 5V pin on the same header to the bottom red (+) rail with a red wire. At the right end of the breadboard, join the bottom (+) rail to the top (+) rail with a red wire and the bottom (−) rail to the top (−) rail with a black wire: the breadboard's top and bottom rails are not connected to each other.

    • Arduino GND → the bottom blue (−) rail (black wire)
    • Arduino 5V → the bottom red (+) rail (red wire)
    • the bottom red (+) rail → the top red (+) rail (red wire)
    • the bottom blue (−) rail → the top blue (−) rail (black wire)
  2. 2

    Add and wire the buzzer

    Add and wire the buzzer

    Plug the passive buzzer's + leg into column 12 in row F of the breadboard's top half and its other leg into column 13; the + leg is usually the longer one and the body has a + mark. Connect the Arduino's pin 8 to column 12 with an orange male-male wire (BUZZER_PIN 8). Connect column 13 to the top blue (−) rail with a short black wire.

    • buzzer + leg → column 12, top half
    • buzzer − leg → column 13, top half
    • Arduino pin 8 → column 12, top half (orange wire)
    • column 13, top half → the top blue (−) rail (black wire)
  3. 3

    Add the blue LED with its resistor

    Add the blue LED with its resistor

    Plug the blue LED's long leg (+) into column 18 in row F of the top half and its short leg (−) into column 19. Put one end of a 220 Ω resistor in row J of column 19 and the other end in the top blue (−) rail. Connect the Arduino's pin 9 to column 18 with a blue wire (BLUE_LED 9). The resistor limits the current through the LED. The blue LED is the alarm's watch light: while idle it blinks briefly every 2 seconds, and it stays on while the sensor sees a flame.

    • blue LED long leg (+) → column 18, top half
    • blue LED short leg (−) → column 19, top half
    • blue LED's resistor (leg 1) → column 19, top half
    • blue LED's resistor (leg 2) → the top blue (−) rail
    • Arduino pin 9 → column 18, top half (blue wire)
  4. 4

    Add the red LED with its resistor

    Add the red LED with its resistor

    Plug in the red LED the same way: long leg (+) in column 24 of row F, short leg (−) in column 25. Put the second 220 Ω resistor from row J of column 25 to the top (−) rail. Connect the Arduino's pin 10 to column 24 with a yellow wire (RED_LED 10). While the alarm sounds, the red and blue LEDs flash in turn like a fire engine's lights.

    • red LED long leg (+) → column 24, top half
    • red LED short leg (−) → column 25, top half
    • red LED's resistor (leg 1) → column 25, top half
    • red LED's resistor (leg 2) → the top blue (−) rail
    • Arduino pin 10 → column 24, top half (yellow wire)
  5. 5

    Connect the flame sensor and set its threshold

    Connect the flame sensor and set its threshold

    Push the female ends of male-female wires onto the flame sensor's pins; the pin names are printed on the board. Connect DO straight to the Arduino's pin 11 with a green wire (FLAME_PIN 11), GND to the top blue (−) rail with a black wire, and VCC to the top red (+) rail with a red wire. Point the black receiver at the sensor's tip towards where the flame will be; it sees about a 60° cone. After uploading the code, set the threshold: the board has two small lights, one for power and one (the DO light) that comes on when it sees a flame. If the DO light is on with no flame around, turn the screw on the blue trimmer with a small screwdriver until the light goes out, then a little further. Sunlight and incandescent bulbs give off infrared light too, so do not point the sensor at a window or a lamp.

    • Arduino pin 11 → flame sensor DO (green wire)
    • flame sensor GND → the top blue (−) rail (black wire)
    • flame sensor VCC → the top red (+) rail (red wire)

Arduino sketch

// The flame sensor's DO output: LOW when
// it sees a flame
const int FLAME_PIN = 11;
// The buzzer's and the two LEDs' pins
const int BUZZER_PIN = 8;
const int BLUE_LED = 9;
const int RED_LED = 10;

// A flame flickers, so DO does too: seen
// again within this, it is still there
const unsigned long FLICKER_HOLD = 300;
// A flame lasting this long sounds the
// alarm (a spark or a glint does not)
const unsigned long CONFIRM_TIME = 500;
// It keeps sounding this long after the
// flame is out
const unsigned long CLEAR_TIME = 3000;
// The siren's lowest and highest tones
// (Hz)
const int SIREN_LOW = 800;
const int SIREN_HIGH = 2000;

unsigned long lastFlame = 0;
unsigned long flameSince = 0;
bool flameSeen = false;
bool alarmOn = false;
unsigned long alarmStart = 0;
int playing = 0;

void setup() {
  // A loose wire reads HIGH: no alarm
  pinMode(FLAME_PIN, INPUT_PULLUP);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BLUE_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  Serial.begin(9600);

  // Listen for 2 s: always seeing a flame
  // means the threshold may be too keen
  Serial.println("Checking the sensor...");
  int seen = 0;
  for (int i = 0; i < 100; i++) {
    if (digitalRead(FLAME_PIN) == LOW) seen++;
    digitalWrite(BLUE_LED, (i / 10) % 2 ? HIGH : LOW);
    delay(20);
  }
  digitalWrite(BLUE_LED, LOW);
  if (seen > 90) {
    Serial.println("The sensor sees a flame all the time.");
    Serial.println("With no flame around, turn the screw on");
    Serial.println("the board until its DO light goes out.");
  }
  Serial.println("Alarm set. To test it, light a lighter");
  Serial.println("30-50 cm away from the sensor.");
}

// Siren: rises from low to high every
// second, the LEDs take turns like a
// fire engine's
void updateOutputs(unsigned long now) {
  int hz = 0;
  if (alarmOn) {
    unsigned long t = (now - alarmStart) % 1000;
    hz = SIREN_LOW + (long)(SIREN_HIGH - SIREN_LOW) * t / 1000;
    // 20 Hz steps: fewer tone() calls
    hz = hz / 20 * 20;
    bool redTurn = (now - alarmStart) / 150 % 2 == 0;
    digitalWrite(RED_LED, redTurn ? HIGH : LOW);
    digitalWrite(BLUE_LED, redTurn ? LOW : HIGH);
  } else {
    digitalWrite(RED_LED, LOW);
    // On watch: blue blinks every 2 s,
    // and stays on while it sees a flame
    bool blink = now % 2000 < 100;
    digitalWrite(BLUE_LED, flameSeen || blink ? HIGH : LOW);
  }
  if (hz != playing) {
    playing = hz;
    if (hz > 0) {
      tone(BUZZER_PIN, hz);
    } else {
      noTone(BUZZER_PIN);
    }
  }
}

void loop() {
  unsigned long now = millis();
  if (digitalRead(FLAME_PIN) == LOW) lastFlame = now;
  bool flame = lastFlame > 0 && now - lastFlame < FLICKER_HOLD;

  if (flame && !flameSeen) {
    flameSince = now;
    if (!alarmOn) Serial.println("Flame seen...");
  }
  if (!flame && flameSeen && !alarmOn) {
    Serial.println("Too short, no alarm.");
  }
  flameSeen = flame;

  // Timed up to when it was last seen
  if (!alarmOn && flame && lastFlame - flameSince >= CONFIRM_TIME) {
    alarmOn = true;
    alarmStart = now;
    Serial.println("FIRE ALARM! Flame detected.");
  }
  if (alarmOn && now - lastFlame >= CLEAR_TIME) {
    alarmOn = false;
    Serial.print("Flame out, alarm stopped (it lasted ");
    Serial.print((now - alarmStart) / 1000);
    Serial.println(" s).");
  }
  updateOutputs(now);
}

What the Serial Monitor shows

SERIAL MONITOR · 9600 BAUD
Checking the sensor...
Alarm set. To test it, light a lighter
30-50 cm away from the sensor.
Flame seen...
Too short, no alarm.
Flame seen...
FIRE ALARM! Flame detected.
Flame out, alarm stopped (it lasted 7 s).

If a wire is loose

SERIAL MONITOR · 9600 BAUD
Checking the sensor...
The sensor sees a flame all the time.
With no flame around, turn the screw on
the board until its DO light goes out.
Alarm set. To test it, light a lighter
30-50 cm away from the sensor.
Flame seen...
FIRE ALARM! Flame detected.

What you will see

At start the blue LED blinks for 2 seconds while the Arduino listens to the sensor. Then "Alarm set" appears in the Serial Monitor and the blue LED starts blinking briefly every 2 seconds. To test it, light a lighter 30-50 cm from the sensor: as soon as the sensor sees the flame the blue LED stays on, and once the flame has lasted half a second the buzzer plays a siren rising from low to high while the red and blue LEDs flash in turn. Put the lighter out and the alarm sounds for 3 more seconds, then stops; the Serial Monitor shows how long it lasted. Light the lighter only very briefly and "Too short, no alarm" appears. If the alarm never sounds, watch the board's DO light: if it stays off with a flame in front of it, turn the trimmer the other way or bring the lighter closer; if it lights up but the alarm stays quiet, check that the green wire is on pin 11. If the alarm goes off by itself, or "The sensor sees a flame all the time" appears at start, the sensor is seeing the sun or a lamp, or the threshold is too keen: point the sensor elsewhere and turn the trimmer until the DO light goes out. Safety: use the lighter or candle away from anything that burns, with an adult, and never leave a flame unattended; this project does not replace an approved smoke detector at home.

In the app, tick off every wire, match the parts to your inventory and pick up where you left off.

Build it step by step in the app