ESP32 S3 UNO - Flame Sensor

This ESP32 S3 Uno flame sensor tutorial shows you how to wire an infrared flame sensor to the ESP32 S3 Uno form board and detect fire with Arduino code. The same module is often sold as a fire sensor or IR flame detector. You will see a "fire detected" message in the Serial Monitor, and also read how strong the flame is as a number.

In this tutorial, you will:

  1. Wire a flame sensor to the ESP32 S3 Uno.
  2. Detect fire using the digital DO output and digitalRead().
  3. Measure flame intensity from the analog AO output with analogRead().
  4. Adjust the fire sensor sensitivity with the on-board potentiometer.
ESP32 S3 Uno flame sensor

Once it works, you can extend the code to switch on a warning horn through a relay whenever a flame shows up.

Hardware Preparation

1×ESP32 S3 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Flame Sensor
1×5-in-1 5-way Flame Sensor
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of Flame Sensor

Before you write any code, it helps to know what the sensor actually measures. A flame sensor does not see fire the way you do. It looks for infrared light, and that is why it can react to a lighter even in a dark room.

infrared flame fire-sensor module

The module picks up the infrared light given off by a flame, so it is a simple way to build a fire detector. You may find it sold as an infrared flame sensor or a fire sensor. It gives you two signals at the same time: a digital output that is either LOW or HIGH, and an analog output that changes with the amount of infrared light.

The sensor is tuned to the infrared wavelengths that flames produce. This helps it ignore other heat sources such as your body or a room lamp. Still, it is not perfect. Sometimes it may report a flame that is not there, or miss one that is. Do not use it as your only safety device.

Pinout

You can buy this sensor in two versions. Both work with the same code in this tutorial.

Single flame sensor

The single module has four pins:

Pin Description
VCC Power input, 3.3V to 5V. On the ESP32 S3 Uno, use 3.3V
GND Ground (0V)
DO Digital output. HIGH when no flame is seen, LOW when a flame is seen. A potentiometer on the board sets the sensitivity
AO Analog output. The value goes up when there is more infrared light and goes down when there is less
Flame Sensor Pinout
image source: diyables.io

There are also two small LEDs on the board. The PWR-LED turns on when the module has power. The DO-LED turns on when the sensor detects a flame, which is handy for testing without any code.

5-in-1 flame sensor

The 5-in-1 module puts five flame sensors on one PCB. They share one potentiometer and the same VCC and GND pins. Each sensor still has its own DO and AO pin, so all five can detect flames on their own at the same time. Because each sensor faces a different direction, the module covers a much wider area than a single sensor.

How It Works

The two outputs work in different ways, so it is worth looking at them one by one.

The DO pin

The potentiometer on the module sets an infrared threshold. When the infrared level goes above this threshold, the sensor decides a flame is present: the DO pin goes LOW and the DO-LED lights up. When the infrared level stays below the threshold, no flame is detected: the DO pin stays HIGH and the DO-LED is off.

The AO pin

The AO pin gives a voltage that follows the infrared level. More infrared light gives a higher reading, and less infrared light gives a lower reading. The potentiometer has no effect on this pin, it only changes the DO threshold.

ESP32 S3 Uno Pinout

The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D2, A0…) and their GPIO numbers when you wire the flame sensor.

ESP32 S3 Uno pinout diagram

Wiring Diagram

The flame sensor has two outputs. You can connect just one of them or both, depending on what your project needs.

The wiring diagram between ESP32 S3 Uno Flame Sensor

This image is created using Fritzing. Click to enlarge image

Flame Sensor Pin ESP32 S3 Uno Pin
VCC 3.3V
GND GND
DO D2 (GPIO18)
AO A0 (GPIO2)

WARNING

ESP32 S3 Uno pins work at 3.3V and are NOT 5V tolerant. Power the flame sensor from 3.3V so the DO and AO signals never go above 3.3V. If you power it from 5V, the outputs can reach 5V, and you must add a voltage divider on DO and AO.

ESP32 S3 Uno Code - Read value from DO pin

This sketch reads the DO pin again and again. When the pin is LOW, it prints that a fire is detected. When the pin is HIGH, it prints that there is no flame.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-flame-sensor */ #define DO_PIN 18 // The ESP32 S3 Uno pin GPIO18 (D2) connected to DO pin of the flame sensor void setup() { // initialize serial communication Serial.begin(9600); // initialize the ESP32 S3 Uno's pin as an input pinMode(DO_PIN, INPUT); } void loop() { int flame_state = digitalRead(DO_PIN); if (flame_state == HIGH) Serial.println("The flame is NOT present => The fire is NOT detected"); else Serial.println("The flame is present => The fire is detected"); }

Detailed Instructions

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram.
  3. Connect the board to your computer with a USB Type-C cable.
  4. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  5. Copy the code above and paste it into the Arduino IDE.
  6. Upload the code by clicking the Upload button.
  7. Test it by pointing the flame sensor at a flame, such as a lighter.
  8. Check the result in the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
The flame is present => The fire is detected The flame is present => The fire is detected The flame is NOT present => The fire is NOT detected The flame is NOT present => The fire is NOT detected The flame is NOT present => The fire is NOT detected The flame is present => The fire is detected The flame is present => The fire is detected The flame is present => The fire is detected
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: If the DO-LED stays on all the time, or stays off even with a flame in front of the sensor, turn the potentiometer slowly until the LED reacts the way you expect.

ESP32 S3 Uno Code - Read value from AO pin

This sketch reads the analog AO pin and prints the raw number to the Serial Monitor. The higher the number, the stronger the infrared light from the flame.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-flame-sensor */ #define AO_PIN 2 // The ESP32 S3 Uno pin GPIO2 (A0) connected to AO pin of the flame sensor void setup() { // initialize serial communication Serial.begin(9600); // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); } void loop() { int flame_value = analogRead(AO_PIN); // 0 to 4095 on the ESP32 S3 Uno (12-bit ADC) Serial.println(flame_value); }

The ESP32 S3 Uno ADC can only measure a small voltage by default. The line analogSetAttenuation(ADC_11db) sets 11 dB attenuation, so the analog pin can read the full range from 0V up to about 3.3V. Without it, readings hit 4095 too early and the flame values look wrong. The ADC is 12-bit, so the value goes from 0 to 4095.

Detailed Instructions

  1. Copy the code above and open it in the Arduino IDE.
  2. Upload the code by clicking the Upload button.
  3. Test it by moving a flame toward the sensor and then away from it.
  4. Check the result in the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
580 824 904 2052 2788 3836 3860 4020 4024 4064 4076 2644 2180 1364 688
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: Write down the value with no flame and the value with a flame close by. A threshold between these two numbers works well for your own fire alarm.

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step. The demo in the video uses this code, which shows the fire state on an LCD 20x4 and flashes an LED and a buzzer when a flame is found:

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-flame-sensor */ #include <Wire.h> #include <DIYables_LCD_I2C.h> //================================================== // PIN CONFIG //================================================== #define FLAME_PIN 18 // GPIO18 (D2) #define BUZZER_PIN 17 // GPIO17 (D3) #define LED_PIN 19 // GPIO19 (D4) //================================================== // ACTIVE LEVEL //================================================== // LED active LOW #define LED_ON LOW #define LED_OFF HIGH // Buzzer active LOW #define BUZZER_ON LOW #define BUZZER_OFF HIGH // Flame sensor #define FIRE_DETECTED_LEVEL LOW #define FIRE_NORMAL_LEVEL HIGH //================================================== DIYables_LCD_I2C lcd(0x27, 20, 4); // I2C on SDA (GPIO8) and SCL (GPIO9) //================================================== enum SystemState { STATE_SAFE, STATE_FIRE }; SystemState currentState = STATE_SAFE; SystemState previousState = STATE_FIRE; //================================================== unsigned long blinkTimer = 0; unsigned long fireStartTime = 0; bool blinkState = false; //================================================== void setup() { Serial.begin(115200); pinMode(FLAME_PIN, INPUT); pinMode(LED_PIN, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); digitalWrite(LED_PIN, LED_OFF); digitalWrite(BUZZER_PIN, BUZZER_OFF); lcd.init(); lcd.backlight(); // Splash Screen lcd.clear(); lcd.setCursor(6,0); lcd.print("DIYables"); lcd.setCursor(4,1); lcd.print("FIRE MONITOR"); lcd.setCursor(4,2); lcd.print("ESP32 S3 Uno"); delay(2000); lcd.clear(); } //================================================== void loop() { bool fireDetected = (digitalRead(FLAME_PIN) == FIRE_DETECTED_LEVEL); currentState = fireDetected ? STATE_FIRE : STATE_SAFE; //------------------------------------------------ // State Changed //------------------------------------------------ if(currentState != previousState) { lcd.clear(); if(currentState == STATE_SAFE) { drawSafeScreen(); digitalWrite(LED_PIN, LED_OFF); digitalWrite(BUZZER_PIN, BUZZER_OFF); } else { fireStartTime = millis(); drawFireScreen(); } previousState = currentState; } //------------------------------------------------ // State Handler //------------------------------------------------ switch(currentState) { case STATE_SAFE: updateSafeMode(); break; case STATE_FIRE: updateFireMode(); break; } } //================================================== // SAFE SCREEN //================================================== void drawSafeScreen() { lcd.setCursor(0,0); lcd.print("FIRE MONITOR"); lcd.setCursor(0,1); lcd.print("Status : SAFE "); lcd.setCursor(0,2); lcd.print("Flame : NONE "); lcd.setCursor(0,3); lcd.print("Alarm : OFF "); } //================================================== void updateSafeMode() { digitalWrite(LED_PIN, LED_OFF); digitalWrite(BUZZER_PIN, BUZZER_OFF); } //================================================== // FIRE SCREEN //================================================== void drawFireScreen() { lcd.setCursor(0,0); lcd.print("!!! FIRE ALERT !!!"); lcd.setCursor(0,1); lcd.print("Status : DANGER"); lcd.setCursor(0,2); lcd.print("Flame : DETECTED"); } //================================================== void updateFireMode() { unsigned long now = millis(); //---------------------------------------------- // LED + BUZZER FLASH //---------------------------------------------- if(now - blinkTimer >= 250) { blinkTimer = now; blinkState = !blinkState; if(blinkState) { digitalWrite(LED_PIN, LED_ON); digitalWrite(BUZZER_PIN, BUZZER_ON); } else { digitalWrite(LED_PIN, LED_OFF); digitalWrite(BUZZER_PIN, BUZZER_OFF); } } //---------------------------------------------- // FIRE TIMER //---------------------------------------------- unsigned long sec = (now - fireStartTime) / 1000; char buffer[21]; sprintf(buffer, "Alarm : %02lu:%02lu", sec / 60, sec % 60); lcd.setCursor(0,3); lcd.print(buffer); }

Function References

These pages explain the Arduino functions used in this tutorial in more detail.

FAQ

Can I power the flame sensor from 5V on the ESP32 S3 Uno?

The module itself works from 3.3V to 5V, but the ESP32 S3 Uno pins are not 5V tolerant. If you power the sensor from 5V, the DO and AO pins can output up to 5V and may damage the board. Power it from 3.3V, or add a voltage divider on each signal pin.

Why does the code call analogSetAttenuation(ADC_11db)?

It sets the ESP32 S3 Uno ADC input range to about 0V to 3.3V, so the full flame sensor signal maps to 0 to 4095. Without it, the range is smaller and readings saturate early. The UNO R4 does not need this line, it is only for ESP32 boards. Keep the AO signal at 3.3V or less.

Why are my analog values much bigger than on an Arduino UNO R4?

The ESP32 S3 Uno has a 12-bit ADC, so readings go from 0 to 4095. The UNO R4 code uses 10-bit readings from 0 to 1023. If you copy a threshold from an UNO R4 project, multiply it by about 4.

Why does the DO pin show LOW when there is a flame?

That is how the module is designed. DO is active LOW, so LOW means a flame is detected and HIGH means no flame. In your code, check for LOW when you want to trigger an alarm.

Can sunlight trigger the flame sensor?

Yes. Sunlight and some strong lamps contain a lot of infrared light, so the sensor may report a flame that is not there. Test indoors, keep the sensor out of direct sun, and turn the potentiometer to reduce the sensitivity if needed.

What if my project needs more pins than the Uno headers give, for example for a 5-in-1 flame sensor?

The ESP32 S3 Uno has two extra rows of holes with more GPIOs: GPIO15 and GPIO16 (I/O, PWM, analog), GPIO45 and GPIO35 to GPIO42 (I/O, PWM), and GPIO47/GPIO48 (output only, PWM). Solder pin headers to use them and write the GPIO number in code. For extra AO outputs use GPIO15 and GPIO16, and for extra DO outputs use GPIO35 to GPIO42, never GPIO47/GPIO48 because they are output only. Be careful with two things. First, GPIO47/GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.

Troubleshooting

Problem Possible Cause Solution
No COM port appears in Arduino IDE USB driver missing or board not in upload mode Install the CP210x or CH340 driver, try another USB cable, or hold BOOT while pressing RESET
Upload fails or times out Wrong board selected Select ESP32S3 Dev Module and the correct COM port, then try again
PWR-LED on the sensor is off No power or loose wire Check that VCC goes to 3.3V and GND goes to GND
Always prints "fire is detected" Sensitivity is too high or strong sunlight hits the sensor Turn the potentiometer to lower the sensitivity and move the sensor away from sunlight
Never detects a flame Sensitivity is too low or the flame is too far away Turn the potentiometer the other way and bring the flame closer, about 20 to 50 cm
Analog value stays at 4095 Sensor powered from 5V or attenuation line missing Power the sensor from 3.3V and keep analogSetAttenuation(ADC_11db) in setup()
Analog value stays at 0 AO wire on the wrong pin Connect AO to A0 (GPIO2) and use pin 2 in the code
Serial Monitor shows strange characters Wrong baud rate Set the Serial Monitor to 9600 baud

Learn More

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!