Nauras Shaji
Created August 15, 2025 © GPL3+

Firescape

Early fire detection with multi-sensor IoT system, real-time alerts, and live monitoring to protect lives, assets, and the environment.

Intermediate5 hours24
Firescape

Things used in this project

Story

Read more

Schematics

Schematic

Code

Arduino code

Arduino
fire detection
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define FLAME_SENSOR_PIN 2
#define BUZZER_PIN 3
#define LED_PIN 4


LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust to 0x3F if needed

void setup() {
    pinMode(FLAME_SENSOR_PIN, INPUT);
    pinMode(BUZZER_PIN, OUTPUT);
    pinMode(LED_PIN, OUTPUT);
    Serial.begin(115200);
    lcd.init();
    lcd.begin(16, 2);  // <-- Use begin() instead of init()
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Flame Test");
    delay(2000);
    lcd.clear();
}

void loop() {
    int flame_detected = digitalRead(FLAME_SENSOR_PIN);
    Serial.println(flame_detected);

    if (flame_detected == HIGH) { // Flame detected (LOW signal)
        digitalWrite(BUZZER_PIN, HIGH);
        digitalWrite(LED_PIN, HIGH);
        lcd.setCursor(0, 0);
        lcd.print("FLAME DETECTED!");
        lcd.setCursor(0, 1);
        lcd.print("Take Action!");
    } else { // No flame detected (HIGH signal)
        digitalWrite(BUZZER_PIN, LOW);
        digitalWrite(LED_PIN, LOW);
        lcd.setCursor(0, 0);
        lcd.print("No Flame Found  ");
        lcd.setCursor(0, 1);
        lcd.print("Stay Safe       ");
    }
  
    delay(500);
}

xiao esp32s3 code

Arduino
#include "esp_camera.h"
#include <WiFi.h>
#include "esp_http_server.h"

// WiFi Credentials
const char *ssid = "realme";
const char *password = "12345678";

// Fire Sensor Pin
#define FIRE_SENSOR_PIN 6  // Change if needed
#define Buzzer_PIN 44
// XIAO ESP32S3 Camera Pins
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      10
#define SIOD_GPIO_NUM      40
#define SIOC_GPIO_NUM      39
#define Y9_GPIO_NUM        48
#define Y8_GPIO_NUM        11
#define Y7_GPIO_NUM        12
#define Y6_GPIO_NUM        14
#define Y5_GPIO_NUM        16
#define Y4_GPIO_NUM        18
#define Y3_GPIO_NUM        17
#define Y2_GPIO_NUM        15
#define VSYNC_GPIO_NUM     38
#define HREF_GPIO_NUM      47
#define PCLK_GPIO_NUM      13

bool camera_initialized = false;
httpd_handle_t camera_httpd = NULL;

// Function Declarations
bool initCamera();
void stopCamera();
void startCameraServer();
void stopCameraServer();
static esp_err_t stream_handler(httpd_req_t *req);

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println("\nStarting...");

  pinMode(FIRE_SENSOR_PIN, INPUT);
  pinMode(Buzzer_PIN, OUTPUT);
  // Connect to WiFi
  WiFi.begin(ssid, password);
  WiFi.setSleep(false);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected");
}

void loop() {
  int fire_detected = digitalRead(FIRE_SENSOR_PIN);

  if (fire_detected == HIGH) {  // Fire detected (LOW for active-low sensors)
    Serial.println("πŸ”₯ Fire detected! Starting camera stream...");
    digitalWrite(Buzzer_PIN,HIGH);
    if (!camera_initialized) {
      if (initCamera()) {
        camera_initialized = true;
        startCameraServer();
      } else {
        Serial.println("🚨 Camera initialization failed!");
      }
    }
  } else {
    Serial.println("βœ… No fire detected.");
    digitalWrite(Buzzer_PIN,LOW);
    if (camera_initialized) {
      Serial.println("Stopping camera stream...");
      stopCameraServer();
      stopCamera();
      camera_initialized = false;
    }
  }

  delay(2000);
}

// Function to initialize the camera
bool initCamera() {
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_QVGA;
  config.pixel_format = PIXFORMAT_JPEG;
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 10;
  config.fb_count = 2;

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x\n", err);
    return false;
  }

  Serial.println("πŸ“· Camera initialized successfully!");
  return true;
}

// Function to stop the camera
void stopCamera() {
  esp_camera_deinit();
  Serial.println("πŸ“· Camera deinitialized.");
}

// Function to start camera server
void startCameraServer() {
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.server_port = 80;

  httpd_uri_t uri = {
    .uri = "/",
    .method = HTTP_GET,
    .handler = stream_handler,
    .user_ctx = NULL
  };

  if (httpd_start(&camera_httpd, &config) == ESP_OK) {
    httpd_register_uri_handler(camera_httpd, &uri);
    Serial.print("πŸ“‘ Camera stream started at: http://");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("❌ Failed to start camera server!");
  }
}

// Function to stop camera server
void stopCameraServer() {
  if (camera_httpd) {
    httpd_stop(camera_httpd);
    camera_httpd = NULL;
    Serial.println("πŸ“‘ Camera server stopped.");
  }
}

// Function to handle streaming
static esp_err_t stream_handler(httpd_req_t *req) {
  camera_fb_t *fb = NULL;
  esp_err_t res = ESP_OK;
  size_t _jpg_buf_len = 0;
  uint8_t *_jpg_buf = NULL;

  res = httpd_resp_set_type(req, "multipart/x-mixed-replace; boundary=frame");

  while (res == ESP_OK) {
    fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("❌ Camera capture failed!");
      res = ESP_FAIL;
      break;
    }

    if (fb->format != PIXFORMAT_JPEG) {
      bool converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
      esp_camera_fb_return(fb);
      fb = NULL;
      if (!converted) {
        Serial.println("JPEG compression failed");
        res = ESP_FAIL;
        break;
      }
    } else {
      _jpg_buf = fb->buf;
      _jpg_buf_len = fb->len;
    }

    char part_buf[64];
    int len = snprintf(part_buf, sizeof(part_buf),
                       "--frame\r\nContent-Type: image/jpeg\r\nContent-Length: %zu\r\n\r\n",
                       _jpg_buf_len);
    res = httpd_resp_send_chunk(req, part_buf, len);
    if (res == ESP_OK) {
      res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
    }
    if (res == ESP_OK) {
      res = httpd_resp_send_chunk(req, "\r\n", 2);
    }

    esp_camera_fb_return(fb);
    fb = NULL;

    if (res != ESP_OK) {
      break;
    }

    delay(100);
  }

  return res;
}

Credits

Nauras Shaji
3 projects β€’ 3 followers

Comments