The most reliable and accessible fire sensor for Arduino beginners is the KY-026 (or HW-201) 4-pin IR flame sensor module. It detects 760nm to 1100nm infrared light emitted by combustion, outputting both a digital HIGH/LOW signal and an analog voltage (0-5V) proportional to flame proximity. While the digital pin is useful for simple alarms, the analog output allows you to gauge distance and filter out ambient IR noise from sunlight or incandescent bulbs.

Project Specifications

  • Difficulty Rating: 2/5 (Beginner-friendly, basic analog I/O)
  • Estimated Time: 20 minutes
  • Target Board Variant: Arduino Uno R3 (ATmega328P, 5V logic)
  • Estimated Cost: ~$8.00 (Uno clone + sensor module)

Parts List and Pin Mapping for the KY-026 Fire Sensor

Before stripping wires, verify your module. The KY-026 uses an LM393 dual comparator IC to process the signal from the IR photodiode. Cheap clones sometimes omit the 10kΩ pull-up resistors or solder the photodiode backwards. Ensure your module has 4 pins: AO, DO, GND, and VCC.

KY-026 Sensor Pin Arduino Uno R3 Pin Wire Color (Std) Function / Notes
VCC 5V Red Powers the LM393 and IR diode. Do not use 3.3V.
GND GND Black Common ground reference.
AO (Analog Out) A0 Yellow Outputs 0-5V inversely proportional to IR intensity.
DO (Digital Out) D8 (Optional) Blue Outputs LOW when flame is detected (threshold set by trimpot).

Additional Components: 5V active buzzer (connect to D9), 220Ω current-limiting resistor for the buzzer (optional but recommended for pin protection), and male-to-female jumper wires.

Step-by-Step Wiring and Calibration Procedure

Bench Tip: The IR photodiode on the KY-026 is highly directional, with a detection cone of roughly 60 degrees. It must physically face the flame. Furthermore, the blue potentiometer on the module only adjusts the digital (DO) threshold. It does absolutely nothing to the analog (AO) output. Do not waste time turning the pot if you are reading analog values.
  1. De-energize the board: Ensure the Arduino Uno is unplugged from USB before making connections to prevent accidental shorts on the 5V rail.
  2. Connect Power: Route the red jumper from the sensor VCC to the Arduino 5V pin, and black from GND to Arduino GND.
  3. Connect Analog Signal: Route the yellow jumper from the sensor AO pin to Arduino A0.
  4. Wire the Buzzer: Connect the buzzer's positive leg to Arduino D9 (via a 220Ω resistor if using a bare piezo, or directly if it's an active buzzer module with an onboard driver). Connect the buzzer negative leg to GND.
  5. Calibrate Ambient Baseline: Plug in the Arduino, open the Serial Monitor at 9600 baud, and upload a basic analogRead(A0) sketch. Note the baseline value in a well-lit room (usually between 800 and 1023). Note: The KY-026 outputs a HIGH voltage (near 1023) when no flame is present, and the voltage drops toward 0 as flame intensity increases.
  6. Test with Flame: Flick a butane lighter 12 inches away from the sensor. The analog value should drop sharply (e.g., to 300-500). Move it closer (2 inches); it should drop near 0.

Complete Arduino Code with Analog Thresholding

The following code targets the Arduino Uno R3 (ATmega328P). It uses a software rolling average to filter out 100/120Hz flicker caused by ambient AC mains lighting, which often causes false triggers on raw analog reads. It also includes basic serial error handling.

/*
 * KY-026 Fire Sensor for Arduino Uno R3
 * Target: ATmega328P (5V Logic)
 * Features: Rolling average filter, hysteresis thresholding
 */

#define FLAME_AO_PIN A0
#define BUZZER_PIN 9
#define LED_PIN 13 // Built-in Uno LED

// Thresholds (Calibrate these based on your Serial Monitor readings)
#define FLAME_DETECTED_THRESHOLD 600  // Value drops BELOW this when flame is near
#define FLAME_CLEAR_THRESHOLD 750     // Hysteresis to prevent buzzer flickering

const int NUM_READINGS = 10;
int readings[NUM_READINGS];
int readIndex = 0;
long total = 0;
int average = 0;
bool fireAlarmState = false;

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 2000) {
    // Wait for serial port to connect, timeout after 2 seconds for standalone operation
  }
  
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);
  digitalWrite(LED_PIN, LOW);

  // Initialize array
  for (int i = 0; i < NUM_READINGS; i++) {
    readings[i] = 1023; // Assume no flame at startup
  }
  
  Serial.println("KY-026 Fire Sensor Initialized.");
}

void loop() {
  // Subtract the last reading
  total = total - readings[readIndex];
  
  // Read new value from analog pin
  int rawValue = analogRead(FLAME_AO_PIN);
  
  // Hardware fault check: if pin is floating or shorted to 5V constantly
  if (rawValue > 1023) rawValue = 1023; 
  
  readings[readIndex] = rawValue;
  total = total + readings[readIndex];
  readIndex = (readIndex + 1) % NUM_READINGS;
  
  average = total / NUM_READINGS;

  // Hysteresis logic for alarm state
  if (average < FLAME_DETECTED_THRESHOLD && !fireAlarmState) {
    fireAlarmState = true;
    digitalWrite(BUZZER_PIN, HIGH);
    digitalWrite(LED_PIN, HIGH);
    Serial.println("ALARM: FIRE DETECTED!");
  } 
  else if (average > FLAME_CLEAR_THRESHOLD && fireAlarmState) {
    fireAlarmState = false;
    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(LED_PIN, LOW);
    Serial.println("CLEAR: Flame extinguished.");
  }

  // Debug output
  Serial.print("Raw: ");
  Serial.print(rawValue);
  Serial.print(" | Avg: ");
  Serial.println(average);

  delay(50); // 20Hz sampling rate
}

Debugging: First Three Checks and Common Compilation Errors

When your fire sensor for Arduino fails to trigger, or the code refuses to compile, follow this decision path.

The First Three Things to Check When Hardware Fails

  1. VCC is 5V, not 3.3V: The LM393 comparator on the KY-026 requires adequate voltage headroom to drive the output rail-to-rail. If you wire VCC to the Uno's 3.3V pin, the analog output will max out around 680 instead of 1023, ruining your threshold math.
  2. IR Photodiode Orientation: Look closely at the black IR receiver. If it is completely opaque and not slightly translucent, or if the analog value never drops below 1000 even when a lighter is held 1 inch away, the diode is either dead or soldered backwards (a notorious issue on $1 Amazon multipacks).
  3. AC Mains Flicker Interference: If your serial monitor shows the analog value wildly bouncing between 400 and 600 near a desk lamp, your lamp is emitting IR (common with halogen/incandescent). Turn off the lamp or rely on the software rolling average provided in the code above.

Exact Compilation Error: expected unqualified-id before numeric constant

If you copy-paste code from forums, you will frequently encounter this exact error string in the Arduino IDE output pane:

error: expected unqualified-id before numeric constant
#define FLAME_AO_PIN A0;
^

Ranked Causes and Fixes:

  1. Trailing Semicolon in #define (90% of cases): The C++ preprocessor does a literal text replacement. If you write #define FLAME_AO_PIN A0;, the compiler replaces every instance of FLAME_AO_PIN with A0;. When it hits analogRead(A0;), it throws a syntax error. Fix: Remove the semicolon at the end of the #define line.
  2. Missing Pin Definitions (10% of cases): You deleted the #define block but left the variables in the setup() function. Fix: Ensure all pin constants are declared before void setup().

Extending or Simplifying the Build

Depending on your end goal, you can drastically alter the complexity of this circuit.

How to Simplify: If you only need a binary "fire / no fire" alert and don't care about proximity, abandon the analog pin entirely. Wire the sensor's DO (Digital Out) pin to Arduino D2. Use a small flathead screwdriver to turn the blue potentiometer on the module until the onboard DO LED turns off, then back it off slightly. In your code, simply use digitalRead(2). This offloads the threshold math to the LM393 hardware comparator and reduces your code to three lines.

How to Extend: For a practical home safety prototype, add a 5V relay module (like the SRD-05VDC-SL-C). Wire the Arduino D9 pin to the relay's IN pin. Connect a 12V solenoid water valve or a 120V AC exhaust fan to the relay's Normally Open (NO) and Common (COM) terminals. Safety Warning: Never switch mains voltage without proper enclosure, strain relief, and an inline fuse. If you are not comfortable with 120V AC, stick to 12V DC solenoids. You can also swap the Uno for an ESP32 and use the WiFi.h library to push MQTT alerts to Home Assistant when the analog threshold is breached.

Frequently Asked Questions

Can a fire sensor for Arduino detect smoke or just flames?

The KY-026 strictly detects infrared light (760-1100nm) emitted by flames. It cannot detect smoke, smoldering embers without a visible flame, or combustible gases. If you need smoke detection, you must pair it with an MQ-2 (combustible gas/smoke) or a photoelectric smoke sensor module. For comprehensive fire safety, use both.

Why does my fire sensor for Arduino trigger near my TV remote?

TV remotes use 940nm IR LEDs to transmit data to the receiver. This wavelength falls perfectly inside the KY-026's detection range. When you press a button on your remote, the sensor interprets the rapid IR pulses as a flame. To fix this in software, you can check the rate of change: a flame produces a relatively steady IR output, while a remote produces high-frequency square-wave pulses.

What is the maximum detection distance for the KY-026 flame sensor?

Under ideal, dark conditions, the KY-026 can detect a standard butane lighter flame up to 3 feet (approx. 1 meter) away. However, for a standard candle or a small electrical fire, the reliable detection distance drops to 12 to 18 inches. The inverse-square law applies heavily here; doubling the distance from the flame reduces the IR intensity hitting the photodiode by a factor of four.