AranyaLink — Open-Source Forest Fire Detection Mesh Network
by The Uncertified Engineer in Circuits > Sensors
188 Views, 1 Favorites, 0 Comments
AranyaLink — Open-Source Forest Fire Detection Mesh Network
Aranya (अरण्य) is Sanskrit word for forest. This project is named after what it protects.
Introduction
Every year, wildfires cost the United States between $394 billion and $893 billion. Globally, the 2024–25 fire season burned an area larger than India and released 8 billion tonnes of CO₂. The 2025 Southern California fires alone caused $140 billion in economic damage in a matter of weeks.
The technology to catch fires early exists. A professional IoT sensor mesh can detect a smoldering fire in under 3 minutes. A single air tanker dispatched at minute two costs $14,000 per hour. A fire crew deployed at hour three costs $1.3 million per week in wages alone. The math is not complicated — early detection saves everything downstream.
The problem is access. A state-wide sensor network costs $36 million. A single AI camera station runs $50,000 per year. Satellite subscriptions start at $12,000 annually per municipality. The communities living closest to fire-prone forests — in India, Indonesia, Brazil, rural Africa — have none of it. Roughly 30% of forest fires go undetected in their incipient stages, not because the science is hard, but because the price tag is prohibitive.
AranyaLink closes that gap.
It is an open-source, infrastructure-free wildfire detection mesh network built on ESP32 microcontrollers, costing under $10 per node, requiring no Wi-Fi, no cellular towers, no cloud subscription, and no prior infrastructure of any kind. Nodes communicate directly with each other using ESP-NOW, a peer-to-peer protocol that turns every unit into both a detector and a repeater. A fire detected deep in the forest hops — node to node — until it reaches a Ground Control Station at the forest edge, delivering a GPS-precise alert with temperature, humidity, flame status, and a live Google Maps link in seconds.
The mesh is self-healing. The detection is dual-verified. The cost is democratic.
A better world is one where protecting a forest doesn't require a government budget. Where a community of makers can deploy a detection network on a Saturday morning and leave it watching over their watershed. Where the gap between a smoldering ember and a catastrophic megafire is closed not by a $36 million contract, but by a $10 node and an open-source sketch.
That is what this project builds. Let's get into it.
How It Works
Each AranyaLink node watches its local environment continuously. When both its temperature sensor and infrared flame sensor cross fire thresholds simultaneously, it broadcasts an alert packet over ESP-NOW — no router, no internet, nothing in between.
Every neighboring node that receives the packet does two things: it checks its own sensors to independently confirm the fire, then re-broadcasts the packet further into the network. This dual-verification step filters out false alarms and builds a confidence score — the more nodes confirm, the higher the certainty.
The packet travels hop-by-hop across the mesh until it reaches the Ground Control Station — a dedicated ESP32 plugged into a laptop at the forest perimeter — which prints a formatted alert with GPS coordinates, sensor readings, verification count, confidence level, and a live Google Maps link directly to the Serial Monitor.
The full chain — from ignition to alert — takes seconds.
Supplies
Per Sensor Node (build as many as your coverage area requires)
- ESP32 DevKit v1 (30-pin)
Main controller, ESP-NOW radio (buy)
- DHT11 Temperature & Humidity Sensor
Ambient heat and humidity monitoring (buy)
- 3-Pin IR Flame Sensor (KY-026 or equivalent)
Infrared flame detection (buy)
- Neo-6M GPS Module (with antenna)
Real-time coordinates (buy)
- Jumper wires (M-M and M-F)
Connections (buy)
- Breadboard (for prototyping)
Layout and testing (buy)
Estimated total per node~$9 – $10
For permanent outdoor deployment, additionally:
- 18650 Li-ion battery + TP4056 charger module
Field power supply$3 – $5
- 5V solar panel (mini, 1–2W)
Autonomous recharging. $3 – $6
- IP65 waterproof enclosure (small ABS box)
Weather protection$2 – $4
Ground Control Station (one per network)
- ESP32 DevKit v1
ESP-NOW receiver radio$3 – $5
- USB cable (Micro-USB or USB-C)
Serial Monitor connection to PC
- On handLaptop or PC with Arduino IDE
Alert display and loggingOn hand
Tools & Software
- Arduino IDE (free — arduino.cc)
- USB-to-Serial driver for your ESP32 board (CP2102 or CH340, depending on variant)
- Arduino Library Manager — install: DHT sensor library (Adafruit), Adafruit Unified Sensor (dependency), TinyGPS++ (Mikal Hart)
- Soldering iron + solder (optional — required only for permanent installations)
Understanding the Network Architecture
An AranyaLink network has two physical components — sensor nodes scattered across the forest, and a Ground Control Station (GCS) at the forest perimeter connected to a laptop. Nodes never connect to a router or the internet. They talk exclusively to each other over ESP-NOW, Espressif's peer-to-peer radio protocol, broadcasting to every node within radio range simultaneously.
The packet travels in three stages:
- Detect — A node's temperature crosses the threshold and its IR flame sensor activates at the same moment. It generates a random packetID, fills the packet struct with its GPS coordinates, sensor readings, and Node ID, then broadcasts immediately.
- Verify or relay — Every neighboring node that receives the packet instantly reads its own sensors. If it also detects fire conditions, it appends its Node ID to the verifyingNodes[] array and increments verificationCount before re-broadcasting. If its sensors are normal, it re-broadcasts the packet unchanged. Either way, the packet keeps moving.
- Propagate — The packet hops node-to-node across the mesh until it reaches the GCS, which prints a formatted alert with GPS coordinates, a confidence level, and a direct Google Maps link.
Loop prevention — Each node keeps a rolling buffer of the last 10 processed packetID values. Any packet whose ID already exists in the buffer is silently dropped, preventing the same alert from circling the network indefinitely.
Confidence scoring from the verificationCount field:
Self-healing by design
Every AranyaLink node is completely autonomous. It has no awareness of what other nodes exist on the network, no pairing process, no registration, and no dependency on any central coordinator. A node powers on, listens, and broadcasts. That is its entire relationship with the network.
This independence is what makes the mesh self-healing. If Node 4 is destroyed by an advancing fire front, the network does not notice. The nodes that previously routed through Node 4 simply broadcast their packets into the air — and if any other node is within range to pick it up and forward it, the alert still reaches the GCS. No reconfiguration. No manual intervention. No single point of failure.
A hub-and-spoke system — where all nodes report to one central gateway — fails completely the moment that gateway is compromised. In a wildfire, the gateway is exactly the kind of infrastructure most likely to be in the fire's path. AranyaLink's flat, peer-to-peer architecture means the only way to silence the network entirely is to destroy every node simultaneously. The fire would have to outrun the alert it triggered.
Wiring the Sensor Node
Each sensor node uses three peripherals wired to a single ESP32 DevKit. All three operate at 3.3V — no voltage dividers or level shifters required. The GCS requires no wiring at all beyond a USB cable to your laptop.
Connection table
Three things worth knowing before you wire
DHT11 pull-up — The 10kΩ resistor between the DATA pin and 3V3 is not optional for reliable field operation. The ESP32 has weak internal pull-ups, but over any length of wire in an outdoor enclosure they introduce read failures. Use the external resistor.
IR flame sensor polarity — Most KY-026 and equivalent 3-pin modules pull DO LOW when a flame is detected and HIGH when clear. This is already accounted for in the code with #define FLAME_ACTIVE LOW. If your module behaves the opposite way, change that single define.
Neo-6M power — Most Neo-6M breakout boards include an onboard 3.3V regulator, meaning they accept either 3.3V or 5V on their VCC pin. Check the silkscreen on your specific board. If it says "3.3V" on the VCC pad, wire directly to 3V3. If it says "5V" or "VCC", wire to the ESP32's VIN pin (5V USB passthrough). The UART TX/RX lines are always 3.3V logic and connect directly to ESP32 GPIO with no level shifting.
Ground Control Station
The GCS is a bare ESP32 with nothing connected except a USB cable to your laptop. No sensors, no peripherals, no breadboard. Flash the GCS sketch, open Serial Monitor at 115200 baud, and it is ready.
Setting Up Arduino IDE & Installing Libraries
Install the ESP32 board package
Open Arduino IDE. Go to File → Preferences and paste the following URL into the Additional Boards Manager URLs field:
Then go to Tools → Board → Boards Manager, search for esp32 by Espressif Systems, and install it. This adds full ESP32 support including the WiFi.h and esp_now.h libraries — both ship built-in with the board package, no separate install needed.
Install the three required libraries
Go to Sketch → Include Library → Manage Libraries and install the following one by one:
DHT sensor library - by Adafruit
Adafruit Unified Sensor - also by Adafruit
TinyGPS++ - by Mikal Hart
When installing the DHT library, Arduino IDE will prompt "Install all" to include the Adafruit Unified Sensor dependency — click Install All.
Select your board and port
Plug your ESP32 into your computer via USB. Go to Tools → Board → ESP32 Arduino and select ESP32 Dev Module. Then go to Tools → Port and select the COM port your ESP32 appeared on. If no port appears, your board likely needs a driver — check the chip on your USB-to-Serial bridge (CP2102 or CH340) and install the corresponding driver from the manufacturer's website.
Verify the setup
Before uploading anything, open File → Examples → WiFi → WiFiScan and hit the tick (✓) button to compile only. If it compiles without errors, your environment is ready.
Configuring the Node Sketch
Download the full sketch from the GitHub repository before starting this step
Every node in the network runs the same sketch. The only section that changes between nodes is the small configuration block at the very top of AranyaLink_Node.ino. You never need to touch anything below it for a standard deployment.
NODE_ID must be a unique integer on every physical node. Node 1, Node 2, Node 3 and so on. This is what gets stamped into the verifyingNodes[] array when a node confirms a fire, and what the GCS displays to identify which units responded.
NODE_LAT_FALLBACK / NODE_LON_FALLBACK are the hardcoded coordinates used in any alert packet sent before the GPS module acquires a satellite fix. Look up the coordinates of your deployment site on Google Maps, paste them here before flashing each node. Once the GPS acquires a fix outdoors (typically within 30–90 seconds of powering on with a clear sky view), these fallback values are replaced automatically with live GPS data and are never used again until the next power cycle.
TEMP_THRESHOLD defaults to 50°C. In regions with extreme ambient summer heat — deserts, tropical forests — consider raising this to 55°C or 60°C to reduce false positives from peak daytime temperatures. The flame sensor provides the second layer of confirmation, so the threshold doesn't need to be ultra-conservative.
FLAME_ACTIVE defaults to LOW, matching the behavior of the KY-026 and most 3-pin IR flame sensor modules. If your module's DO pin goes HIGH on flame detection instead, change this one define. Nothing else in the code needs to change.
Flashing multiple nodes
Flash Node 1 with NODE_ID 1, disconnect, change NODE_ID to 2, flash Node 2, and so on. The GCS sketch has no configuration variables — flash it identically to every GCS unit.
Code Walkthrough — the Sensor Node
You don't need to understand every line to deploy AranyaLink. But understanding four key sections will help you debug, adapt, and extend it. Here they are.
The packet struct
__attribute__((packed)) forces the compiler to store this struct in memory with no padding bytes between fields. This matters because ESP-NOW transmits the struct as a raw block of bytes — if two nodes compiled the same code with different padding, the fields would misalign on the receiving end and every value would be silently corrupted. Packed structs are mandatory for any binary wireless protocol between microcontrollers.
The loop — fire detection
Both thresholds must be crossed simultaneously — temperature AND flame. Neither alone triggers an alert. This is the first layer of false-positive filtering built directly into the detection logic.
esp_random() uses the ESP32's hardware random number generator, seeded by the RF subsystem, to generate the packetID. This makes collisions between simultaneous alerts on different nodes statistically negligible across any realistic deployment size.
markSeen() is called immediately after broadcasting the node's own packet. This prevents the node from re-processing its own alert when a neighbor reflects it back.
OnDataRecv — the repeater engine
This is the heart of AranyaLink. It runs every time an ESP-NOW packet arrives.
Six lines of logic, six jobs:
- Size check — Drops any packet that isn't exactly sizeof(AranyaPacket) bytes. Filters noise and malformed frames.
- Loop prevention — Checks the rolling 10-slot seenPackets[] buffer. If this packetID has been processed before, the function returns immediately. This is what stops alerts from bouncing indefinitely around a dense mesh.
- Sensor read — The node reads its own sensors in real time, not from a cached value. This ensures the verification reflects actual conditions at the moment the packet passes through.
- Verify or relay — If this node's own sensors confirm fire conditions, it appends its NODE_ID to the verifyingNodes[] array and increments the count. If sensors are normal, this block is skipped entirely and the packet is forwarded unchanged.
- Forward — Re-broadcasts the packet (verified or unmodified) to all neighbors within radio range.
- Mark — Adds the packetID to the seen buffer so this node never processes the same alert twice.
GPS integration
TinyGPS++ works as a streaming parser — it processes one character at a time from the GPS serial port. By draining the serial buffer on every loop iteration before anything else, the coordinates are always as fresh as the GPS module can provide. currentLat and currentLon start as the hardcoded fallback values and are silently updated in the background the moment a satellite fix is acquired, with no interruption to the sensor polling or ESP-NOW listening.
Code Walkthrough — the Ground Control Station
The GCS sketch is intentionally lean. It has no sensors, no peers to register, and nothing to broadcast. Its entire job is to receive packets, deduplicate them, and print formatted alerts.
What a successful alert looks like
When a fire alert reaches the GCS, the Serial Monitor prints:
Packet ID — The unique identifier generated at fire origin. If you see the same ID arrive multiple times with different Relayed via MAC addresses, the mesh is working correctly — the same alert propagated along multiple paths.
Relayed via — The MAC address of the last node that forwarded the packet before it reached the GCS. This is not necessarily the origin node. It tells you which physical unit is closest to the GCS in the packet's travel path.
Maps Link — Paste directly into any browser or tap on a phone. Opens Google Maps pinned to the GPS coordinates of the origin node — the node that first detected the fire.
Confidence level — Derived entirely from verificationCount:
Duplicate packets
If the same packetID arrives more than once (via different mesh paths), the GCS prints a compact [DUP] line instead of a full alert block:
This is not an error — it means the mesh has redundant paths to the GCS, which is exactly what you want. More [DUP] lines mean a healthier, more resilient network.
The 30-second heartbeat
Every 30 seconds with no activity, the GCS prints:
This confirms the unit is alive, powered, and listening. If this line stops appearing, the GCS has frozen or lost power.
Uploading & Bench Testing
Uploading the sketches
- Open AranyaLink_Node.ino in Arduino IDE
- Set NODE_ID to 1 in the configuration block
- Select Tools → Board → ESP32 Dev Module
- Select the correct COM port under Tools → Port
- Set Tools → Upload Speed → 115200
- Click Upload (→). The IDE will compile, then you'll see Connecting.... followed by a progress bar
- Once uploaded, open Tools → Serial Monitor, set baud to 115200
- Press the EN (reset) button on the ESP32 — you should see the AranyaLink boot message
Repeat for the GCS unit using AranyaLink_GCS.ino — no configuration changes needed.
Triggering a test alert on your desk
With both units powered and Serial Monitor open on the GCS, simulate a fire event on Node 1:
- Heat the DHT11 — hold a candle or a lighter few cm from the sensor until the Serial Monitor on Node 1 shows a temperature reading above your TEMP_THRESHOLD (you can also reduced the TEMP_THRESHOLD while testing ).
- Trigger the flame sensor — flick a lighter few cm from the IR sensor module, or briefly shine a phone torch directly at it (IR flame sensors respond to the infrared component of an open flame most reliably, but a bright incandescent source works for bench testing)
When both conditions are met in the same 2-second polling cycle, Node 1 will print [ALERT] FIRE DETECTED! and the GCS Serial Monitor will display the full formatted alert block within one or two seconds.
Five common failure points
Field Deployment
Planning node placement
ESP-NOW has a practical range of 100–150 metres between nodes in open terrain with moderate tree cover. Dense forest canopy reduces this to 60–80 metres. Plan your deployment with this in mind:
- Space nodes no more than 120 metres apart in forested terrain
- Place nodes at elevated positions where possible — on a post, a tree branch, or a slight ridge — to maximize line-of-sight between units
- The GCS should sit at the forest perimeter, ideally elevated, with at least one sensor node within direct range
- A network of 8–10 nodes spaced at 120m intervals covers approximately 1–1.5 km of forest edge — enough to protect a village boundary or a nature reserve perimeter
For interior forest coverage rather than edge coverage, arrange nodes in a grid pattern at 100m spacing. Ten nodes in a grid cover roughly 9 hectares.
Power
Each node runs continuously at full power. A 1200mAh 18650 Li-ion cell through a TP4056 charge controller and a 5V boost converter provides approximately 6–8 hours of standalone runtime. For permanent deployment, pair with a 1–2W 5V mini solar panel — sufficient to maintain charge through a full day in direct or partial sunlight, keeping the node alive indefinitely.
Wire the solar panel to the TP4056 charge input (B+ / B-), the battery to the battery terminals, and the 5V boost converter output to the ESP32's VIN pin. No additional components needed.
The enclosure
The AranyaLink prototype enclosures are built from cardboard — intentionally.
If this project is about making wildfire detection accessible to every community on earth, the build materials need to match that promise. A cardboard box, a roll of packing tape, and a hot glue gun are available in every country, in every town, for less than the price of a coffee. A 3D-printed enclosure is not.
For a field-ready cardboard enclosure:
- Double-wall the cardboard at all six faces for structural rigidity. A box within a box with a 5mm air gap is significantly more robust than single-layer card
- Seal all external seams with two layers of packing tape, overlapping by 10mm. Run tape across the grain of the cardboard as well as along it
- Wax the outer surface — rub a plain household candle across every face, then pass a heat gun or hairdryer over it to melt the wax into the fibres. This makes the surface water-repellent and dramatically extends outdoor lifespan
- Cable entry — drill or pierce a small hole for the GPS antenna cable. Fill the gap with hot glue after routing the cable through. This is the most weather-critical point of the enclosure
- Mount the flame sensor and DHT11 facing outward through small cutouts in the enclosure wall, sealed around the edges with hot glue
A waxed, double-walled, taped cardboard enclosure will survive light rain and several weeks of outdoor exposure. For extended deployment through a full monsoon or winter, upgrade to a $2–3 ABS junction box from any hardware store — the same wiring, the same nodes, just a different shell.
GPS fix acquisition
The Neo-6M requires a clear view of the sky to acquire a satellite fix. Power the node outdoors and allow 60–120 seconds for the first fix after a cold start. Once a fix is acquired, the module stores satellite almanac data in its onboard battery-backed memory and subsequent cold starts fix in under 30 seconds. The Serial Monitor will show GPS:SRCH until a fix is found, then switch to GPS:FIX with live coordinates.
Always verify a GPS:FIX reading on each node before final installation. A node sealed inside an enclosure in a dense forest canopy gap may never acquire a fix — in that case it will transmit the hardcoded fallback coordinates, which is still useful but less precise.
Reading & Acting on Alerts
The full alert in the field
When an alert arrives at your GCS laptop, the Serial Monitor shows the complete block from Step 6. The fields that matter most for an operational response are:
Maps Link — Tap this immediately. It opens the GPS coordinates of the origin node in Google Maps. If the node had a satellite fix, this is accurate to within 3–5 metres. If it was transmitting fallback coordinates, it points to the approximate location you hardcoded before deployment — still a useful starting quadrant.
Origin Node — Cross-reference against your deployment map to identify the physical location of the detecting unit. Label each node enclosure with its NODE_ID in permanent marker before deployment so field teams can locate and check any specific unit.
Confidence level — Treat Unverified alerts as smoke signals worth investigating. Treat Medium and High alerts as confirmed fire events requiring immediate dispatch. In a real deployment, set up a simple protocol: Unverified triggers a phone call to the nearest ranger, Medium or High triggers emergency services.
Relayed via MAC — If the origin node's GPS coordinates seem inconsistent with the relaying MAC address, the fire may have moved or the origin node may have been destroyed by the advancing fire front. The relaying node's position gives you a secondary location reference.
Watching the mesh in real time
Keep the GCS Serial Monitor open during any alert event. Each [DUP] line that follows the initial alert shows you another path the packet traveled through the network. A healthy mesh produces 2–4 duplicate lines per alert. Zero duplicates means the GCS only has one path from the origin — consider adding a node to improve redundancy at that point in the network.
The 30-second [GCS] Up: heartbeat line confirms the system is live. If it stops, the GCS has lost power or frozen. In a permanent installation, set up a watchdog — tape the GCS ESP32 inside its own cardboard enclosure with a TP4056 and battery so it survives a power cut at the base station laptop.
Limitations, Future Improvements & Vision
Honest limitations
AranyaLink is a proof-of-concept and a foundation. It is not a finished commercial product, and being clear about what it cannot do is as important as celebrating what it can.
ESP-NOW range — 100–150 metres per hop in forested terrain. For large-scale deployments covering thousands of hectares, this requires a dense node grid that may be impractical. The architecture directly supports swapping ESP-NOW for LoRa (SX1276/SX1278) which extends hop range to 1–2 kilometres — the same mesh logic, longer wires between nodes.
DHT11 accuracy — ±2°C accuracy and a 1Hz maximum sample rate. In applications where the ambient temperature frequently approaches the detection threshold, this margin introduces uncertainty. Upgrading to a DHT22 (±0.5°C) or SHT31 (±0.3°C) requires changing one #define in the configuration block and swapping the physical component.
IR flame sensor — The KY-026 detects infrared radiation in the 760–1100nm range. Bright direct sunlight can trigger occasional false positives on sensors facing west in late afternoon. Mounting sensors in a shaded orientation within the enclosure and adding a small cardboard sun visor over the sensor window eliminates this.
No persistent logging — The GCS prints alerts to Serial Monitor but does not write them to a file, SD card, or database. If the laptop running the GCS is closed or the Serial Monitor is not open, alerts are lost. Adding an SD card module to the GCS ESP32 and writing each packet as a JSON line to a log file is a straightforward upgrade.
GPS cold start — In dense canopy, the GPS may never acquire a fix, falling back to hardcoded coordinates. This is mitigated by careful node placement during deployment, but cannot be fully solved with the Neo-6M hardware.
The upgrade path
AranyaLink is designed to grow. Every major limitation has a clear, low-cost solution:
None of these upgrades require rewriting the core architecture. The packet struct, the mesh logic, the verification system, and the GCS output format remain identical. AranyaLink is a foundation you build on, not a finished ceiling.
Vision
The global wildfire detection ecosystem has two tiers. At the top: satellites, AI camera networks, and enterprise IoT meshes operated by governments and well-funded agencies in wealthy nations. At the bottom: nothing. A ranger with binoculars. A farmer who smells smoke at 3am.
AranyaLink is not trying to replace the top tier. ALERTCalifornia's 1,240 cameras and OroraTech's orbital constellation do things a $15 ESP32 will never do. But they also cost things that most of the world will never afford.
What AranyaLink demonstrates is that the gap between those two tiers — the gap where 30% of forest fires grow undetected — does not require a $36 million contract to begin closing. It requires an ESP32, three sensors, a cardboard box, and someone who cares enough about a forest to build something that watches over it.
The name comes from Sanskrit. Aranya — the forest — was not just geography in the ancient world. It was a system of interdependence. Every part sustained every other part. The scholars who retreated into the Aranya to write their treatises understood something that the modern wildfire crisis keeps relearning: when you protect the forest, you protect everything the forest sustains.
A network of AranyaLink nodes watching over a watershed is a small thing. A few microcontrollers in cardboard boxes zip-tied to trees. But the principle it represents is not small. It is the idea that protection should not be a function of budget. That the communities most exposed to risk deserve the same early warning as the ones with the largest procurement teams.
Build a node. Share the design. Plant it somewhere that needs watching.
The forest doesn't wait — but now, neither do we.
I built the first AranyaLink prototype as a 15 year old high-school student, on a desk, with $10 in components, a free IDE, and an afternoon. No lab. No grant. No team. If that is possible, the question that follows is uncomfortable but necessary: what exactly is stopping a nation with a forest ministry, a disaster management budget, a space program, and thousands of kilometres of fire-vulnerable forest from deploying ten thousand of these tomorrow? The technology is not the barrier. It never was.