Contents β 26 sections
Project Overview
Watches a waste site for methane build-up and leaks, reporting concentration as a fraction of the explosive limit so a dangerous pocket is caught before it can ignite.
A landfill is a slow methane factory. Buried organic waste decomposes without oxygen and produces landfill gas β roughly half methane β for decades after the site closes. Methane is both a potent greenhouse gas (dozens of times worse than COβ over its lifetime) and, in the wrong concentration, explosive: between about 5% and 15% in air it will ignite from any spark. It does not stay put, either β it migrates sideways through soil and can accumulate in a nearby building's basement or a service trench far from the tip face. This monitor puts methane sensing across and around a waste site so a build-up or a leak is detected while it is still a warning, not yet a hazard.
The single most important design decision is how the reading is expressed. A raw ppm or percent-methane number means little to the person who has to act on it; what matters for safety is how close the gas is to the point where it can explode. So the monitor reports concentration as a percentage of the lower explosive limit (%LEL) β 100% LEL being the 5%-methane point where the atmosphere becomes flammable β and stages its alarms as fractions of that: a low-level warning well before danger, a serious alarm approaching the explosive range, with the numbers chosen so people act with a wide safety margin. Temperature, humidity and barometric pressure are logged alongside because they drive when and where gas migrates and surfaces (a falling barometer, in particular, lets buried gas expand and escape).
Waste sites are large, wet, corrosive and often without power or network, so the nodes are solar-powered, sealed and ruggedised, communicate over LoRa, and log locally so nothing is lost. A network of them turns a sprawling site into a live methane map β showing which cells are venting, whether a migration front is heading toward the boundary and a neighbouring property, and how emissions rise and fall with the weather. It is explicit that it is a monitoring and early-warning aid within a site's formal gas-safety regime, not a replacement for certified fixed detectors or intrinsically-safe equipment where those are required β but as a dense, honest, self-reporting layer it catches the developing problems that periodic manual surveys miss between visits.
What this project does
- Measures methane and reports it as a percentage of the lower explosive limit (%LEL)
- Stages alarms as fractions of the explosive limit with a wide safety margin
- Logs temperature, humidity and barometric pressure that drive gas migration
- Maps which cells are venting and whether a migration front nears the boundary
- Runs on solar + battery across a large, powerless site
- Reports over LoRa and logs locally through outages
- Complements, does not replace, certified fixed gas-safety systems
Real-World Applications
| Setting | How it is used |
|---|---|
| Active and closed landfills | Continuous surface and perimeter methane monitoring to catch venting cells and lateral migration long after a site has stopped taking waste. |
| Landfill boundary / property protection | Perimeter nodes warning if a migration front approaches neighbouring buildings where gas could accumulate dangerously. |
| Composting and anaerobic-digestion sites | Detecting methane build-up around organic-waste processing and biogas infrastructure. |
| Old/contaminated land redevelopment | Monitoring former tips being surveyed or built on, where buried gas remains a long-term hazard. |
Deployment contexts where a build of this kind earns its keep.
Features & Capabilities
- %LEL reporting β the number that actually means "how dangerous"
- Staged, margin-of-safety alarms below the explosive range
- Barometric-pressure context (falling pressure releases buried gas)
- Site-wide methane mapping and migration-front tracking
- Solar, sealed, corrosion-tolerant nodes for waste environments
- LoRa + local logging for large sites without power or network
- Honest framing as an aid within a formal gas-safety regime
Difficulty, Time & Required Skills
| Attribute | Value |
|---|---|
| Difficulty level | Advanced |
| Estimated completion time | 12β18 hours |
| Indicative build cost | βΉ4,500 β βΉ6,500 per node |
| Primary discipline | Environment |
| Reference platform | ESP32 DevKit V1 (ESP-WROOM-32) |
Skills you should have (or will pick up)
- Reading a methane sensor and converting to %LEL
- Designing staged, margin-of-safety gas alarms
- Understanding gas migration and the role of barometric pressure
- LoRa + solar design for large, harsh outdoor sites
- Working within a formal gas-safety framework (knowing the system's limits)
Bill of Materials
Every part below is commonly available from Indian and international hobby-electronics suppliers. Prices are indicative 2026 retail figures in Indian rupees and will drift β treat them as a budgeting guide, not a quotation.
| Component | Key specification | Qty | Approx. cost |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) Wi-Fi transmit bursts peak near 500 mA β size the regulator accordingly. | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18Γ 12-bit ADC, 2Γ 8-bit DAC | 1 | βΉ450 |
| MQ-2 combustible gas / smoke sensor Needs 24β48 h burn-in and a stable 5 V; the heater alone draws ~150 mA. | 300β10000 ppm LPG, propane, methane, hydrogen, smoke; analogue + digital output | 1 | βΉ150 |
| BME280 pressure/humidity/temperature sensor Self-heating skews temperature by ~1 Β°C β read in forced mode, not continuous. | 300β1100 hPa Β±1 hPa, 0β100 %RH Β±3 %, β40 to +85 Β°C Β±1 Β°C, 3.4 Β΅A at 1 Hz | 1 | βΉ420 |
| MH-Z19B NDIR COβ sensor Disable auto-baseline calibration (ABC) for sealed rooms or it drifts to 400 ppm. | 0β5000 ppm Β±(50 ppm + 5 %), NDIR, 60 s warm-up, UART + PWM output | 1 | βΉ2,600 |
| SX1278 LoRa 433 MHz module (Ra-02) Never power the radio without an antenna β the PA will destroy itself. | β148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7βSF12 | 1 | βΉ480 |
| 20 W 12 V polycrystalline solar panel Rated watts assume 1000 W/mΒ² β plan for 60β70 % of nameplate in real installs. | Vmp 17.5 V, Imp 1.14 A, Voc 21.6 V, 350 Γ 290 mm, aluminium frame | 1 | βΉ1,200 |
| TP4056 Li-ion charger + DW01 protection Buy the version *with* protection ICs β the bare charger will over-discharge your cell. | 1 A programmable CC/CV charge to 4.2 V Β±1 %, over-discharge and short protection | 1 | βΉ45 |
| 18650 Li-ion cell 3400 mAh + holder Never charge below 0 Β°C; always use a protected cell or a BMS. | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 1 | βΉ450 |
| Methane (CHβ) sensor NDIR/catalytic is more selective than MQ-class; choose for the hazard level | MQ-4 / TGS2611 or catalytic/NDIR CHβ sensor with %LEL or ppm output | 1 | βΉ600 |
| Corrosion-resistant vented enclosure Landfill gas and leachate are corrosive | IP-rated, chemically resistant, vented for gas ingress, shades electronics | 1 | βΉ650 |
| Perimeter probe / borehole adapter For boundary migration monitoring, not just surface | Draws soil-gas from a shallow probe for sub-surface migration sensing | 1 | βΉ400 |
| LoRa gateway (site edge) | One gateway with backhaul, shared by the whole site network | 1 | βΉ2,500 |
Estimated total: βΉ9,945, excluding tools, shipping and consumables.
Tools and consumables
- Soldering iron (temperature controlled, 350 Β°C) with 0.8 mm 60/40 or lead-free solder
- Digital multimeter β continuity, DC volts and current ranges
- Wire strippers, flush cutters and a small set of precision screwdrivers
- Heat-shrink tubing and a heat gun (or a lighter, carefully)
- A laptop with a USB port and the toolchain listed above
Hardware Specifications
| Part | Specification | Supply | Interface | Reference |
|---|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18Γ 12-bit ADC, 2Γ 8-bit DAC | 3.3 V logic / 5 V USB | UART, SPI, IΒ²C, IΒ²S, CAN, PWM | Datasheet |
| MQ-2 combustible gas / smoke sensor | 300β10000 ppm LPG, propane, methane, hydrogen, smoke; analogue + digital output | 5 V (heater) | Analogue + comparator digital | Datasheet |
| BME280 pressure/humidity/temperature sensor | 300β1100 hPa Β±1 hPa, 0β100 %RH Β±3 %, β40 to +85 Β°C Β±1 Β°C, 3.4 Β΅A at 1 Hz | 1.7β3.6 V (module has 3.3 V LDO) | IΒ²C (0x76/0x77) or SPI | Datasheet |
| MH-Z19B NDIR COβ sensor | 0β5000 ppm Β±(50 ppm + 5 %), NDIR, 60 s warm-up, UART + PWM output | 4.5β5.5 V | UART 9600 8N1, PWM | Datasheet |
| SX1278 LoRa 433 MHz module (Ra-02) | β148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7βSF12 | 3.3 V | SPI | Datasheet |
| 20 W 12 V polycrystalline solar panel | Vmp 17.5 V, Imp 1.14 A, Voc 21.6 V, 350 Γ 290 mm, aluminium frame | 12 V nominal | MC4 / screw terminals | Datasheet |
| TP4056 Li-ion charger + DW01 protection | 1 A programmable CC/CV charge to 4.2 V Β±1 %, over-discharge and short protection | 4.5β5.5 V in | micro-USB / pads | Datasheet |
| 18650 Li-ion cell 3400 mAh + holder | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 3.0β4.2 V | Holder / spot-welded tabs | Datasheet |
Consolidated electrical and interface specifications for every active part in the build.
Power Budget & Supply Sizing
Add up the typical active current of every part, then size the supply with at least 50 % headroom so transmit bursts and motor inrush never brown out the controller.
| Load | Supply rail | Typical current (mA) | Notes |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | 3.3 V logic / 5 V USB | 160 | Wi-Fi transmit bursts peak near 500 mA β size the regulator accordingly. |
| MQ-2 combustible gas / smoke sensor | 5 V (heater) | 150 | Needs 24β48 h burn-in and a stable 5 V; the heater alone draws ~150 mA. |
| BME280 pressure/humidity/temperature sensor | 1.7β3.6 V (module has 3.3 V LDO) | 0.4 | Self-heating skews temperature by ~1 Β°C β read in forced mode, not continuous. |
| MH-Z19B NDIR COβ sensor | 4.5β5.5 V | 60 | Disable auto-baseline calibration (ABC) for sealed rooms or it drifts to 400 ppm. |
| SX1278 LoRa 433 MHz module (Ra-02) | 3.3 V | 120 | Never power the radio without an antenna β the PA will destroy itself. |
| 20 W 12 V polycrystalline solar panel | 12 V nominal | 1140 | Rated watts assume 1000 W/mΒ² β plan for 60β70 % of nameplate in real installs. |
| TP4056 Li-ion charger + DW01 protection | 4.5β5.5 V in | 1000 | Buy the version *with* protection ICs β the bare charger will over-discharge your cell. |
Summed typical draw is 2630.4 mA. With a 1.5Γ design margin the supply should deliver at least 4000 mA continuously at the stated rail voltage.
Software Requirements & Development Environment
Reference toolchain: Arduino IDE 2.3.x with the ESP32 board package 3.x (or PlatformIO on VS Code). Anything newer normally works; anything older may lack the board definitions used here.
- Install the Arduino IDE 2.3.x (or PlatformIO if you prefer a real editor and dependency locking).
- Add
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonunder File β Preferences β Additional Board Manager URLs, then install esp32 from the Boards Manager. - Set the correct port under Tools β Port. On Linux add yourself to the
dialoutgroup:sudo usermod -aG dialout $USERand log out and back in. - Open the Serial Monitor at 115200 baud β every sketch here logs its state there.
- Keep File β Preferences β Show verbose output during: compilation switched on while you are debugging build errors.
Required libraries
| Library | Why it is needed | Install |
|---|---|---|
| WiFi (ESP32 core) bundled | Station/AP connection management for the ESP32. | Bundled with the ESP32 Arduino core |
| Adafruit BME280 2.2.x | Compensation maths for the Bosch pressure/humidity/temperature sensor. | Library Manager β "Adafruit BME280 Library" |
| LoRa (sandeepmistry) 0.8.0 | SX127x radio configuration, packet TX/RX and callbacks. | Library Manager β "LoRa" by Sandeep Mistry |
| ArduinoJson 7.x | Zero-allocation JSON serialisation and parsing. | Library Manager β "ArduinoJson" by Benoit Blanchon |
| Preferences (NVS) bundled | Wear-levelled key/value storage in ESP32 flash for settings. | Bundled with the ESP32 core |
Block Diagram
The block diagram shows the functional decomposition of the system β what senses, what decides, what acts, and where the data ends up.
Circuit Diagram & Wiring
Every signal line in the build is shown below, followed by a pin-by-pin connection table you can work through with a multimeter in hand.
| Peripheral | Peripheral pin | Controller pin | Signal |
|---|---|---|---|
| CHβ sensor | AOUT/UART | GPIO 34 / 16-17 | Methane concentration |
| MQ-2 (backup) | AOUT | GPIO 35 (ADC) | Combustible-gas cross-check |
| BME280 | SDA/SCL | GPIO 21/22 | Temp/RH/pressure (IΒ²C) |
| LoRa SX1276 | SCK/MISO/MOSI | GPIO 18/19/23 | SPI radio bus |
| LoRa SX1276 | NSS/RST/DIO0 | GPIO 5/14/2 | Chip-select, reset, IRQ |
| Alarm beacon | IN | GPIO 13 | Local visual alarm |
| Solar + TP4056 | OUT | 3V3 reg | Charged supply |
Wire one row at a time and tick it off β most "it does not work" reports trace back to a single swapped pair.
Wiring explanation
- Vent the enclosure so gas can reach the sensor while the electronics and battery are shaded and protected from corrosive leachate and rain.
- A catalytic/NDIR methane sensor is preferred where the hazard is real; give it its stable supply and warm-up and treat MQ-class parts as a cross-check.
- Log barometric pressure with the BME280 β emissions rise as the barometer falls, and pressure context makes a reading interpretable.
- For migration monitoring, draw soil-gas from a shallow perimeter probe rather than sampling only open air above the tip.
- Where an explosive atmosphere is credible, follow site rules on intrinsically-safe equipment; this build is a monitoring aid, not a certified detector.
System Architecture
Read the stack from the bottom up: physical hardware, the firmware that drives it, the transport that moves data off the device, and the software a human actually looks at.
Working Principle
Everything about this monitor is organised around one number that means danger: the lower explosive limit. Methane is only flammable within a band β roughly 5% to 15% by volume in air β and the bottom of that band, 5%, is the LEL. Reporting a reading as "% of LEL" makes the whole scale intuitive and safety-relevant: 0% LEL is clean air, 100% LEL is the threshold of an explosive atmosphere, and every alarm can be set as a comfortable fraction of that. A "20% LEL" warning means the gas is at one-fifth of the way to flammable β plenty of margin, but a clear signal to investigate β while "50% LEL" is a serious situation demanding action. Expressing methane this way, rather than as an abstract ppm, is what lets a non-specialist act correctly.
The staging is deliberately conservative because the consequence is explosion. Alarm thresholds sit well below the LEL and escalate: a low warning to prompt a look, a higher alarm to trigger site procedures, all reached long before the atmosphere could actually ignite. This margin absorbs the real uncertainty of low-cost sensing β these sensors drift, cross-respond to other gases, and are indicative rather than precise β so that even a sensor reading somewhat optimistically still alarms with room to spare. The monitor also cross-checks methane against a general combustible-gas channel, so a suspicious rise is corroborated rather than trusted from a single element.
Barometric pressure is the piece of context that makes methane readings make sense over time. Landfill gas sits under slight pressure in the waste mass and soil; when the atmospheric pressure falls β as a weather front approaches β that buried gas expands and is drawn out to the surface and through migration pathways, so surface methane and boundary migration both tend to peak as the barometer drops. A node that logs pressure can explain a rise ("emissions up because the barometer is falling fast") and even anticipate one, which is why pressure, temperature and humidity are logged as first-class data, not decoration.
At site scale the goal shifts from a point reading to a picture. Landfills are large; gas vents unevenly from different cells and migrates laterally toward boundaries. A network of nodes across the surface and around the perimeter builds a live methane map: which cells are actively venting, whether a migration front is advancing toward the fence line and a neighbouring building where gas could accumulate in an enclosed space, and how the whole site's emissions breathe with the weather. Perimeter nodes drawing soil-gas from shallow probes are especially valuable, because lateral migration into an off-site basement or trench is the classic landfill-gas tragedy, and it happens away from the obvious tip face. The system is candid that it operates within a formal gas-safety regime β it complements certified fixed detectors and intrinsically-safe practice rather than replacing them β but as a dense, continuous, honestly-scaled early-warning layer it closes the gap between periodic manual surveys, catching the build-ups and migration events that develop in between.
The maths behind it
Percent of lower explosive limit
Methane is flammable from ~5% to ~15% vol in air.
LEL = 5% vol = 50000 ppm.
%LEL = (CHβ concentration in ppm) / 50000 Γ 100
So 10000 ppm CHβ = 20% LEL.
Alarms are set as fractions of LEL (with margin):
warning ~10β20% LEL, alarm ~40β50% LEL β all below 100%.
Barometric influence on emissions
Falling atmospheric pressure lets buried gas expand/escape:
emission β when dP/dt < 0 (barometer dropping)
Track the pressure trend to contextualise a methane rise:
rapid pressure drop + methane rise = pressure-driven venting,
expected and transient β but still real gas at the surface.
Sensor drift handling (trend + cross-check)
Low-cost CHβ sensors drift, so combine absolute %LEL alarms
with a rate-of-change check and a cross-sensor gate:
alarm if %LEL > stage_threshold
AND combustible cross-check also elevated
flag "suspect" if the two sensors disagree markedly
(one may be drifting/faulted β maintenance).
Program Flowchart
The firmware is a single cooperative loop. Nothing blocks for long, so networking, sensing and the user interface all stay responsive.
Assembly Instructions
Build on a breadboard first and only commit to solder once the whole system has run for an hour without a fault.
Build the corrosion-tolerant node
House the electronics in a chemically-resistant, vented, IP-rated enclosure so landfill gas can reach the sensor while the board and battery are shielded from corrosive leachate, rain and sun.
Fit the methane sensor (catalytic/NDIR where the hazard warrants) and allow its warm-up; add the BME280 for pressure/temperature/humidity.
Set up surface and perimeter sensing
Place surface nodes over the tip and perimeter nodes at the boundary, the latter drawing soil-gas from shallow probes to catch lateral migration before it leaves the site.
Power, radio and local alarm
Angle the solar panel, mount the LoRa antenna high, and wire a local visual beacon that lights on a high-%LEL alarm regardless of the network. Place gateways at the site edge.
Step-by-Step Implementation Guide
Work through these in order. Each step ends in something you can observe, so a failure is always localised to the step you just finished.
Convert to %LEL and stage the alarm
Convert the methane reading to ppm, then to %LEL against the 50000 ppm LEL, map to a staged alarm well below 100% LEL, and require corroboration from the combustible cross-check.
cppmethane-lel.ino#define LEL_PPM 50000.0f // 5% vol CH4 = 100% LEL float percentLEL(float ch4_ppm) { return ch4_ppm / LEL_PPM * 100.0f; } enum Stage { CLEAR=0, WATCH=1, WARNING=2, ALARM=3 }; // Staged alarm, all thresholds well BELOW the explosive limit. Stage stageOf(float lel, bool crossElevated) { if (lel >= 50.0f && crossElevated) return ALARM; // ~half LEL: act now if (lel >= 20.0f) return WARNING; // one-fifth LEL if (lel >= 10.0f) return WATCH; // early notice return CLEAR; } // Cross-check: methane and combustible channels should agree. bool suspectDrift(float lel, float combustible_pctLEL) { return fabsf(lel - combustible_pctLEL) > 25.0f; // large disagreement }return ch4_ppm / LEL_PPM * 100.0fConverts the methane concentration to a percentage of the explosive limit β the single number that expresses how close the atmosphere is to flammable.if (lel >= 50.0f && crossElevated) return ALARMThe highest alarm still sits at only half the explosive limit and requires the combustible cross-check to agree, giving a wide safety margin and guarding against a single drifting sensor.if (lel >= 10.0f) return WATCHA gentle early-notice stage fires at a tenth of the LEL, so a developing build-up is flagged long before it is anywhere near dangerous.bool suspectDrift(When the methane and combustible channels disagree sharply, one is likely drifting or faulted, so the node flags itself for maintenance rather than trusting a lone number.Add pressure context and report
Log the barometric trend, attach it to each reading so a rise can be explained, drive the local beacon on alarm, transmit %LEL and stage over LoRa, and log locally.
Complete Source Code
The listing below is complete and compiles as written β there are no elided sections. Read the annotations under each block before you upload it.
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Landfill Methane Monitor β ESP32, CH4 %LEL, pressure context, LoRa
Reports methane as a percentage of the lower explosive limit, stages
alarms with a wide safety margin, logs barometric context that drives
migration, and reports over LoRa on solar. An aid within a formal
gas-safety regime, not a certified detector.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <LoRa.h>
#include <SPI.h>
#include <Preferences.h>
#include <math.h>
#define PIN_CH4 34
#define PIN_COMB 35
#define PIN_BEACON 13
#define LORA_CS 5
#define LORA_RST 14
#define LORA_DIO0 2
#define LEL_PPM 50000.0f
Adafruit_BME280 bme;
Preferences prefs;
float CH4_CAL, COMB_CAL;
RTC_DATA_ATTR float prevPressure = NAN;
enum Stage { CLEAR=0, WATCH=1, WARNING=2, ALARM=3 };
const char *STAGE[] = {"clear","watch","warning","alarm"};
float readCH4ppm() { // sensor-specific mapping
long s=0; for(int i=0;i<64;i++) s+=analogRead(PIN_CH4);
return (s/64.0f)/4095.0f * CH4_CAL; // CH4_CAL maps ADCβppm
}
float readCombustiblePctLEL() {
long s=0; for(int i=0;i<64;i++) s+=analogRead(PIN_COMB);
return (s/64.0f)/4095.0f * COMB_CAL; // COMB_CAL maps ADCβ%LEL
}
Stage stageOf(float lel, bool cross) {
if (lel>=50.0f && cross) return ALARM;
if (lel>=20.0f) return WARNING;
if (lel>=10.0f) return WATCH;
return CLEAR;
}
void transmit(float lel, float comb, float t, float rh, float p,
float dP, Stage st, bool suspect) {
LoRa.beginPacket();
LoRa.printf("{\"node\":1,\"lel\":%.1f,\"comb\":%.1f,\"t\":%.1f,"
"\"rh\":%.0f,\"p\":%.0f,\"dP\":%.1f,\"stage\":\"%s\","
"\"suspect\":%d}",
lel, comb, t, rh, p, dP, STAGE[st], suspect?1:0);
LoRa.endPacket();
}
void logLocal() { /* append timestamped record */ }
void setup() {
Serial.begin(115200);
pinMode(PIN_BEACON, OUTPUT);
analogSetPinAttenuation(PIN_CH4, ADC_11db);
analogSetPinAttenuation(PIN_COMB, ADC_11db);
Wire.begin(21,22); bme.begin(0x76);
prefs.begin("ch4",true);
CH4_CAL=prefs.getFloat("ch4",100000.0f);
COMB_CAL=prefs.getFloat("comb",100.0f);
prefs.end();
float ch4 = readCH4ppm();
float lel = ch4 / LEL_PPM * 100.0f;
float comb = readCombustiblePctLEL();
float t = bme.readTemperature();
float rh = bme.readHumidity();
float p = bme.readPressure()/100.0f; // hPa
float dP = isnan(prevPressure)? 0 : p - prevPressure;
prevPressure = p;
bool cross = comb > 15.0f; // combustible corroborates
Stage st = stageOf(lel, cross);
bool suspect = fabsf(lel - comb) > 25.0f;
digitalWrite(PIN_BEACON, st >= ALARM ? HIGH : LOW);
logLocal();
SPI.begin();
LoRa.setPins(LORA_CS, LORA_RST, LORA_DIO0);
LoRa.begin(433E6);
LoRa.setSpreadingFactor(10);
transmit(lel, comb, t, rh, p, dP, st, suspect);
// sample faster if elevated or barometer dropping fast
uint32_t sleep_s = (lel > 10.0f || dP < -1.0f) ? 120 : 900;
esp_sleep_enable_timer_wakeup((uint64_t)sleep_s * 1000000ULL);
esp_deep_sleep_start();
}
void loop() {} // deep sleep restarts setup()
Configuration & Calibration
Configuration steps
- Calibrate CH4_CAL (ADCβppm) and COMB_CAL against known gas concentrations; set the LEL for the target gas (methane 50000 ppm).
- Set the staged %LEL thresholds conservatively below 100% LEL per your site's safety procedures.
- Configure surface vs perimeter (soil-gas) node behaviour and the pressure-trend sensitivity.
- Choose the region-legal LoRa frequency, local logging, and the local-beacon behaviour.
Calibration procedure
An uncalibrated sensor produces confident, precise, wrong numbers. Do this once per physical unit and record the constants.
Methane span
Calibrate the methane sensor against a known methane concentration (calibration gas) so %LEL is accurate; repeat regularly as these sensors drift.
Cross-channel agreement
Confirm the methane and combustible channels agree on clean and elevated air so the cross-check and suspect-drift logic behave.
Pressure/context
Verify the BME280 pressure tracks a reference barometer so the dP trend is trustworthy.
Network Architecture & Connectivity
Communication protocol
Nodes report %LEL, stage, cross-check and barometric context on a cadence that shortens when elevated; alarm-stage changes publish immediately. Local logging is authoritative and forwards backlog on reconnect.
| Topic / endpoint | Direction | Payload |
|---|---|---|
landfill/node/1/gas | node β broker | %LEL, combustible, T/RH/pressure, dP, stage |
landfill/node/1/alarm | node β broker | staged %LEL alarm (escalated) |
landfill/node/1/status | node β broker | battery, suspect/cal flags, RSSI |
Message contract between the device and the broker.
Cloud platform configuration
A broker feeds a site gas map that shows which cells vent, tracks a migration front toward the boundary, and overlays the barometric trend so emission peaks are explained; alarms escalate to site safety staff.
Dashboard setup
A site map coloured by %LEL stage with perimeter migration indicators, plus emission-vs-pressure trends and per-node sensor-health flags.
Mobile app integration
Escalating alerts on warning/alarm stages, especially perimeter migration, routed to site gas-safety personnel.
Security considerations
- Sign node reports so false gas alarms cannot be injected into a safety system.
- Keep the local beacon and logging independent of the network so a lost link cannot hide an on-site hazard.
- Alert on a node going silent β a failed node in a gas environment is itself significant.
Testing Procedure & Expected Output
Test from the bottom up. Confirm power, then each sensor in isolation, then the integrated loop β the first failing step tells you exactly where to look.
| Test | What you should see |
|---|---|
| Apply a known methane concentration | %LEL reads correctly; the right stage triggers with margin below LEL |
| Elevate methane but not the combustible channel | Top alarm withheld (no corroboration); suspect-drift may flag |
| Drop the barometric pressure (or simulate) | dP trend negative; faster sampling engaged; context attached |
| Reach the alarm stage | Local beacon lights independent of the network; alert transmitted |
| Drop the LoRa link | Reading logged locally; backlog forwards on reconnect |
| Run a solar cycle in a wet/corrosive mock environment | Enclosure protects electronics; node keeps reporting |
Bench-test checklist. If a row fails, stop and fix it before moving on.
Expected output
The site dashboard shows a methane map (nodes coloured by %LEL stage), the barometric trend, and any migration front approaching the boundary; alarms list the node and %LEL.
{
"node": 1,
"lel": 22.5,
"comb": 24.0,
"t": 28.7,
"rh": 74,
"p": 1006,
"dP": -2.4,
"stage": "warning",
"suspect": 0
}
Here methane is at 22.5% LEL (warning stage), corroborated by the combustible channel, while the barometer is falling (β2.4 hPa) β a pressure-driven venting event flagged with plenty of margin below the explosive limit.
Troubleshooting: Common Errors & Fixes
Performance Optimisation
- Deep-sleep between reads when clear; shorten intervals when %LEL is elevated or the barometer is falling.
- Average many ADC samples per gas channel; single samples are far too noisy for a safety decision.
- Persist the pressure baseline in RTC memory so the barometric trend survives sleep.
- Keep packets small; the value is the timely %LEL and stage, not data volume.
- Replace every
delay()with amillis()comparison β blocking delays are the single most common cause of dropped readings. - Sample sensors on a fixed cadence and publish on a slower one; you almost never need to transmit at the sampling rate.
- Move networking into its own FreeRTOS task so a slow DNS lookup cannot stall the control loop.
- Use
uint8_t/uint16_twhere the range allows; on an 8-bit AVR a 32-bit add costs four times as much. - Batch several samples into one MQTT publish. Radio time, not CPU time, dominates the energy budget.
- Set the MQTT keep-alive to a value that matches your reporting interval so the broker does not churn reconnections.
- For battery builds use deep sleep between samples: an ESP32 drops from ~160 mA awake to about 10 Β΅A asleep, which is the difference between days and months of runtime.
Safety Precautions
- This is a monitoring and early-warning aid within a formal gas-safety regime β not a replacement for certified fixed detectors or intrinsically-safe equipment where those are required.
- Report and act in %LEL with wide margins; never let alarms approach the actual explosive limit.
- Where an explosive atmosphere is credible, only appropriately-rated, certified equipment may be used β follow site rules and law.
- Keep the lithium battery and any spark-capable component out of potentially flammable atmospheres unless suitably protected.
- Lithium cells vent and burn when abused. Only use protected cells or a proper BMS, never charge below 0 Β°C, and never leave a charging pack unattended on a wooden desk.
- MQ-series sensors run a hot element. They get genuinely hot, need ventilation, and must never be enclosed in a sealed plastic box.
- Never power an RF module without its antenna fitted β the reflected power destroys the output stage. Check your local licence-free band and duty-cycle limits before transmitting.
- Wear eye protection when soldering or cutting, and solder in a ventilated space β rosin flux fumes are a respiratory irritant.
- Power the circuit through a bench supply with a current limit while you are testing. A 300 mA limit turns a wiring mistake into a beep instead of a dead board.
- Disconnect power before changing any wiring. Hot-plugging a sensor onto a live bus is the fastest way to lose a controller.
Maintenance
- Recalibrate methane sensors against calibration gas on a regular schedule; drift is significant.
- Inspect enclosures for corrosion and reseal; replace degraded parts before they let leachate in.
- Verify perimeter probes remain clear and representative of soil-gas.
- Test the local beacon and confirm local logging/backlog forwarding before relying on the network.
- Re-check every screw terminal and header after the first week β thermal cycling loosens connections that felt tight on day one.
- Log pack voltage. When resting voltage after a full charge drops below about 4.0 V, the cell is near end of life β replace it.
- Wash the panel every few weeks in dusty conditions; a visible dust film costs 15β25 % of the harvest.
- Keep the broker and dashboard containers patched, and rotate device credentials at least once a year.
- Recalibrate at the interval given in the calibration section, and keep the constants in a text file next to the firmware β not only in flash.
- Keep a short logbook of firmware versions and what changed. Six months later you will not remember why that constant is 1.083.
Future Improvements & Upgrades
A working v1 is a platform, not a finish line. These are the upgrades that add the most capability for the least rework.
- Add flux (emission-rate) estimation, not just concentration, for greenhouse-gas quantification.
- Fuse many nodes with wind and pressure into a migration model that predicts boundary risk.
- Add gas-extraction well control to actively manage a venting cell.
- Integrate with the site's certified detection for a combined operational + safety view.
- Design a proper PCB. Once the breadboard version has run for a month, moving to a two-layer board removes the intermittent-contact failures that dominate prototype faults.
- Add over-the-air firmware updates so you never have to physically reach a deployed node again.
- Add persistent local storage (microSD or the on-chip flash) so a network outage does not create a hole in your data.
- Move configuration out of the source: a captive-portal setup page or a JSON config file makes the build reusable without a recompile.
- Add a battery and solar option so the unit survives a power cut and can be sited away from a socket.
- Write a small test harness that feeds synthetic sensor values through the decision logic, so you can validate thresholds without physically triggering the event.
Frequently Asked Questions
References & Learning Resources
These are the primary sources worth reading in full. Manufacturer datasheets always outrank forum posts when the two disagree.