Saturday, 31 October 2026

AI Railway Accident Prevention & Crack Detection System

AI-Powered Railway Accident Prevention & Crack Detection System

Agentic IoT using ESP32 + AI + n8n Automation + Telegram Voice Alerts + Google Sheets + ThingSpeak Cloud Dashboard

Complete project documentation IoT + AI + Automation

This project is designed as an intelligent railway track condition monitoring and early-warning system. It combines an ESP32 microcontroller, IoT sensors, AI-based anomaly analysis, n8n workflow automation, Telegram notifications with voice alerts, Google Sheets data logging, and a ThingSpeak cloud dashboard.

The main objective is to identify unusual track conditions, monitor vibration and environmental changes, record suspected defects, and immediately notify railway maintenance personnel.

Important engineering distinction: A low-cost ESP32 sensor prototype can demonstrate condition monitoring and anomaly detection, but it cannot certify the presence or absence of structural rail cracks. Actual railway crack inspection requires validated non-destructive testing (NDT), such as qualified ultrasonic inspection, and professional railway engineering procedures. This project must remain a supplementary research and educational prototype, not a railway signalling, braking, or safety-control system.

Explore the capabilities of Ultrasonic Rail Testing - Pandrol
Налагоджувальна плата ESP32-WROOM-32 DevKit V1 Wi-Fi, Bluetooth – фото, відгуки, характеристики в інтернет-магазині ROZETKA від продавця: Rozenda
One Big Circle, KONUX, and Network Rail: Smarter Rail Maintenance

1. Project overview

Project title

AI-Based Railway Accident Prevention and Crack Detection Monitoring System Using ESP32, Agentic IoT, n8n Automation and Telegram Voice Alerts.

Technologies used

Component

Technology

Microcontroller

ESP32

Programming

Arduino IDE / C++

Sensor monitoring

Vibration, temperature, environmental sensors

Crack inspection research

Ultrasonic NDT / simulated defect inputs

IoT communication

Wi-Fi, HTTP, MQTT

Automation

n8n

AI analysis

AI agent / LLM through n8n

Mobile alerts

Telegram Bot

Voice notification

Telegram audio message

Data storage

Google Sheets

Cloud dashboard

ThingSpeak

Web interface

HTML, CSS, JavaScript

Backend

n8n Webhook

Power

Regulated DC supply

Main objectives

  1. Monitor railway track vibration and abnormal movement.

  2. Identify unusual sensor patterns.

  3. Detect possible anomalies that need inspection.

  4. Send sensor data to an IoT cloud platform.

  5. Use AI to summarize and classify monitoring events.

  6. Automate alerts through n8n.

  7. Send Telegram text and voice notifications.

  8. Save historical readings in Google Sheets.

  9. Display sensor readings and trends on ThingSpeak.

  10. Provide a webpage for monitoring sensor status and event history.

2. Complete system architecture

The project consists of six major layers.

System architecture

RAILWAY TRACK MONITORING

Vibration • Temperature • Environmental monitoring • Inspection data

ESP32 IoT CONTROLLER

Sensor acquisition • Filtering • Threshold checks • Wi-Fi transmission

CLOUD COMMUNICATION

HTTP / Webhook • ThingSpeak • n8n

n8n AUTOMATION + AI AGENT

Data validation • Anomaly classification • Event management • Alert generation

Telegram

Text and voice alerts

Google Sheets

Event history and reports

ThingSpeak

Cloud graphs

IoT Webpage

Live monitoring

How the complete system works

  1. Sensors collect measurements from a laboratory track model or approved monitoring test setup.

  2. ESP32 reads the sensor values.

  3. ESP32 applies basic filtering and threshold checks.

  4. ESP32 sends the readings to n8n through an HTTP webhook.

  5. n8n validates the data.

  6. An AI agent generates a human-readable interpretation of the event.

  7. n8n sends alerts to Telegram.

  8. An optional text-to-speech service generates an audio announcement.

  9. Google Sheets stores the readings.

  10. ThingSpeak visualizes the sensor history.

  11. The webpage displays the latest monitoring status.

3. Hardware components required

GitHub - TronixLab/DOIT_ESP32_DevKit-v1_30P · GitHub
ADXL345 Accelerometer Module
 – UG LAND INDIA
SW-420 Motion Sensor Module Vibration Switch Alarm Sensor Module

No.

Component

Quantity

Purpose

1

ESP32 DevKit V1

1

Main controller

2

ADXL345 accelerometer

1

Vibration and acceleration monitoring

3

SW-420 vibration module

1

Basic vibration event input

4

DS18B20

1

Temperature monitoring

5

HC-SR04

1

Demonstration of distance/displacement changes

6

Breadboard

1

Circuit assembly

7

Jumper wires

As needed

Connections

8

USB power supply

1

ESP32 power

9

Wi-Fi connection

1

Internet communication

10

Optional ultrasonic NDT instrument

1

Qualified rail inspection research

Important: HC-SR04, SW-420 and ADXL345 are demonstration sensors, not railway crack-detection instruments. In particular, an accelerometer detects motion and vibration, not an internal rail fracture. Do not connect a hobby ultrasonic module to a rail and interpret its distance measurement as proof of structural integrity.

3.1 Sensor descriptions

A. ADXL345 accelerometer

ADXL345 Guide: Datasheet, Pinout, Arduino, ESP32 & Calibration

Measures acceleration on three axes:

  • X-axis acceleration

  • Y-axis acceleration

  • Z-axis acceleration

It can be used to monitor changes in vibration and movement.

B. SW-420 vibration sensor

Interfacing vibration Sensor with Arduino

Detects vibration events. It is useful for basic demonstrations, but it does not provide calibrated structural measurements.

C. DS18B20 temperature sensor

DS18B20 Waterproof Digital Temperature Sensor Probe - Thingbits India

Monitors temperature changes in the demonstration environment.

D. Ultrasonic testing

Ultrasonic and Eddy Current Flaw Detectors for Rail and Weld Testing | OKOndt GROUP

Professional ultrasonic NDT uses suitable transducers, coupling, calibration standards, inspection procedures and qualified interpretation. For this project, inspection results can be entered as externally verified inspection observations.

4. Circuit and schematic diagram

4.1 ESP32 connection table

The following is a low-voltage laboratory demonstration circuit.

Sensor

Sensor pin

ESP32 pin

ADXL345

VCC

3.3V

ADXL345

GND

GND

ADXL345

SDA

GPIO 21

ADXL345

SCL

GPIO 22

SW-420

VCC

3.3V

SW-420

GND

GND

SW-420

DO

GPIO 27

DS18B20

VCC

3.3V

DS18B20

GND

GND

DS18B20

DATA

GPIO 4

Add a 4.7 kΩ pull-up resistor between DS18B20 DATA and 3.3V.

Electrical precautions: Do not connect a 5V sensor output directly to an ESP32 GPIO. Check each sensor's electrical specifications and use appropriate level shifting where required. Avoid installing hobby electronics on operational railway infrastructure.

4.2 Schematic diagram

The following simplified connection drawing shows the wiring concept:

text

                 USB 5V
                   |
             +-------------+
             |   ESP32     |
             |             |
  3.3V ------+-------------+------------------+
             |             |                  |
 GPIO 21 <---+---- SDA     |             DS18B20 DATA
 GPIO 22 <---+---- SCL     |                  |
 GPIO 27 <---+---- DO      |               4.7KΩ
 GPIO 4  <---+-------------+                  |
             |                                3.3V
             +-------------+
                 |  GND
                 |
       +---------+----------+
       |         |          |
    ADXL345    SW-420    DS18B20
       |         |          |
       +---------+----------+
                 GND

4.3 Complete data-flow diagram

mermaid

flowchart TD
    A[Railway Monitoring Test Setup] --> B[ADXL345]
    A --> C[SW-420]
    A --> D[DS18B20]

    B --> E[ESP32 Controller]
    C --> E
    D --> E

    E --> F[Filtering and Data Validation]
    F --> G[Wi-Fi HTTP Request]
    G --> H[n8n Webhook]

    H --> I[Validate Incoming Data]
    I --> J[AI Event Analysis]
    J --> K{Event Classification}

    K -->|Normal| L[Store Monitoring Data]
    K -->|Warning| M[Telegram Warning]
    K -->|Critical Suspected Anomaly| N[Urgent Human Inspection Alert]

    L --> O[Google Sheets]
    L --> P[ThingSpeak]
    M --> O
    N --> O

    O --> Q[IoT Web Dashboard]
    P --> Q

5. Software architecture and installation

The software is divided into five parts.

Software

Role

Arduino IDE

ESP32 programming

n8n

Workflow automation

AI API

Event interpretation

Telegram Bot

Notifications

Google Sheets + ThingSpeak

Data storage and visualization

Step 1: Install Arduino IDE

Download: Arduino IDE official website 

Then:

  1. Install Arduino IDE.

  2. Open Preferences.

  3. Add the ESP32 board manager URL if it is not already configured.

  4. Open Boards Manager.

  5. Search for ESP32.

  6. Install the Espressif ESP32 package.

  7. Select your ESP32 development board.

  8. Select the correct COM port.

Step 2: Install libraries

Open Arduino IDE → Library Manager.

Install:

  • Adafruit ADXL345

  • Adafruit Unified Sensor

  • OneWire

  • DallasTemperature

  • ArduinoJson

Step 3: Configure Wi-Fi

You will need:

  • Wi-Fi SSID

  • Wi-Fi password

  • ESP32 board

  • n8n webhook URL

Step 4: Create an n8n account

Use either a self-hosted installation or the hosted service.

n8n is the automation engine connecting the ESP32 to AI, Telegram, Google Sheets and other cloud services.

6. ESP32 programming – complete starter code

This firmware demonstrates sensor acquisition, basic anomaly screening and sending data to an n8n webhook.

It is deliberately a monitoring-only implementation. It does not calculate rail crack dimensions or make railway safety decisions.

6.1 ESP32 Arduino code

cpp

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoJson.h>

// -------- WiFi configuration --------
const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";

// -------- n8n webhook --------
const char* WEBHOOK_URL =
  "https://YOUR_N8N_HOST/webhook/rail-monitor";

// -------- Sensor pins --------
#define VIBRATION_PIN 27
#define TEMP_PIN 4

Adafruit_ADXL345_Unified accel =
  Adafruit_ADXL345_Unified(12345);

OneWire oneWire(TEMP_PIN);
DallasTemperature tempSensor(&oneWire);

unsigned long previousMillis = 0;
const unsigned long interval = 10000;

// Demonstration thresholds only.
// Calibrate for your laboratory setup.
const float VIBRATION_THRESHOLD = 15.0;

void connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  Serial.print("Connecting");

  unsigned long start = millis();

  while (WiFi.status() != WL_CONNECTED &&
         millis() - start < 20000) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("WiFi connected");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("WiFi unavailable");
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(VIBRATION_PIN, INPUT);

  Wire.begin(21, 22);

  if (!accel.begin()) {
    Serial.println("ADXL345 not detected");
  } else {
    accel.setRange(ADXL345_RANGE_16_G);
    Serial.println("ADXL345 initialized");
  }

  tempSensor.begin();

  connectWiFi();
}

void sendData(
  float ax,
  float ay,
  float az,
  float temperature,
  int vibration,
  bool anomaly
) {
  if (WiFi.status() != WL_CONNECTED) {
    connectWiFi();
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("No network; data not transmitted");
    return;
  }

  HTTPClient http;

  http.begin(WEBHOOK_URL);
  http.addHeader("Content-Type", "application/json");

  JsonDocument doc;

  doc["device_id"] = "RAIL-ESP32-01";
  doc["ax"] = ax;
  doc["ay"] = ay;
  doc["az"] = az;
  doc["temperature"] = temperature;
  doc["vibration"] = vibration;
  doc["anomaly"] = anomaly;
  doc["status"] = anomaly ? "WARNING" : "NORMAL";

  String payload;
  serializeJson(doc, payload);

  int responseCode = http.POST(payload);

  Serial.print("HTTP response: ");
  Serial.println(responseCode);

  http.end();
}

void loop() {
  if (millis() - previousMillis >= interval) {
    previousMillis = millis();

    sensors_event_t event;
    accel.getEvent(&event);

    float ax = event.acceleration.x;
    float ay = event.acceleration.y;
    float az = event.acceleration.z;

    tempSensor.requestTemperatures();
    float temperature =
      tempSensor.getTempCByIndex(0);

    int vibration = digitalRead(VIBRATION_PIN);

    float magnitude = sqrt(
      ax * ax + ay * ay + az * az
    );

    bool anomaly =
      (magnitude > VIBRATION_THRESHOLD);

    Serial.println("----- RAIL MONITOR -----");

    Serial.printf("X: %.2f\n", ax);
    Serial.printf("Y: %.2f\n", ay);
    Serial.printf("Z: %.2f\n", az);

    Serial.printf(
      "Temperature: %.2f C\n", temperature
    );

    Serial.printf(
      "Vibration input: %d\n", vibration
    );

    Serial.printf(
      "Acceleration magnitude: %.2f\n",
      magnitude
    );

    Serial.println(
      anomaly ? "WARNING" : "NORMAL"
    );

    sendData(
      ax, ay, az,
      temperature,
      vibration,
      anomaly
    );
  }
}

6.2 How the code works

  • ESP32 connects to the Wi-Fi network.

  • ADXL345 measures acceleration.

  • DS18B20 measures temperature.

  • SW-420 provides a digital vibration input.

  • ESP32 calculates acceleration magnitude.

  • The example compares the magnitude against a demonstration threshold.

  • Data is packaged as JSON.

  • HTTP POST sends the JSON to n8n.

Example JSON message:

json
{
  "device_id": "RAIL-ESP32-01",
  "ax": 0.45,
  "ay": 0.32,
  "az": 9.81,
  "temperature": 32.5,
  "vibration": 0,
  "anomaly": false,
  "status": "NORMAL"
}

Technical limitation: This example uses instantaneous acceleration magnitude, including gravity, rather than calibrated vibration RMS or frequency-domain analysis. The threshold is illustrative and must not be treated as a crack-detection threshold. A research-grade vibration system should use calibrated sampling, baseline comparison, filtering, RMS/FFT features and repeatability testing.

7. n8n workflow automation

This is the main automation section of the project.

7.1 Create a webhook

  1. Open n8n.

  2. Create a new workflow.

  3. Add a Webhook node.

  4. Set HTTP Method to POST.

  5. Set Path to rail-monitor.

  6. Set response mode to respond to webhook.

  7. Save the workflow.

  8. Activate the workflow when ready.

Your endpoint will resemble:

text
https://YOUR_N8N_HOST/webhook/rail-monitor

Use the test URL while developing and the production URL when the workflow is active.

7.2 Complete n8n workflow diagram

mermaid

flowchart TD
 A[Webhook: ESP32 Data] --> B[Validate JSON]
 B --> C[Extract Sensor Values]
 C --> D[IF: Anomaly or Invalid Data?]
 D -->|No anomaly| E[Google Sheets: Append Row]
 D -->|Anomaly| F[AI Agent: Analyze Event]
 F --> G[Structured Event Summary]
 G --> H[Google Sheets: Append Row]
 G --> I[Telegram Text Alert]
 G --> J[Text-to-Speech Service]
 J --> K[Telegram Voice Message]
 E --> L[ThingSpeak Update]
 H --> L
 L --> M[Webhook Response]
 I --> M
 K --> M

7.3 Required n8n nodes

Node

Function

Webhook

Receives ESP32 readings

Edit Fields

Extracts and prepares values

IF

Checks event conditions

AI Agent

Summarizes monitoring anomalies

Google Sheets

Saves readings

HTTP Request

Sends readings to ThingSpeak

Telegram

Sends text alerts

HTTP Request / TTS

Generates voice audio

Telegram

Sends generated audio

Respond to Webhook

Returns HTTP response

7.4 Configure the IF node

Create a condition based on:

javascript
{{ $json.body.anomaly === true }}
  • True: send the event for further investigation.

  • False: record the normal reading.

Also validate that all required fields are present and numeric. A missing sensor reading must not be interpreted as a normal reading.

7.5 Configure the AI Agent

The AI agent should summarize the data and recommend a human inspection. It should not independently authorize a railway track as safe or unsafe.

Example AI system instruction:

text

You are a Railway Condition Monitoring Assistant.

Your responsibility is to analyze laboratory and
supplementary railway monitoring sensor readings.

You receive:
- Device ID
- X, Y and Z acceleration
- Temperature
- Vibration event
- Sensor health information

Your tasks:

1. Summarize the sensor readings.
2. Identify unusual patterns.
3. Classify the observation as NORMAL,
   WARNING or SENSOR_FAULT.
4. Explain which sensor triggered the event.
5. Recommend a human engineering inspection
   when unusual measurements are observed.
6. Clearly state when data is insufficient.

Important restrictions:

- Never claim that a rail is crack-free.
- Never calculate actual crack dimensions from
  ordinary vibration measurements.
- Never declare railway infrastructure safe.
- Never control railway signalling or braking.
- Never suppress an alert based on an AI opinion.
- Treat missing, stale or invalid data as
  a monitoring fault requiring investigation.

Output structured JSON only.

Example AI output:

json
{
  "classification": "WARNING",
  "device_id": "RAIL-ESP32-01",
  "observation": "Unusual acceleration reading detected.",
  "reason": "Acceleration exceeded the configured demonstration threshold.",
  "recommended_action": "Arrange human inspection of the test setup.",
  "confidence": "Not calibrated",
  "infrastructure_safety_status": "NOT ASSESSED"
}

8. Telegram notification and voice alert system

RAILCAR.SmartControl: уведомления о ключевых событиях с вашим парком теперь в Telegram
File:Telegram voice messages.png - Wikimedia Commons
INFERNO: AI-Powered Fire & Smoke Detection and security System on edge device | Olisemeka

The Telegram bot sends immediate messages when the monitoring system identifies an unusual sensor reading.

8.1 Create a Telegram bot

  1. Open Telegram.

  2. Search for @BotFather.

  3. Start a conversation.

  4. Send /newbot.

  5. Enter a bot name.

  6. Enter a username ending in bot.

  7. Copy the generated bot token.

  8. Keep the token private.

Official website: Telegram Bot API documentation .

8.2 Obtain your chat ID

  1. Open your new bot.

  2. Press Start.

  3. Send a test message.

  4. Use Telegram's Bot API getUpdates method to identify your chat ID.

  5. Store it in n8n credentials or secure configuration.

Do not publish your bot token in your Arduino source code, public webpage or GitHub repository.

8.3 Configure Telegram text notification

In n8n:

  • Add Telegram node.

  • Select Send Message.

  • Configure bot credentials.

  • Enter your chat ID.

  • Set the message using the AI output.

Example notification:

Railway Monitoring Bot

Example

WARNING – INSPECTION REQUIRED

AI Railway Monitoring Alert

  • Device: RAIL-ESP32-01

  • Event: Unusual vibration

  • Acceleration: 15.8 m/s²

  • Temperature: 32.5°C

  • Time: 14:25:30

AI observation: An unusual acceleration reading was detected.

Recommended action: Arrange human inspection of the test setup and verify sensor operation.

This is a supplementary monitoring alert, not a certified railway safety determination.

8.4 Telegram voice notifications

The voice alert feature can convert the AI-generated text into speech.

Voice notification workflow

mermaid

flowchart TD
 A[AI Agent Output] --> B[Prepare Alert Text]
 B --> C[Text-to-Speech API]
 C --> D[Generate MP3 or OGG Audio]
 D --> E[Telegram Send Audio]
 E --> F[Maintenance Team Receives Voice Alert]

Example voice message:

Attention! Railway monitoring warning. Unusual vibration has been detected by monitoring device RAIL-ESP32-01. Please arrange a human inspection and verify the sensor readings. This is a supplementary monitoring alert.

How to configure this in n8n

  1. Connect the AI Agent output to an Edit Fields node.

  2. Create a field named alert_text.

  3. Pass the text to a compatible text-to-speech service.

  4. Configure the service to return an MP3 or OGG file.

  5. Send the generated binary audio to Telegram.

  6. Use Telegram's Send Audio or Send Voice node, depending on the desired format.

The TTS service can be selected based on available credentials and pricing. The AI Agent creates the announcement; the TTS service converts it into speech.

9. Google Sheets integration

Google Sheets is used as the historical database for sensor measurements and alerts.

9.1 Create a spreadsheet

Create a Google Sheet named:

AI_Railway_Monitoring_System

Create the following columns:

Column

Field

A

Timestamp

B

Device_ID

C

Acceleration_X

D

Acceleration_Y

E

Acceleration_Z

F

Temperature

G

Vibration

H

Anomaly

I

AI_Classification

J

AI_Observation

K

Recommended_Action

9.2 Configure Google Sheets in n8n

  1. Add Google Sheets node.

  2. Connect Google account credentials.

  3. Select your spreadsheet.

  4. Select the worksheet.

  5. Choose Append Row.

  6. Map the incoming JSON fields to spreadsheet columns.

  7. Test the workflow.

Example data:

Time

Device

Temperature

Anomaly

Classification

10:00

RAIL-01

30.2

False

NORMAL

10:01

RAIL-01

31.1

False

NORMAL

10:02

RAIL-01

32.5

True

WARNING

10:03

RAIL-01

32.2

False

NORMAL

This information can be used for:

  • Historical analysis.

  • Daily monitoring reports.

  • Sensor performance evaluation.

  • Maintenance inspection records.

  • Research project documentation.

10. ThingSpeak cloud dashboard

IoT based Weather Station using ThingSpeak IoT Analytics - Hackster.io
Advanced IoT Data Processing with ThinkSpeak - Embedded Computing
ThingSpeak Cloud Platform in IoT: Features, Working, and Applications Explained
 – Electro Robo Store

ThingSpeak provides an IoT cloud platform for storing and visualizing measurements.

Website: ThingSpeak official platform .

10.1 Create a ThingSpeak channel

  1. Create a ThingSpeak account.

  2. Open Channels.

  3. Select New Channel.

  4. Enter channel name: Railway Monitoring.

  5. Enable these fields:

Field

Name

Field 1

Acceleration X

Field 2

Acceleration Y

Field 3

Acceleration Z

Field 4

Temperature

Field 5

Vibration

Field 6

Anomaly

  1. Save the channel.

  2. Open API Keys.

  3. Copy the Write API Key.

  4. Keep the API key private.

10.2 Send ESP32 data to ThingSpeak through n8n

Add an HTTP Request node after your data validation node.

Configure:

Setting

Value

Method

GET

URL

https://api.thingspeak.com/update

Query parameter

api_key

Query parameter

field1

Query parameter

field2

Query parameter

field3

Query parameter

field4

Query parameter

field5

Query parameter

field6

Use expressions for the incoming values:

javascript
field1 = {{ $json.body.ax }}
field2 = {{ $json.body.ay }}
field3 = {{ $json.body.az }}
field4 = {{ $json.body.temperature }}
field5 = {{ $json.body.vibration }}
field6 = {{ $json.body.anomaly ? 1 : 0 }}

Use the actual API key through secure n8n credentials or protected configuration.

Note: ThingSpeak channels have update-rate restrictions. For a standard free channel, the minimum update interval is generally 15 seconds. Configure your ESP32 and workflow accordingly.

10.3 Dashboard visualization

Create the following graphs:

  • X-axis acceleration graph.

  • Y-axis acceleration graph.

  • Z-axis acceleration graph.

  • Temperature monitoring graph.

  • Vibration event graph.

  • Anomaly event graph.

The dashboard provides historical trends and supports the monitoring webpage.

11. AI-powered IoT webpage

The webpage is the main user interface for the project.

It displays:

  1. Device connection status.

  2. Current sensor values.

  3. Acceleration readings.

  4. Temperature.

  5. Vibration status.

  6. Latest monitoring event.

  7. AI observation.

  8. Cloud monitoring information.

11.1 Webpage architecture

mermaid

flowchart TD
 A[ESP32 Sensors] --> B[n8n Webhook]
 B --> C[Data Processing]
 C --> D[Google Sheets]
 C --> E[ThingSpeak]
 C --> F[AI Analysis]
 F --> G[Event Summary]
 D --> H[Webpage]
 E --> H
 G --> H
 H --> I[Monitoring Dashboard]

11.2 Example webpage code

This is a simple standalone dashboard. It uses the public ThingSpeak channel's read API for graph-independent latest-reading display. Configure your own channel ID and read key.

HTML
Wrap linesCopy codePreview

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
 content="width=device-width,initial-scale=1">
<title>AI Railway Monitoring Dashboard</title>

<style>
body {
  font-family: Arial, sans-serif;
  background: #101827;
  color: white;
  margin: 0;
  padding: 20px;
}

h1 { color: #54c7ec; }

.grid {
  display: grid;
  grid-template-columns:
    repeat(auto-fit,minmax(190px,1fr));
  gap: 15px;
}

.card {
  background: #1e2b40;
  padding: 20px;
  border-radius: 12px;
}

.value {
  font-size: 27px;
  color: #54c7ec;
  margin-top: 12px;
}

.status {
  padding: 10px;
  background: #244d37;
  border-radius: 8px;
}

.warning {
  background: #73441e;
}

small { color: #b6c5d9; }
</style>
</head>

<body>

<h1>🚆 AI Railway Monitoring System</h1>

<p>ESP32 + IoT + AI + n8n Automation</p>

<div class="status" id="connection">
  Connecting to cloud...
</div>

<div class="grid">

<div class="card">
  <h3>Acceleration X</h3>
  <div class="value" id="ax">--</div>
  <small>m/s²</small>
</div>

<div class="card">
  <h3>Acceleration Y</h3>
  <div class="value" id="ay">--</div>
  <small>m/s²</small>
</div>

<div class="card">
  <h3>Acceleration Z</h3>
  <div class="value" id="az">--</div>
  <small>m/s²</small>
</div>

<div class="card">
  <h3>Temperature</h3>
  <div class="value" id="temp">--</div>
  <small>°C</small>
</div>

<div class="card">
  <h3>Vibration</h3>
  <div class="value" id="vibration">--</div>
</div>

<div class="card">
  <h3>Monitoring Event</h3>
  <div class="value" id="event">--</div>
</div>

</div>

<h2>Latest Monitoring Information</h2>

<div class="card">
  <p id="lastUpdate">Waiting for data...</p>
  <p id="description">
    Monitoring data has not yet arrived.
  </p>
</div>

<script>

// Configure your own ThingSpeak channel
const CHANNEL_ID = "YOUR_CHANNEL_ID";
const READ_KEY = "YOUR_READ_API_KEY";

async function updateDashboard() {

  const url =
    `https://api.thingspeak.com/channels/${CHANNEL_ID}/feeds/last.json?api_key=${READ_KEY}`;

  try {

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("Cloud request failed");
    }

    const data = await response.json();

    document.getElementById("ax").textContent =
      data.field1 ?? "--";

    document.getElementById("ay").textContent =
      data.field2 ?? "--";

    document.getElementById("az").textContent =
      data.field3 ?? "--";

    document.getElementById("temp").textContent =
      data.field4 ?? "--";

    document.getElementById("vibration").textContent =
      data.field5 ?? "--";

    const anomaly = Number(data.field6);

    const event = document.getElementById("event");

    event.textContent =
      anomaly === 1 ? "WARNING" : "NORMAL";

    event.parentElement.className =
      anomaly === 1 ? "card warning" : "card";

    document.getElementById("connection")
      .textContent = "Cloud connected";

    document.getElementById("lastUpdate")
      .textContent =
      "Last update: " + data.created_at;

    document.getElementById("description")
      .textContent =
      anomaly === 1
      ? "An unusual monitoring event was recorded. Human inspection is required."
      : "No configured anomaly flag was reported in the latest cloud reading.";

  } catch (error) {

    document.getElementById("connection")
      .textContent = "Cloud connection unavailable";

    document.getElementById("description")
      .textContent =
      "Unable to retrieve the latest sensor readings.";

  }
}

// Initial reading and periodic refresh
updateDashboard();
setInterval(updateDashboard, 20000);

</script>

</body>
</html>

11.3 Webpage limitations

This dashboard is a basic read-only example. It does not provide:

  • Authenticated maintenance-user accounts.

  • A secure backend.

  • Historical event filtering.

  • Role-based access.

  • A validated AI decision record.

  • Real-time streaming.

For a production-quality demonstration, use a private backend or authenticated API rather than exposing private cloud read keys in browser JavaScript.

12. Complete project workflow – from sensor to voice notification

mermaid

sequenceDiagram
 participant S as Sensors
 participant E as ESP32
 participant N as n8n
 participant A as AI Agent
 participant T as Telegram
 participant G as Google Sheets
 participant C as ThingSpeak
 participant W as Web Dashboard

 S->>E: Sensor readings
 E->>N: JSON over HTTP
 N->>N: Validate sensor data
 N->>A: Send event context
 A-->>N: Classification and explanation
 N->>G: Append monitoring record
 N->>C: Update cloud channel
 N->>T: Send text alert
 N->>T: Send voice notification
 C-->>W: Latest cloud measurements
 G-->>W: Historical records through backend
 W->>W: Display monitoring status

Example operating scenarios

Scenario

System response

Normal vibration

Record data

Unusual vibration

Generate warning

Temperature anomaly

Record and notify

Sensor disconnected

Sensor fault notification

Wi-Fi disconnected

Local monitoring continues; flag communication loss

AI service unavailable

Preserve raw readings and use deterministic rules

Cloud unavailable

Buffer data locally if storage is provided

A particularly important design feature is that the AI service must never be the only alerting mechanism. Deterministic monitoring rules and sensor-fault detection should operate independently of AI availability.

13. Project testing and implementation

Before presenting the project, test each component independently.

13.1 Testing procedure

Test

Input

Expected output

Test 1

ESP32 powered ON

ESP32 starts

Test 2

Wi-Fi available

Connected

Test 3

ADXL345 connected

Acceleration readings

Test 4

DS18B20 connected

Temperature readings

Test 5

Vibration input activated

Vibration event

Test 6

Webhook receives JSON

n8n executes

Test 7

Anomaly flag enabled

Warning workflow

Test 8

Telegram configured

Text notification

Test 9

TTS configured

Voice notification

Test 10

Google Sheets connected

New row inserted

Test 11

ThingSpeak connected

New graph point

Test 12

Webpage opened

Latest readings displayed

13.2 Sample expected output

ESP32 serial monitor

Example normal condition

text
WiFi connected
ADXL345 initialized

----- RAIL MONITOR -----
X: 0.45
Y: 0.32
Z: 9.81
Temperature: 30.50 C
Vibration input: 0
Acceleration magnitude: 9.83
NORMAL

HTTP response: 200

Example warning condition

text
----- RAIL MONITOR -----
X: 12.50
Y: 4.20
Z: 9.10
Temperature: 32.50 C
Vibration input: 1
Acceleration magnitude: 15.97
WARNING

HTTP response: 200
Illustrative output only. Values and thresholds are not validated railway inspection criteria.

14. AI agentic automation – advanced features

To make this project more than a basic IoT monitoring system, you can add the following agentic features.

AI capability

Function

Event interpretation

Explain unusual readings

Pattern analysis

Compare readings with historical baselines

Maintenance assistance

Generate inspection recommendations

Automated reporting

Prepare daily reports

Voice notification

Announce important monitoring events

Fault analysis

Identify missing or inconsistent sensor data

Trend analysis

Identify recurring monitoring abnormalities

Suggested AI agent workflow

mermaid

flowchart TD
 A[Incoming Sensor Data] --> B[Data Quality Agent]
 B --> C[Anomaly Analysis Agent]
 C --> D[Historical Comparison]
 D --> E[Event Summary Agent]
 E --> F[Human Review Queue]
 F --> G[Telegram Notification]
 F --> H[Maintenance Report]
 H --> I[Google Sheets]
 H --> J[Dashboard]

Recommended architecture: Keep AI agents advisory. Use deterministic rules for event triggering, independent watchdogs for communication faults, and human approval for maintenance decisions. Do not let an LLM autonomously modify railway infrastructure or control railway operations.

15. Project security

Since the system uses cloud services and remote communication, security is important.

  • Use HTTPS for webhook communication.

  • Use a secret authentication key for the ESP32 webhook.

  • Store API keys in n8n credentials.

  • Never publish Wi-Fi passwords.

  • Never expose Telegram bot tokens.

  • Protect Google Sheets access.

  • Use private ThingSpeak channels when appropriate.

  • Validate incoming JSON.

  • Reject malformed or stale sensor readings.

  • Keep event timestamps.

  • Maintain local records when the internet is unavailable.

  • Apply rate limiting and duplicate-alert suppression.

For an actual railway deployment, cybersecurity and functional safety would require a separate professional assessment.

16. Limitations and future enhancements

Current prototype limitations

  1. Low-cost vibration sensors cannot reliably identify internal rail cracks.

  2. Vibration anomalies may be caused by external disturbances.

  3. ESP32 Wi-Fi depends on network availability.

  4. AI analysis can produce incorrect interpretations.

  5. ThingSpeak and Google Sheets are not safety-critical real-time systems.

  6. The example threshold requires calibration.

  7. The prototype is not certified for railway use.

Future enhancements

Rail Bolt Hole Inspection :: Sonatest

1. Professional ultrasonic NDT integration

Incorporate externally validated inspection measurements and inspection records.

Machine learning for predictive maintenance with KONUX

2. Advanced vibration analytics

Add calibrated RMS, FFT, frequency analysis and historical baseline comparisons.

Computer Vision for Rail Track Defect Detection: Use Cases

3. AI computer vision

Analyze images of track surfaces for visible defects, with human verification.

I&T Solution - Enhanced Rail Track Defect Detection Through Cutting-Edge AI Technology 2024-06-7

4. Multiple ESP32 monitoring nodes

Add multiple identified devices for distributed laboratory monitoring.

Railway Intelligence Platform | AI Simulation & Digital Twin | Neodustria

5. Predictive maintenance

Study historical sensor trends to identify conditions that may require inspection.

17. Project abstract for college documentation

Writing
 

AI-Powered Railway Accident Prevention and Crack Detection Monitoring System Using ESP32, IoT, AI Agent and n8n Automation

Abstract

Railway infrastructure requires continuous inspection and maintenance to minimize the possibility of accidents caused by track deterioration and abnormal operating conditions. This project proposes an AI-powered railway condition monitoring prototype using ESP32, IoT sensors, cloud services and workflow automation.

The proposed system uses an ESP32 microcontroller connected to vibration, acceleration and temperature sensors to collect monitoring data from a laboratory railway track model or an approved test environment. The collected sensor readings are transmitted through Wi-Fi to an n8n automation platform using HTTP webhooks.

An AI agent processes the incoming monitoring information, identifies unusual sensor patterns and generates human-readable event summaries and inspection recommendations. When a monitoring anomaly or sensor fault is identified, n8n automatically initiates a notification workflow.

The system integrates Telegram for instant text notifications and generated voice alerts, Google Sheets for historical monitoring records, and ThingSpeak for cloud-based sensor visualization. A web-based dashboard provides a convenient interface for viewing the latest sensor measurements and monitoring events.

The proposed prototype demonstrates the integration of embedded systems, artificial intelligence, Internet of Things technology and agentic workflow automation. It aims to support early identification of abnormal monitoring conditions and improve maintenance awareness.

Actual railway crack verification requires qualified non-destructive testing equipment and validated inspection procedures. Therefore, the proposed system is intended as a supplementary educational and research prototype rather than a certified railway safety or accident-prevention control system.

Keywords

ESP32, Railway Monitoring, IoT, Artificial Intelligence, Agentic AI, n8n Automation, Vibration Monitoring, Crack Inspection, Telegram Voice Alerts, Google Sheets, ThingSpeak, Predictive Maintenance.

18. Suggested project report structure

For a final-year engineering project, organize your documentation into these chapters:

Chapter

Title

1

Introduction

2

Existing System and Proposed System

3

Literature Survey

4

Hardware Requirements

5

Software Requirements

6

System Architecture

7

Circuit Diagram and Connections

8

ESP32 Programming

9

IoT and Cloud Integration

10

n8n Workflow Automation

11

AI Agent Implementation

12

Telegram Voice Alert System

13

Google Sheets and ThingSpeak

14

Web Dashboard

15

Testing and Results

16

Limitations

17

Future Scope

18

Conclusion

19

References

19. Official software and technical resources

These are useful resources for implementation:

20. Recommended final project demonstration

For your college presentation or project exhibition, I recommend demonstrating the system in this sequence:

Live project demonstration

  1. Show the ESP32 hardware

    Display the connected sensors and power up the monitoring system.

  2. Show normal sensor readings

    Display acceleration, temperature and vibration values in Serial Monitor.

  3. Introduce a controlled test disturbance

    Apply a repeatable vibration to the laboratory test fixture, not to operational railway infrastructure.

  4. Show the anomaly event

    Demonstrate how the ESP32 transmits the measurement to n8n.

  5. Show AI analysis

    Display the AI-generated event summary and inspection recommendation.

  6. Show Telegram alerts

    Demonstrate the text notification and generated voice announcement.

  7. Show Google Sheets

    Display the automatically recorded monitoring event.

  8. Show ThingSpeak and the webpage

    Demonstrate sensor graphs and the live monitoring dashboard.

21. Next step: prepare the complete implementation package

The documentation above provides the architecture, circuit plan, firmware starter, workflow design and webpage starter. To turn it into a complete buildable project, the remaining deliverables should be prepared together:

  • Complete ESP32 firmware with sensor filtering, calibration and fault handling.

  • Importable n8n workflow JSON with AI, Telegram, TTS, Sheets and ThingSpeak nodes.

  • Full responsive HTML/CSS/JavaScript dashboard.

  • Detailed pin-to-pin wiring diagram.

  • Google Sheets template.

  • ThingSpeak channel configuration.

  • Testing checklist and project presentation.

One important question: Is this project for a college final-year demonstration using a small railway track model, or are you planning research on actual railway track inspection?

That determines whether the next implementation should focus on a low-cost ESP32 prototype or integration with professional ultrasonic NDT inspection equipment.

 

AI Railway Accident Prevention & Crack Detection System

This project is an IoT-based railway safety prototype that monitors a model railway track for cracks, obstacles, abnormal vibration, and unsafe conditions using an ESP32. It sends sensor data to ThingSpeak, logs events in Google Sheets, and uses an n8n AI agent workflow to classify the event and send Telegram text + voice alerts. Railway prototypes commonly use ultrasonic distance sensing, IR crack sensing, vibration sensing, GPS, and cloud dashboards for this purpose.[ijarcce][jetir][ijert]

Safety note: This is an educational prototype, not a certified railway-safety product. Never deploy it on live railway infrastructure without approval, fail-safe design, and compliance with railway authority standards.

Project Overview

The ESP32 acts as the edge device. It reads sensors, runs local threshold/ML-based anomaly detection, displays status, sounds a buzzer, and posts data to the cloud. The n8n workflow receives the event, uses an AI agent to generate a clear incident report, creates a voice file, and notifies maintenance staff through Telegram. n8n’s Telegram node supports sending messages, audio, photos, documents, and location updates.[docs.n8n]

Main capabilities

  • Detects simulated rail cracks using IR reflectance sensors.
  • Detects surface deformation or obstacles using an HC-SR04 ultrasonic sensor.
  • Detects abnormal vibration using MPU6050/GY-521.
  • Measures temperature and humidity using DHT22.
  • Adds GPS location for incident reporting using NEO-6M.
  • Displays live status on an OLED and a local ESP32 web dashboard.
  • Uploads readings to ThingSpeak for charts and remote monitoring.
  • Logs every anomaly in Google Sheets.
  • Sends Telegram text alerts and voice alerts through n8n.
  • Uses an AI agent to summarize severity, likely cause, and recommended action.
  • Activates a buzzer and warning LED locally.

System Architecture

                 ┌──────────────────────────────┐
                 │        RAILWAY TRACK          │
                 │  IR sensors / ultrasonic /    │
                 │  vibration / DHT22 / GPS      │
                 └───────────────┬──────────────┘
                                 │
                          ┌──────▼──────┐
                          │    ESP32    │
                          │ Edge AI +   │
                          │ Web Server  │
                          └──┬───────┬──┘
              Buzzer/LED/OLED│       │Wi-Fi HTTP POST
                             │       │
                 ┌───────────▼─┐   ┌─▼───────────────┐
                 │ Local Alarm │   │    ThingSpeak    │
                 └─────────────┘   └─┬───────────────┘
                                     │ Webhook / Read API
                          ┌──────────▼──────────┐
                          │       n8n Cloud      │
                          │  Webhook + AI Agent  │
                          │  TTS + Telegram Bot  │
                          └──────┬───────┬───────┘
                                 │       │
                    ┌────────────▼─┐   ┌─▼─────────────┐
                    │ Google Sheets │   │ Telegram App  │
                    │ Incident Log  │   │ Text + Voice  │
                    └───────────────┘   └───────────────┘

Hardware Required

Component Purpose Typical connection
ESP32 DevKit V1 Main controller, Wi-Fi, web server —
2 × IR obstacle/reflectance sensors Detect dark crack/gap on rail surface Left: GPIO 34, Right: GPIO 35
HC-SR04 ultrasonic sensor Detect track gap, deformation, obstacle TRIG: GPIO 5, ECHO: GPIO 18
MPU6050 accelerometer/gyro Detect vibration anomalies SDA: GPIO 21, SCL: GPIO 22
DHT22 Temperature and humidity DATA: GPIO 4
NEO-6M GPS Incident coordinates GPS TX: GPIO 16, GPS RX: GPIO 17
0.96" OLED SSD1306 Local status display SDA: GPIO 21, SCL: GPIO 22
Buzzer Local audible alarm GPIO 23
Red LED Fault indicator GPIO 25
Green LED Normal indicator GPIO 26
5 V relay/module, optional Stop model train / signal GPIO 27
Breadboard, jumper wires, 5 V supply Prototype assembly —

The ultrasonic sensor measures distance by transmitting a 10 microsecond trigger pulse and converting the echo pulse width into distance; it is widely used for crack, deformation, and obstacle detection in railway prototypes.[jetir][jetir]

Circuit Schematic

                         ESP32 DevKit
                      ┌────────────────┐
  IR LEFT  OUT ───────► GPIO 34        │
  IR RIGHT OUT ───────► GPIO 35        │
                                      │
  HC-SR04 TRIG ───────► GPIO 5        │
  HC-SR04 ECHO ──[1k]──► GPIO 18       │
  HC-SR04 ECHO ──[2k to GND]           │
                                      │
  DHT22 DATA ──[10k to 3.3V]─► GPIO 4 │
                                      │
  MPU6050 SDA ─────────► GPIO 21      │
  MPU6050 SCL ─────────► GPIO 22      │
                                      │
  NEO-6M TX ───────────► GPIO 16      │
  NEO-6M RX ──[level shift]─► GPIO 17 │
                                      │
  OLED SDA ────────────► GPIO 21      │
  OLED SCL ────────────► GPIO 22      │
                                      │
  Buzzer + ────────────► GPIO 23      │
  Red LED + ──[220R]───► GPIO 25      │
  Green LED + ─[220R]──► GPIO 26      │
  Relay IN ────────────► GPIO 27      │
                                      │
  All sensor VCC → 3.3 V / 5 V as required
  All GND → common GND

Important: HC-SR04 output is commonly 5 V. Use a voltage divider or logic-level converter on ECHO before connecting it to ESP32. The NEO-6M TX is usually 3.3 V-safe, but verify your module specification.

Detection Logic

The system uses a hybrid approach:

  1. Rule-based edge detection on ESP32 for immediate safety response.
  2. AI agent classification in n8n for context-aware reporting.
  3. Cloud analytics in ThingSpeak for trends and visualization.

Crack detection

IR reflectance sensors detect a sudden drop in reflected infrared light when the beam crosses a crack, gap, or dark discontinuity. A common prototype approach reads the sensor several times and marks a crack only if multiple readings agree, reducing false alarms.[ijert]

Normal rail: IR output HIGH
Crack/gap:   IR output LOW
Decision:    3 or more LOW readings out of 5 = CRACK

Distance anomaly

The ultrasonic sensor measures distance to the rail surface. If the measured distance differs too much from a calibrated baseline, the system flags deformation, missing material, or an obstacle. HC-SR04 modules are typically specified for roughly 2 cm to 400 cm range.[jetir]

distance_deviation = |current_distance - baseline_distance|

if distance_deviation > 2.0 cm:
    status = TRACK_DEFORMATION_OR_OBSTACLE

Vibration anomaly

The MPU6050 provides acceleration on X, Y, and Z axes. A moving inspection trolley or model train produces a baseline vibration level; sudden spikes may indicate a fault, loose joint, or impact. Similar railway IoT systems combine ultrasonic, vibration, and environmental data before sending status to ThingSpeak.[ijarcce]

vibration_magnitude = sqrt(ax² + ay² + az²)

if vibration_magnitude > threshold:
    status = HIGH_VIBRATION

AI risk score

The ESP32 calculates a simple weighted risk score:

Risk = 0.40C + 0.30D + 0.20V + 0.10E

Where:

  • C = crack severity, 0 to 1
  • D = distance/deformation severity, 0 to 1
  • V = vibration severity, 0 to 1
  • E = environmental severity, 0 to 1
Risk score AI classification Action
0.00–0.24 NORMAL Green LED, log normal reading
0.25–0.49 WARNING Yellow/orange status, Telegram warning
0.50–0.74 HIGH RISK Buzzer, Telegram text + voice alert
0.75–1.00 CRITICAL Buzzer, relay stop, emergency Telegram voice alert

Software Flowchart

                    ┌─────────────┐
                    │    START    │
                    └──────┬──────┘
                           ▼
              ┌────────────────────────┐
              │ Initialize Wi-Fi,      │
              │ sensors, OLED, GPS     │
              └───────────┬────────────┘
                          ▼
              ┌────────────────────────┐
              │ Read IR left/right     │
              │ Read ultrasonic        │
              │ Read MPU6050           │
              │ Read DHT22             │
              │ Read GPS               │
              └───────────┬────────────┘
                          ▼
              ┌────────────────────────┐
              │ Run crack detection    │
              │ Calculate distance     │
              │ Calculate vibration    │
              │ Calculate risk score   │
              └───────────┬────────────┘
                          ▼
                   ┌─────────────┐
                   │ Risk > 0.25?│
                   └──┬───────┬──┘
                  Yes │       │ No
                      ▼       ▼
        ┌──────────────────┐ ┌──────────────────┐
        │ Activate buzzer/ │ │ Green LED        │
        │ red LED/relay    │ │ Send to          │
        │ Send event to    │ │ ThingSpeak       │
        │ n8n webhook      │ └──────────────────┘
        └────────┬─────────┘
                 ▼
     ┌──────────────────────────┐
     │ n8n AI Agent analyzes    │
     │ event and severity       │
     └────────────┬─────────────┘
                  ▼
     ┌──────────────────────────┐
     │ Append row to Google     │
     │ Sheets                   │
     └────────────┬─────────────┘
                  ▼
     ┌──────────────────────────┐
     │ Generate voice alert     │
     │ Send Telegram message    │
     │ Send Telegram voice      │
     └────────────┬─────────────┘
                  ▼
              ┌─────────┐
              │  LOOP   │
              └─────────┘

ESP32 Arduino Code

Install these Arduino libraries:

  • WiFi.h
  • HTTPClient.h
  • Adafruit_GFX
  • Adafruit_SSD1306
  • Adafruit MPU6050
  • DHT sensor library
  • TinyGPSPlus
  • ArduinoJson
/*
 * AI Railway Accident Prevention & Crack Detection System
 * ESP32 + IR + Ultrasonic + MPU6050 + DHT22 + GPS
 * ThingSpeak + n8n AI Agent + Telegram Voice Alerts
 */

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <TinyGPSPlus.h>
#include <ArduinoJson.h>

// ---------- Wi-Fi ----------
const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";

// ---------- ThingSpeak ----------
const char* THINGSPEAK_HOST = "api.thingspeak.com";
String THINGSPEAK_WRITE_KEY = "YOUR_THINGSPEAK_WRITE_KEY";

// ---------- n8n ----------
String N8N_WEBHOOK_URL = "https://YOUR_N8N_DOMAIN/webhook/railway-alert";

// ---------- Pins ----------
#define IR_LEFT_PIN     34
#define IR_RIGHT_PIN    35
#define TRIG_PIN        5
#define ECHO_PIN        18
#define DHT_PIN         4
#define BUZZER_PIN      23
#define RED_LED_PIN     25
#define GREEN_LED_PIN   26
#define RELAY_PIN       27

#define GPS_RX_PIN      16
#define GPS_TX_PIN      17

// ---------- Objects ----------
DHT dht(DHT_PIN, DHT22);
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
TinyGPSPlus gps;
HardwareSerial gpsSerial(2);

// ---------- Calibration ----------
float baselineDistance = 10.0;  // Set after calibration
float vibrationThreshold = 12.0;

// ---------- Variables ----------
float distanceCm = 0;
float temperatureC = 0;
float humidity = 0;
float ax = 0, ay = 0, az = 0;
float vibration = 0;
float lat = 0, lng = 0;

bool crackLeft = false;
bool crackRight = false;
bool crackDetected = false;
bool distanceFault = false;
bool vibrationFault = false;

float riskScore = 0;
String eventStatus = "NORMAL";
String severity = "LOW";

void setup() {
  Serial.begin(115200);
  gpsSerial.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);

  pinMode(IR_LEFT_PIN, INPUT);
  pinMode(IR_RIGHT_PIN, INPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);

  digitalWrite(BUZZER_PIN, LOW);
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(GREEN_LED_PIN, HIGH);
  digitalWrite(RELAY_PIN, LOW);

  Wire.begin(21, 22);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED not found");
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("Rail Safety AI");
  display.println("Starting...");
  display.display();

  dht.begin();

  if (!mpu.begin()) {
    Serial.println("MPU6050 not found");
  }

  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("Connecting Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWi-Fi connected:");
  Serial.println(WiFi.localIP());

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("Wi-Fi Connected");
  display.println(WiFi.localIP());
  display.display();
}

float readUltrasonicCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);

  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000);

  if (duration == 0) {
    return -1;
  }

  return duration * 0.0343 / 2.0;
}

bool detectIrCrack(int pin) {
  int lowCount = 0;

  for (int i = 0; i < 5; i++) {
    if (digitalRead(pin) == LOW) {
      lowCount++;
    }
    delay(2);
  }

  return lowCount >= 3;
}

void readSensors() {
  crackLeft = detectIrCrack(IR_LEFT_PIN);
  crackRight = detectIrCrack(IR_RIGHT_PIN);
  crackDetected = crackLeft || crackRight;

  distanceCm = readUltrasonicCm();

  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  ax = a.acceleration.x;
  ay = a.acceleration.y;
  az = a.acceleration.z;

  vibration = sqrt(ax * ax + ay * ay + az * az);

  temperatureC = dht.readTemperature();
  humidity = dht.readHumidity();

  while (gpsSerial.available()) {
    gps.encode(gpsSerial.read());
  }

  if (gps.location.isValid()) {
    lat = gps.location.lat();
    lng = gps.location.lng();
  }

  if (distanceCm > 0 && abs(distanceCm - baselineDistance) > 2.0) {
    distanceFault = true;
  } else {
    distanceFault = false;
  }

  vibrationFault = vibration > vibrationThreshold;
}

void calculateRisk() {
  float crackSeverity = crackDetected ? 1.0 : 0.0;
  float distanceSeverity = distanceFault ? 1.0 : 0.0;
  float vibrationSeverity = vibrationFault ? 1.0 : 0.0;

  float envSeverity = 0;
  if (!isnan(temperatureC) && temperatureC > 45) {
    envSeverity = 0.7;
  }

  riskScore =
    0.40 * crackSeverity +
    0.30 * distanceSeverity +
    0.20 * vibrationSeverity +
    0.10 * envSeverity;

  if (riskScore >= 0.75) {
    eventStatus = "CRITICAL_FAULT";
    severity = "CRITICAL";
  } else if (riskScore >= 0.50) {
    eventStatus = "HIGH_RISK";
    severity = "HIGH";
  } else if (riskScore >= 0.25) {
    eventStatus = "WARNING";
    severity = "MEDIUM";
  } else {
    eventStatus = "NORMAL";
    severity = "LOW";
  }
}

void localAlarm() {
  if (riskScore >= 0.50) {
    digitalWrite(RED_LED_PIN, HIGH);
    digitalWrite(GREEN_LED_PIN, LOW);
    digitalWrite(BUZZER_PIN, HIGH);

    if (riskScore >= 0.75) {
      digitalWrite(RELAY_PIN, HIGH);  // Stop model train / activate signal
    }
  } else {
    digitalWrite(RED_LED_PIN, LOW);
    digitalWrite(GREEN_LED_PIN, HIGH);
    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(RELAY_PIN, LOW);
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("RAIL SAFETY AI");
  display.println("----------------");
  display.print("Status: ");
  display.println(eventStatus);
  display.print("Risk: ");
  display.println(riskScore);
  display.print("Dist: ");
  display.print(distanceCm);
  display.println(" cm");
  display.print("Vib: ");
  display.println(vibration);
  display.print("Temp: ");
  display.print(temperatureC);
  display.println(" C");
  display.display();
}

void sendThingSpeak() {
  if (WiFi.status() != WL_CONNECTED) return;

  HTTPClient http;
  String url = "http://" + String(THINGSPEAK_HOST) + "/update?api_key=" +
               THINGSPEAK_WRITE_KEY +
               "&field1=" + String(distanceCm) +
               "&field2=" + String(vibration) +
               "&field3=" + String(temperatureC) +
               "&field4=" + String(humidity) +
               "&field5=" + String(crackDetected ? 1 : 0) +
               "&field6=" + String(riskScore) +
               "&field7=" + String(lat, 6) +
               "&field8=" + String(lng, 6);

  http.begin(url);
  int code = http.GET();
  Serial.print("ThingSpeak response: ");
  Serial.println(code);
  http.end();
}

void sendN8nAlert() {
  if (WiFi.status() != WL_CONNECTED) return;
  if (riskScore < 0.25) return;

  HTTPClient http;
  http.begin(N8N_WEBHOOK_URL);
  http.addHeader("Content-Type", "application/json");

  StaticJsonDocument<768> doc;
  doc["device_id"] = "RAIL-ESP32-001";
  doc["status"] = eventStatus;
  doc["severity"] = severity;
  doc["risk_score"] = riskScore;
  doc["crack_left"] = crackLeft;
  doc["crack_right"] = crackRight;
  doc["distance_cm"] = distanceCm;
  doc["baseline_cm"] = baselineDistance;
  doc["vibration"] = vibration;
  doc["temperature_c"] = temperatureC;
  doc["humidity"] = humidity;
  doc["latitude"] = lat;
  doc["longitude"] = lng;

  String payload;
  serializeJson(doc, payload);

  int code = http.POST(payload);
  Serial.print("n8n response: ");
  Serial.println(code);
  http.end();
}

void loop() {
  readSensors();
  calculateRisk();
  localAlarm();
  updateDisplay();

  sendThingSpeak();
  sendN8nAlert();

  delay(15000);  // ThingSpeak free plan commonly accepts 15-second updates
}

ThingSpeak accepts sensor values through its update endpoint using a channel-specific Write API key; the example above sends distance, vibration, temperature, humidity, crack status, risk score, latitude, and longitude to eight fields.[cosmiclearn]

n8n Automation Design

Workflow overview

ESP32 HTTP POST
      │
      ▼
n8n Webhook node
      │
      ▼
AI Agent node
      │
      ├──► Google Sheets: Append incident row
      │
      ├──► Telegram: Send text alert
      │
      └──► Telegram: Send voice/audio alert

1. Webhook node

Create a webhook named:

railway-alert

Set:

  • HTTP Method: POST
  • Path: railway-alert
  • Response Mode: Immediately

The ESP32 posts JSON such as:

{
  "device_id": "RAIL-ESP32-001",
  "status": "HIGH_RISK",
  "severity": "HIGH",
  "risk_score": 0.72,
  "crack_left": true,
  "crack_right": false,
  "distance_cm": 14.6,
  "baseline_cm": 10.0,
  "vibration": 15.8,
  "temperature_c": 38.4,
  "humidity": 61.0,
  "latitude": 17.385044,
  "longitude": 78.486671
}

2. AI Agent node

Use an AI Agent or an LLM Chain node with this system prompt:

You are an AI railway maintenance assistant.

You will receive JSON sensor data from an ESP32 railway monitoring device.

Your tasks:
1. Classify the incident as NORMAL, WARNING, HIGH_RISK, or CRITICAL.
2. Identify the most likely issue: rail crack, track deformation, obstacle, excessive vibration, overheating, or sensor error.
3. Estimate urgency.
4. Write a short incident report for railway maintenance staff.
5. Write a short voice-alert script of no more than 30 words.

Return valid JSON only:
{
  "classification": "",
  "likely_issue": "",
  "urgency": "",
  "incident_report": "",
  "voice_script": "",
  "recommended_action": ""
}

Use this user prompt:

Sensor data:
{{ $json.body }}

The AI agent can use the n8n Telegram node as a tool; n8n documents that the Telegram node can be used with AI agents and supports human-in-the-loop approval.[docs.n8n]

3. Google Sheets node

Create a Google Sheet named:

Railway_Incident_Log

Use columns:

Timestamp Device ID Status Severity Risk Score Crack Left Crack Right Distance cm Vibration Temperature C Humidity Latitude Longitude AI Classification Likely Issue Recommended Action

Configure the Google Sheets node:

  • Operation: Append Row
  • Document: Railway_Incident_Log
  • Sheet: Sheet1
  • Map fields from the webhook and AI output.

4. Telegram text alert

Use the Telegram → Message → Send Message operation. n8n’s Telegram node supports sending messages to a chat or channel using a Chat ID or channel username.[docs.n8n]

Message text:

🚨 RAILWAY SAFETY ALERT

Status: {{ $json.classification }}
Likely issue: {{ $json.likely_issue }}
Urgency: {{ $json.urgency }}

{{ $json.incident_report }}

Recommended action:
{{ $json.recommended_action }}

Device: {{ $('Webhook').item.json.body.device_id }}
Risk score: {{ $('Webhook').item.json.body.risk_score }}

Location:
https://maps.google.com/?q={{ $('Webhook').item.json.body.latitude }},{{ $('Webhook').item.json.body.longitude }}

5. Telegram voice alert

There are two practical options:

Method How it works Best for
Pre-recorded MP3 Upload normal.mp3, warning.mp3, critical.mp3; n8n selects the correct file Simple, reliable demo
AI TTS API AI agent creates text, ElevenLabs/OpenAI TTS/Google TTS creates MP3, n8n sends audio Dynamic voice alerts

For a dynamic alert:

  1. AI Agent returns voice_script.
  2. Add an HTTP Request node to your TTS provider.
  3. Save the returned MP3 as binary data.
  4. Add Telegram → Message → Send Audio.
  5. Set Binary File to the TTS output field.
  6. Add a caption such as Railway fault voice alert.

n8n’s Telegram node includes a Send Audio operation that can send an audio file from binary data or from a URL.[docs.n8n]

Web Dashboard Code

Add this inside the ESP32 sketch to create a lightweight live dashboard. It shows sensor values, risk status, and allows a manual test alert.

#include <WebServer.h>

WebServer server(80);

void handleRoot() {
  String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AI Railway Safety Dashboard</title>
  <style>
    body { font-family: Arial; background:#0b1220; color:white; text-align:center; }
    .card { background:#152238; margin:12px auto; padding:16px; max-width:420px; border-radius:12px; }
    .normal { color:#4ade80; }
    .warning { color:#facc15; }
    .danger { color:#f87171; }
    button { padding:12px 20px; border:none; border-radius:8px; background:#2563eb; color:white; }
  </style>
</head>
<body>
  <h2>🚆 AI Railway Safety Dashboard</h2>

  <div class="card">
    <h3>Status</h3>
    <p id="status" class="normal">NORMAL</p>
    <p>Risk Score: <span id="risk">0</span></p>
  </div>

  <div class="card">
    <h3>Sensor Readings</h3>
    <p>Distance: <span id="distance">0</span> cm</p>
    <p>Vibration: <span id="vibration">0</span></p>
    <p>Temperature: <span id="temperature">0</span> °C</p>
    <p>Humidity: <span id="humidity">0</span> %</p>
    <p>Crack Left: <span id="crackLeft">NO</span></p>
    <p>Crack Right: <span id="crackRight">NO</span></p>
  </div>

  <div class="card">
    <button onclick="fetch('/test')">Send Test Alert</button>
  </div>

  <script>
    async function update() {
      const r = await fetch('/data');
      const d = await r.json();

      document.getElementById('status').innerText = d.status;
      document.getElementById('status').className =
        d.risk >= 0.5 ? 'danger' : d.risk >= 0.25 ? 'warning' : 'normal';

      document.getElementById('risk').innerText = d.risk;
      document.getElementById('distance').innerText = d.distance;
      document.getElementById('vibration').innerText = d.vibration;
      document.getElementById('temperature').innerText = d.temperature;
      document.getElementById('humidity').innerText = d.humidity;
      document.getElementById('crackLeft').innerText = d.crackLeft ? 'YES' : 'NO';
      document.getElementById('crackRight').innerText = d.crackRight ? 'YES' : 'NO';
    }

    setInterval(update, 2000);
    update();
  </script>
</body>
</html>
)rawliteral";

  server.send(200, "text/html", html);
}

void handleData() {
  String json = "{";
  json += "\"status\":\"" + eventStatus + "\",";
  json += "\"risk\":" + String(riskScore) + ",";
  json += "\"distance\":" + String(distanceCm) + ",";
  json += "\"vibration\":" + String(vibration) + ",";
  json += "\"temperature\":" + String(temperatureC) + ",";
  json += "\"humidity\":" + String(humidity) + ",";
  json += "\"crackLeft\":" + String(crackLeft ? "true" : "false") + ",";
  json += "\"crackRight\":" + String(crackRight ? "true" : "false");
  json += "}";

  server.send(200, "application/json", json);
}

void handleTest() {
  riskScore = 0.85;
  eventStatus = "CRITICAL_FAULT";
  severity = "CRITICAL";
  sendN8nAlert();
  server.send(200, "text/plain", "Test alert sent");
}

void startWebServer() {
  server.on("/", handleRoot);
  server.on("/data", handleData);
  server.on("/test", handleTest);
  server.begin();
}

Call startWebServer(); at the end of setup() and add server.handleClient(); at the beginning of loop().

ThingSpeak Channel Setup

Create a ThingSpeak channel with these fields:

Field Data
1 Ultrasonic distance in cm
2 Vibration magnitude
3 Temperature in °C
4 Humidity in %
5 Crack status: 0 = normal, 1 = crack
6 AI risk score
7 Latitude
8 Longitude

ThingSpeak uses a Write API key to authorize and route incoming data points to the correct channel. Similar published railway-monitoring systems use fields for vibration axes, temperature, humidity, crack status, distance, position, and combined vibration index.[ijarcce][cosmiclearn]

Step-by-Step Build Procedure

Step 1: Assemble the prototype

  1. Place the ESP32 on a breadboard.
  2. Connect both IR sensors to GPIO 34 and GPIO 35.
  3. Connect HC-SR04 TRIG to GPIO 5 and ECHO to GPIO 18 through a voltage divider.
  4. Connect MPU6050 and OLED to I²C pins GPIO 21 and GPIO 22.
  5. Connect DHT22 data to GPIO 4 with a 10 kΩ pull-up resistor.
  6. Connect GPS TX/RX to GPIO 16/17.
  7. Connect the buzzer, LEDs, and optional relay.
  8. Use a common ground for all modules.

Step 2: Calibrate the sensors

  1. Place the ultrasonic sensor at a known distance from a flat rail section.
  2. Record that distance in baselineDistance.
  3. Place the IR sensors above a clean rail surface.
  4. Verify that normal rail gives HIGH and a simulated crack gives LOW.
  5. Move the trolley or shake the setup gently to establish a normal vibration range.
  6. Adjust vibrationThreshold to avoid false alarms.

Step 3: Configure ThingSpeak

  1. Create a ThingSpeak account and channel.
  2. Enable eight fields.
  3. Copy the Write API key.
  4. Replace YOUR_THINGSPEAK_WRITE_KEY in the ESP32 code.
  5. Upload the code and confirm values appear in the channel.
  6. Create line charts for distance, vibration, temperature, and risk score.

Step 4: Create the Telegram bot

  1. Open Telegram and search for @BotFather.
  2. Send /newbot.
  3. Choose a bot name and username.
  4. Copy the bot token.
  5. Create a Telegram group or channel for maintenance staff.
  6. Add the bot as an administrator if using a channel.
  7. Obtain the chat ID using a Telegram trigger or bot API method.

n8n notes that a bot must be added to a channel before it can send messages there.[docs.n8n]

Step 5: Build the n8n workflow

  1. Add a Webhook node: POST /railway-alert.
  2. Add an AI Agent node.
  3. Connect an LLM chat model node.
  4. Paste the AI system prompt and user prompt.
  5. Add a Google Sheets → Append Row node.
  6. Add a Telegram → Send Message node.
  7. Add an HTTP Request node for TTS.
  8. Add a Telegram → Send Audio node.
  9. Activate the workflow.
  10. Copy the production webhook URL into the ESP32 code.

Step 6: Test the complete system

Test Expected result
Normal track Green LED, NORMAL status, ThingSpeak update
Black tape crack under IR sensor Crack detected, risk increases, alert sent
Move ultrasonic target away by 3 cm Distance fault detected
Shake MPU6050 Vibration fault detected
Simulate critical condition Buzzer, red LED, relay trigger, Telegram text and voice
Check Google Sheets New row with sensor values and AI recommendation
Check Telegram Text alert plus voice/audio alert received

Google Sheets Automation

A typical logged incident row may look like this:

Timestamp Device ID Status Severity Risk Crack Distance Vibration AI Classification Action
2026-10-31 14:25:10 RAIL-ESP32-001 HIGH_RISK HIGH 0.72 YES 14.6 15.8 Rail crack likely Inspect section and restrict movement

The Google Sheets node should append this row whenever the webhook receives an event with risk score above 0.25.

AI Agent Sample Output

For an input with crack detected, distance deviation, and high vibration:

{
  "classification": "CRITICAL",
  "likely_issue": "Probable rail surface crack combined with track deformation and abnormal vibration",
  "urgency": "Immediate inspection required",
  "incident_report": "Device RAIL-ESP32-001 detected a crack signal on the left IR sensor. Ultrasonic distance increased from the 10 cm baseline to 14.6 cm, and vibration reached 15.8. The combined risk score is 0.85.",
  "voice_script": "Critical railway fault detected. Crack and track deformation suspected. Immediate inspection required.",
  "recommended_action": "Stop model train movement, mark the section as unsafe, dispatch maintenance staff, and inspect the left rail and track alignment."
}

Project Documentation Structure

Use these sections for your college or project report:

  1. Title: AI Railway Accident Prevention and Crack Detection System Using ESP32, IoT, n8n, and Telegram Voice Alerts
  2. Abstract: Explain how the system detects cracks and abnormal track conditions, uploads data to the cloud, and sends AI-generated alerts.
  3. Objectives: Detect cracks, monitor vibration, prevent accidents, automate alerts, and maintain an incident history.
  4. Existing system: Manual inspection is periodic, slow, and may miss early defects.
  5. Proposed system: Continuous sensor monitoring, edge decision-making, cloud logging, and automated AI alerts.
  6. Block diagram: Include the architecture diagram above.
  7. Circuit diagram: Include the schematic and pin table.
  8. Hardware description: Explain each sensor and module.
  9. Software description: Arduino IDE, ESP32 libraries, ThingSpeak, n8n, Telegram Bot API, Google Sheets, and TTS.
  10. Algorithm: Sensor reading, filtering, threshold detection, risk score, cloud upload, alerting.
  11. Flowchart: Include the software flowchart.
  12. Implementation: Show wiring photos, serial monitor output, ThingSpeak charts, n8n workflow, Telegram alerts, and Google Sheet.
  13. Testing: Include the test table and observed results.
  14. Advantages: Low-cost, real-time, scalable, remote monitoring, automated reporting.
  15. Limitations: Prototype-level accuracy, weatherproofing needed, requires calibration, not certified for real railway deployment.
  16. Future scope: Camera-based deep-learning crack detection, LoRaWAN for long-range coverage, solar power, edge TinyML, digital twin, automatic train-stop integration.

Future Improvements

  • Add an ESP32-CAM to capture crack images and send them to Telegram.
  • Train a CNN/YOLO model on rail-crack images for visual detection.
  • Use LoRa or GSM for areas without Wi-Fi.
  • Add solar power and battery monitoring.
  • Use multiple sensor nodes along the track and map incidents on a dashboard.
  • Add predictive maintenance using historical ThingSpeak data.
  • Add automatic gate/track-circuit simulation and emergency stop.

This design gives you a complete demonstration-ready project: ESP32 edge sensing, AI-assisted decision-making, cloud dashboard, automated spreadsheet recordkeeping, and Telegram voice notifications. Telegram’s n8n integration supports both standard messages and audio files, making it suitable for text-plus-voice safety alerts.[docs.n8n]