{"id":52243,"date":"2026-11-01T10:50:45","date_gmt":"2026-11-01T10:50:45","guid":{"rendered":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/"},"modified":"2026-11-01T10:50:45","modified_gmt":"2026-11-01T10:50:45","slug":"gas-leak-alarm","status":"publish","type":"siratek_tutorial","link":"https:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/","title":{"rendered":"Project, a Gas Leak Alarm"},"content":{"rendered":"<body><p><\/p>\n<h2>What you will build<\/h2>\n<p>A box that watches the air near an LPG cylinder, sounds an alarm when the level rises, latches until somebody acknowledges it, switches on a fan, and tells you plainly when it cannot be trusted.<\/p>\n<h2>Read this first, before you build it or give it to anybody<\/h2>\n<p><strong>This is not a gas detector. It is a project about building one.<\/strong><\/p>\n<p><em>Smoke and Gas Sensing with MQ-2<\/em> sets out why, and the reasons do not go away because the sensor is now in a box with a buzzer:<\/p>\n<ul>\n<li><strong>It is not calibrated and cannot be.<\/strong> The reading says the level went up. It cannot say by how much, and any sketch printing \u201cppm\u201d from this module is printing a number with no basis.<\/li>\n<li><strong>It cannot tell you which gas it is.<\/strong> LPG, alcohol vapour, cooking smoke and a cleaning cloth all move the same reading.<\/li>\n<li><strong>It depends on a working Arduino.<\/strong> A crashed sketch, a loose wire or a flat supply reports nothing at all, silently.<\/li>\n<li><strong>A certified detector is tested, approved and designed to fail audibly.<\/strong> This is a learning component on a breadboard.<\/li>\n<\/ul>\n<p>LPG cylinders are in most kitchens in Kumasi and a leak is genuinely dangerous. <strong>Build this for the understanding, and buy a certified detector for the kitchen.<\/strong> If you give this project to someone, say that sentence to them as well, because a box with a flashing light and a siren looks much more authoritative than it is.<\/p>\n<p>With that said: nearly everything that makes a real alarm trustworthy can be learned here, and the design below takes those parts seriously.<\/p>\n<h2>Before you begin<\/h2>\n<h3>Parts<\/h3>\n<table>\n<thead>\n<tr>\n<th>Part<\/th>\n<th>Siratek product<\/th>\n<th>Its own tutorial<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Arduino Uno<\/td>\n<td>2219<\/td>\n<td><em>Getting Started with Arduino Uno<\/em><\/td>\n<\/tr>\n<tr>\n<td>MQ-2 gas sensor<\/td>\n<td>2949<\/td>\n<td><em>Smoke and Gas Sensing with MQ-2<\/em><\/td>\n<\/tr>\n<tr>\n<td>Passive buzzer<\/td>\n<td>8051<\/td>\n<td><em>Play Tones with a Passive Buzzer<\/em><\/td>\n<\/tr>\n<tr>\n<td>Two-channel relay module<\/td>\n<td>3398<\/td>\n<td><em>A Two-Channel Relay Module<\/em><\/td>\n<\/tr>\n<tr>\n<td>Green, amber and red LEDs with 220 ohm resistors<\/td>\n<td>2234<\/td>\n<td><em>Your First Circuit, an LED and a Resistor<\/em><\/td>\n<\/tr>\n<tr>\n<td>Push button<\/td>\n<td>2353<\/td>\n<td><em>Read a Push Button<\/em><\/td>\n<\/tr>\n<tr>\n<td>Breadboard and jumper wires<\/td>\n<td><\/td>\n<td><em>Using a Breadboard<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Burn the sensor in first, and do it now<\/h3>\n<p>A new MQ-2 drifts considerably over its <strong>first 24 to 48 hours<\/strong> of continuous power. Any threshold you choose before that will be wrong afterwards.<\/p>\n<p>So before you write a line of code: wire <code>VCC<\/code> and <code>GND<\/code>, leave the module powered on a shelf for a day or two, and come back. This is the step everyone skips, and it is why a gas alarm that worked on Monday reports nonsense on Tuesday.<\/p>\n<p>Separately, <strong>every power-up needs two to three minutes of preheat<\/strong>. The sketch below enforces that rather than trusting you to wait.<\/p>\n<h3>Where it goes, which decides whether it works at all<\/h3>\n<p><strong>LPG, propane and butane are heavier than air.<\/strong> They pool at floor level. Mount the sensor around <strong>thirty centimetres from the floor<\/strong>, near the cylinder, and a sensor on a shelf at head height may never see a leak at all.<\/p>\n<p>Methane and natural gas are the opposite case and collect at the ceiling. If you are watching for those, the sensor goes high up.<\/p>\n<p>Either way, keep it <strong>away from the cooker itself<\/strong>. Cooking fumes will trigger it constantly, and an alarm that cries wolf gets unplugged, which is worse than no alarm.<\/p>\n<h3>What the relay is and is not for<\/h3>\n<p>Channel 1 drives a <strong>warning lamp or sounder<\/strong> \u2014 something louder and more visible than a buzzer on a breadboard.<\/p>\n<p>Channel 2 drives a <strong>fan<\/strong>, to ventilate.<\/p>\n<p><strong>Neither channel shuts off a gas supply.<\/strong> A solenoid valve on a gas line is plumbing and safety work, needs the right valve and the right installation, and is not something to drive from a breadboard project with an uncalibrated sensor. If that is what you want, it is a job for somebody qualified.<\/p>\n<p>Read <em>A Two-Channel Relay Module<\/em> before wiring the load side. Two things from it matter here: the <strong>yellow jumper<\/strong> decides whether the optocouplers isolate anything, and the relays in the Siratek photographs are <strong>marked with a 12 V coil voltage while the product is listed as 5 V<\/strong>, so read the printing on your own board before connecting it.<\/p>\n<h3>The failure that matters most<\/h3>\n<p>Think about what this project does when the sensor wire falls off.<\/p>\n<p>An analog input with nothing connected floats. It will read <em>something<\/em>, that something will look like clean air, and the project will sit there with a green light reporting that all is well. <strong>A safety device that fails silently into \u201ceverything is fine\u201d is worse than no device<\/strong>, because it is trusted.<\/p>\n<p>So the sketch checks that the reading is <strong>plausible<\/strong> \u2014 not stuck at zero, not pinned at 1023, not frozen at exactly the same value for minutes on end \u2014 and treats implausibility as a fault with its own distinct signal. That is most of the difference between a demonstration and something built with care.<\/p>\n<h2>How it works<\/h2>\n<p>Five states, and the transitions between them are the project:<\/p>\n<table>\n<thead>\n<tr>\n<th>State<\/th>\n<th>Lights<\/th>\n<th>Sound<\/th>\n<th>What ends it<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>PREHEAT<\/code><\/td>\n<td>Amber, slow blink<\/td>\n<td>Silent<\/td>\n<td>Three minutes<\/td>\n<\/tr>\n<tr>\n<td><code>NORMAL<\/code><\/td>\n<td>Green<\/td>\n<td>Silent<\/td>\n<td>A rise past the warn threshold, or a fault<\/td>\n<\/tr>\n<tr>\n<td><code>WARN<\/code><\/td>\n<td>Amber<\/td>\n<td>Short chirp every few seconds<\/td>\n<td>Rise clears, or it gets worse<\/td>\n<\/tr>\n<tr>\n<td><code>ALARM<\/code><\/td>\n<td>Red<\/td>\n<td>Continuous two-tone<\/td>\n<td><strong>Only the reset button<\/strong><\/td>\n<\/tr>\n<tr>\n<td><code>FAULT<\/code><\/td>\n<td>Red, fast blink<\/td>\n<td>Distinct repeated beep<\/td>\n<td>The reading becomes plausible again<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Three design decisions sit inside that table.<\/p>\n<p><strong>The alarm latches.<\/strong> Once in <code>ALARM<\/code> it stays there until a person presses the button, even if the reading returns to normal. A self-clearing alarm means a leak that happened while you were out left no trace, and the one thing you most want to know is that it happened.<\/p>\n<p><strong>The warn level does not latch.<\/strong> Something briefly raising the reading \u2014 a match, a cleaning cloth \u2014 should chirp and pass. Only a real rise should take it further.<\/p>\n<p><strong>The baseline is frozen above <code>NORMAL<\/code>.<\/strong> The MQ-2 page explains why: a slowly drifting baseline absorbs a slow leak and the alarm quietly clears itself. While anything is happening, the baseline stops moving.<\/p>\n<h3>Why a baseline rather than a fixed threshold<\/h3>\n<p>The raw reading depends on temperature, humidity and the sensor\u2019s age as well as on gas. A fixed threshold chosen on a cool morning triggers by itself on a hot afternoon.<\/p>\n<p>Comparing against a slowly updated average of the recent past removes all of that. What the project reacts to is a <strong>rise<\/strong>, which is what a leak looks like, and the long-term drift it ignores is what the weather looks like.<\/p>\n<h2>Build it in stages<\/h2>\n<h3>Stage 1: watch the raw numbers for an hour<\/h3>\n<p>With the sensor burnt in, run the MQ-2 tutorial\u2019s example and let it print. Note the baseline in your room, how much it moves over an hour, and how far it jumps when you hold an alcohol-dipped cotton bud near the mesh.<\/p>\n<p>Those three numbers give you <code>WARN_RISE<\/code> and <code>ALARM_RISE<\/code>. A rise comfortably larger than the hour\u2019s natural wander, and comfortably smaller than the cotton bud, is the window you want.<\/p>\n<h3>Stage 2: the indicators<\/h3>\n<p>Three LEDs and the buzzer, no sensor logic. Drive each state by hand from the serial monitor until you can tell all five apart from across the room without reading anything.<\/p>\n<p>This sounds like a detour. It is not: an alarm whose states look alike is an alarm nobody can interpret under pressure.<\/p>\n<h3>Stage 3: the relay, control side only<\/h3>\n<p>Wire <code>DC+<\/code>, <code>DC-<\/code>, <code>In1<\/code> and <code>In2<\/code>, with nothing on the contacts, and confirm you hear each channel click. Then wire the load side, having read the coil voltage printed on your own relays.<\/p>\n<h3>Stage 4: put it together<\/h3>\n<p>The complete sketch below, with <code>PREHEAT_MS<\/code> shortened to ten seconds while you test, then set back.<\/p>\n<h2>Pin reference<\/h2>\n<table>\n<thead>\n<tr>\n<th>Device<\/th>\n<th>Pin<\/th>\n<th>Connect to<\/th>\n<th>Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>MQ-2<\/td>\n<td><code>AO<\/code><\/td>\n<td>Uno <code>A0<\/code><\/td>\n<td>The reading<\/td>\n<\/tr>\n<tr>\n<td>MQ-2<\/td>\n<td><code>DO<\/code><\/td>\n<td>Not connected<\/td>\n<td>The trimmer threshold is not used<\/td>\n<\/tr>\n<tr>\n<td>MQ-2<\/td>\n<td><code>VCC<\/code><\/td>\n<td>Uno <code>5V<\/code><\/td>\n<td>Heater, about 150 mA continuously<\/td>\n<\/tr>\n<tr>\n<td>MQ-2<\/td>\n<td><code>GND<\/code><\/td>\n<td>Uno <code>GND<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>Buzzer<\/td>\n<td><code>+<\/code><\/td>\n<td>Uno <code>D8<\/code><\/td>\n<td><code>tone()<\/code> uses Timer 2<\/td>\n<\/tr>\n<tr>\n<td>Buzzer<\/td>\n<td><code>-<\/code><\/td>\n<td>Uno <code>GND<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>Green LED<\/td>\n<td>anode<\/td>\n<td>Uno <code>D5<\/code><\/td>\n<td>Through 220 ohms<\/td>\n<\/tr>\n<tr>\n<td>Amber LED<\/td>\n<td>anode<\/td>\n<td>Uno <code>D6<\/code><\/td>\n<td>Through 220 ohms<\/td>\n<\/tr>\n<tr>\n<td>Red LED<\/td>\n<td>anode<\/td>\n<td>Uno <code>D9<\/code><\/td>\n<td>Through 220 ohms<\/td>\n<\/tr>\n<tr>\n<td>Button<\/td>\n<td>one leg<\/td>\n<td>Uno <code>D2<\/code><\/td>\n<td><code>INPUT_PULLUP<\/code><\/td>\n<\/tr>\n<tr>\n<td>Button<\/td>\n<td>other leg<\/td>\n<td>Uno <code>GND<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>Relay<\/td>\n<td><code>DC+<\/code>, <code>DC-<\/code><\/td>\n<td>Uno <code>5V<\/code>, <code>GND<\/code><\/td>\n<td>Or its own coil supply; see its page<\/td>\n<\/tr>\n<tr>\n<td>Relay<\/td>\n<td><code>In1<\/code><\/td>\n<td>Uno <code>D7<\/code><\/td>\n<td>Warning lamp or sounder<\/td>\n<\/tr>\n<tr>\n<td>Relay<\/td>\n<td><code>In2<\/code><\/td>\n<td>Uno <code>D4<\/code><\/td>\n<td>Fan<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>No LED is on pin 3 or 11.<\/strong> <code>tone()<\/code> takes over Timer 2, which is what produces PWM on those two pins, so anything dimmed there stops responding while the buzzer sounds. The passive buzzer page explains it; here it is the reason for the pin choice.<\/p>\n<figure class=\"siratek-tutorial-figure\"><img decoding=\"async\" src=\"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg\" alt=\"A gas alarm with an MQ-2 on A0, three indicator LEDs, a latching alarm with a reset button, and a two-channel relay driving a warning lamp and a fan, with the sensor mounted low because LPG sinks\" loading=\"lazy\"><figcaption>It reacts to a rise above a drifting baseline, latches until acknowledged, and says so when the reading stops being plausible.<\/figcaption><\/figure>\n<h2>The complete sketch<\/h2>\n<pre><code>\/\/ Siratek: a gas leak alarm, built as a learning project.\n\/\/ This is not a certified detector. See the note at the top of the page.\n\nconst int gasPin    = A0;\nconst int buzzerPin = 8;\nconst int greenPin  = 5;\nconst int amberPin  = 6;\nconst int redPin    = 9;\nconst int resetPin  = 2;\nconst int lampPin   = 7;      \/\/ relay channel 1\nconst int fanPin    = 4;      \/\/ relay channel 2\n\n\/\/ Relay polarity: see A Two-Channel Relay Module.\nconst int RELAY_ON  = LOW;\nconst int RELAY_OFF = HIGH;\n\n\/\/ ---- Measured in YOUR room, after burn-in. See stage 1. ----\nconst int WARN_RISE  = 60;\nconst int ALARM_RISE = 140;\n\/\/ Implausible readings. An unplugged sensor sits near one end.\nconst int PLAUSIBLE_LOW  = 20;\nconst int PLAUSIBLE_HIGH = 1000;\n\/\/ ------------------------------------------------------------\n\nconst unsigned long PREHEAT_MS = 180000UL;   \/\/ three minutes\nconst unsigned long SAMPLE_EVERY = 500;\nconst unsigned long STUCK_AFTER = 300000UL;  \/\/ five identical minutes is a fault\n\nenum State { PREHEAT, NORMAL, WARN, ALARM, FAULT };\nState state = PREHEAT;\n\nfloat baseline = 0;\nconst float smoothing = 0.995;\n\nint raw = 0;\nint rise = 0;\n\nint lastRaw = -1;\nunsigned long lastChange = 0;\nunsigned long lastSample = 0;\nunsigned long blinkAt = 0;\nbool blinkOn = false;\n\nvoid setLights(bool green, bool amber, bool red) {\n  digitalWrite(greenPin, green);\n  digitalWrite(amberPin, amber);\n  digitalWrite(redPin, red);\n}\n\nvoid setup() {\n  \/\/ Relays rest off, before their pins become outputs.\n  digitalWrite(lampPin, RELAY_OFF);\n  digitalWrite(fanPin, RELAY_OFF);\n  pinMode(lampPin, OUTPUT);\n  pinMode(fanPin, OUTPUT);\n\n  pinMode(greenPin, OUTPUT);\n  pinMode(amberPin, OUTPUT);\n  pinMode(redPin, OUTPUT);\n  pinMode(resetPin, INPUT_PULLUP);\n\n  Serial.begin(9600);\n  Serial.println(F(\"Siratek: gas alarm. Preheating; no alarm until this finishes.\"));\n\n  lastChange = millis();\n}\n\n\/\/ Is the sensor telling us anything at all?\nbool implausible() {\n  if (raw &lt; PLAUSIBLE_LOW || raw &gt; PLAUSIBLE_HIGH) {\n    return true;\n  }\n  if (millis() - lastChange &gt; STUCK_AFTER) {\n    return true;                     \/\/ not one count of movement in five minutes\n  }\n  return false;\n}\n\nvoid loop() {\n  if (millis() - lastSample &gt;= SAMPLE_EVERY) {\n    lastSample = millis();\n\n    raw = analogRead(gasPin);\n    if (raw != lastRaw) {\n      lastRaw = raw;\n      lastChange = millis();\n    }\n\n    \/\/ The baseline follows the weather, and only while nothing is happening.\n    if (state == NORMAL) {\n      baseline = smoothing * baseline + (1.0 - smoothing) * raw;\n    }\n    rise = raw - (int) baseline;\n  }\n\n  \/\/ ---- Preheat. Nothing is believed during it. ----\n  if (state == PREHEAT) {\n    if (millis() - blinkAt &gt;= 700) {\n      blinkAt = millis();\n      blinkOn = !blinkOn;\n      setLights(false, blinkOn, false);\n    }\n    if (millis() &gt;= PREHEAT_MS) {\n      baseline = analogRead(gasPin);\n      state = NORMAL;\n      Serial.print(F(\"preheat done. baseline = \"));\n      Serial.println(baseline);\n    }\n    return;\n  }\n\n  \/\/ ---- A fault outranks everything except the alarm. ----\n  if (state != ALARM &amp;&amp; implausible()) {\n    if (state != FAULT) {\n      state = FAULT;\n      Serial.print(F(\"FAULT: implausible reading \"));\n      Serial.println(raw);\n    }\n  } else if (state == FAULT) {\n    state = NORMAL;\n    baseline = raw;\n    Serial.println(F(\"fault cleared\"));\n  }\n\n  \/\/ ---- The reset button only ever clears a latched alarm. ----\n  if (state == ALARM &amp;&amp; digitalRead(resetPin) == LOW) {\n    Serial.println(F(\"alarm acknowledged\"));\n    state = NORMAL;\n    baseline = raw;                  \/\/ start again from where we are now\n    noTone(buzzerPin);\n  }\n\n  \/\/ ---- Transitions ----\n  if (state == NORMAL &amp;&amp; rise &gt; WARN_RISE) {\n    state = WARN;\n    Serial.print(F(\"WARN: rise \"));\n    Serial.println(rise);\n  } else if (state == WARN &amp;&amp; rise &gt; ALARM_RISE) {\n    state = ALARM;\n    Serial.print(F(\"ALARM: rise \"));\n    Serial.println(rise);\n  } else if (state == WARN &amp;&amp; rise &lt; WARN_RISE \/ 2) {\n    state = NORMAL;\n    Serial.println(F(\"clear\"));\n  }\n\n  \/\/ ---- What each state looks and sounds like ----\n  switch (state) {\n    case NORMAL:\n      setLights(true, false, false);\n      noTone(buzzerPin);\n      digitalWrite(lampPin, RELAY_OFF);\n      digitalWrite(fanPin, RELAY_OFF);\n      break;\n\n    case WARN:\n      setLights(false, true, false);\n      digitalWrite(lampPin, RELAY_OFF);\n      digitalWrite(fanPin, RELAY_ON);          \/\/ ventilate early\n      if (millis() % 3000 &lt; 120) {\n        tone(buzzerPin, 1800);\n      } else {\n        noTone(buzzerPin);\n      }\n      break;\n\n    case ALARM:\n      setLights(false, false, true);\n      digitalWrite(lampPin, RELAY_ON);\n      digitalWrite(fanPin, RELAY_ON);\n      tone(buzzerPin, (millis() % 800 &lt; 400) ? 2400 : 1600);\n      break;\n\n    case FAULT:\n      if (millis() - blinkAt &gt;= 200) {\n        blinkAt = millis();\n        blinkOn = !blinkOn;\n        setLights(false, false, blinkOn);\n      }\n      digitalWrite(lampPin, RELAY_OFF);\n      digitalWrite(fanPin, RELAY_OFF);\n      if (millis() % 2000 &lt; 80) {\n        tone(buzzerPin, 600);                  \/\/ low, and unlike the alarm\n      } else {\n        noTone(buzzerPin);\n      }\n      break;\n\n    default:\n      break;\n  }\n}<\/code><\/pre>\n<h3>Five decisions worth explaining<\/h3>\n<p><strong>Nothing is believed during preheat.<\/strong> The reading starts high and falls for three minutes, which looks exactly like a leak clearing. Alarming on it would be alarming on the sensor warming up, and it would happen at every power cut.<\/p>\n<p><strong>The fault check outranks the gas logic, but not the alarm.<\/strong> A sensor that has stopped responding cannot clear an alarm that is already sounding \u2014 that decision belongs to the person with the button.<\/p>\n<p><strong>\u201cStuck\u201d is a fault, not just a range check.<\/strong> A reading pinned at an entirely plausible 412 for five minutes is a dead sensor or a frozen input, and the range check alone would never notice. Real air always wanders by a count or two.<\/p>\n<p><strong>The fault beep is deliberately unlike the alarm.<\/strong> Low, short, every two seconds, against the alarm\u2019s loud two-tone. Someone across the room should be able to tell \u201cit is broken\u201d from \u201cthere is gas\u201d without coming over to look.<\/p>\n<p><strong>Acknowledging resets the baseline to the current reading.<\/strong> After a real event the air takes tens of seconds to clear, and resuming with the old baseline would re-alarm immediately. Starting from where things are now is the honest choice, and it is also why the alarm had to latch: the record of what happened is the latch, not the reading.<\/p>\n<h2>Testing it<\/h2>\n<table>\n<thead>\n<tr>\n<th>Try this<\/th>\n<th>It should<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Power up<\/td>\n<td>Amber blink for three minutes, then green<\/td>\n<\/tr>\n<tr>\n<td>Alcohol-dipped cotton bud near the mesh<\/td>\n<td>Amber and a chirp, then red and the siren<\/td>\n<\/tr>\n<tr>\n<td>Take it away<\/td>\n<td>Stay red and sounding; it has latched<\/td>\n<\/tr>\n<tr>\n<td>Press reset<\/td>\n<td>Green, immediately, with a new baseline<\/td>\n<\/tr>\n<tr>\n<td>Press reset while green<\/td>\n<td>Nothing at all<\/td>\n<\/tr>\n<tr>\n<td><strong>Pull the <code>A0<\/code> wire off<\/strong><\/td>\n<td>Red fast blink and the low fault beep, within a few seconds<\/td>\n<\/tr>\n<tr>\n<td>Pull <code>VCC<\/code> off the sensor instead<\/td>\n<td>Fault, though it may take the five-minute stuck check<\/td>\n<\/tr>\n<tr>\n<td>Leave it an hour untouched<\/td>\n<td>Still green; the baseline follows the room<\/td>\n<\/tr>\n<tr>\n<td>Blow out a match nearby<\/td>\n<td>Warn or alarm, depending on how close<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>The sixth test is the point of the project.<\/strong> Anyone can make a buzzer sound when a reading goes up. Making the box say \u201cdo not trust me\u201d when its sensor falls off is the part that takes thought, and it is worth doing that test in front of whoever you built it for.<\/p>\n<p>The seventh is slower on purpose and worth understanding. Unplugging <code>VCC<\/code> leaves the heater off but the analog pin still connected, so the reading may stay plausible for a while \u2014 which is exactly why the stuck check exists alongside the range check.<\/p>\n<h2>Making it yours<\/h2>\n<ul>\n<li><strong>Show the numbers.<\/strong> An I2C LCD with the raw reading, the baseline and the rise makes choosing thresholds much easier, and makes the project explain itself.<\/li>\n<li><strong>Log the events.<\/strong> The SD card module and the DS3231: a dated line for every warn, alarm and fault. A month of that tells you whether your thresholds are right.<\/li>\n<li><strong>Send it somewhere.<\/strong> The ESP32 MQTT node turns an alarm into a message on your phone. Keep the local buzzer: a notification nobody looks at is not an alarm.<\/li>\n<li><strong>Add a second sensor.<\/strong> An MQ-5 alongside the MQ-2 is more specific to LPG, and two sensors agreeing is far more convincing than one. They wire identically.<\/li>\n<li><strong>Give it a battery.<\/strong> A mains alarm that dies in a power cut is a project; one that keeps watching is a device. <em>Powering Your Project<\/em> has the options, and the heater\u2019s 150 mA makes this harder than it looks.<\/li>\n<\/ul>\n<p>What not to do: put a solenoid valve on the gas line from this. That is the one extension to leave to somebody qualified.<\/p>\n<h2>Troubleshooting<\/h2>\n<table>\n<thead>\n<tr>\n<th>Symptom<\/th>\n<th>Likely cause<\/th>\n<th>Check or fix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Alarms a few minutes after power-up<\/td>\n<td>Preheat too short<\/td>\n<td>Three minutes, and nothing believed before it<\/td>\n<\/tr>\n<tr>\n<td>Alarms by itself in the afternoon<\/td>\n<td>Fixed-threshold thinking<\/td>\n<td>The baseline tracks it; check <code>state == NORMAL<\/code> is the only drift case<\/td>\n<\/tr>\n<tr>\n<td>Never alarms, even on alcohol<\/td>\n<td><code>WARN_RISE<\/code> too high<\/td>\n<td>Print <code>rise<\/code> and watch it<\/td>\n<\/tr>\n<tr>\n<td>Alarms constantly in the kitchen<\/td>\n<td>Too near the cooker<\/td>\n<td>Move it; it responds to many gases<\/td>\n<\/tr>\n<tr>\n<td>Nothing after a real leak outside<\/td>\n<td>Sensor mounted too high<\/td>\n<td>LPG sinks; thirty centimetres from the floor<\/td>\n<\/tr>\n<tr>\n<td>Alarm clears itself<\/td>\n<td>Baseline still drifting while alarming<\/td>\n<td>It must only drift in <code>NORMAL<\/code><\/td>\n<\/tr>\n<tr>\n<td>LED on pin 3 or 11 will not dim<\/td>\n<td><code>tone()<\/code> owns Timer 2<\/td>\n<td>Use 5, 6, 9 or 10<\/td>\n<\/tr>\n<tr>\n<td>Relay does not click<\/td>\n<td>Coil supply or the yellow jumper<\/td>\n<td>See <em>A Two-Channel Relay Module<\/em><\/td>\n<\/tr>\n<tr>\n<td>Relay buzzes and will not pull in<\/td>\n<td>A 12 V coil on 5 V<\/td>\n<td>Read the printing on the relay<\/td>\n<\/tr>\n<tr>\n<td>Fault state at every power-up<\/td>\n<td><code>PLAUSIBLE_LOW<\/code> above the real baseline<\/td>\n<td>Widen the window to your measurements<\/td>\n<\/tr>\n<tr>\n<td>Reading drifts for a day or two<\/td>\n<td>Never burnt in<\/td>\n<td>24 to 48 hours powered, once in its life<\/td>\n<\/tr>\n<tr>\n<td>Board resets when the fan starts<\/td>\n<td>Fan current through the Arduino\u2019s supply<\/td>\n<td>Separate supply, grounds joined<\/td>\n<\/tr>\n<tr>\n<td>Everybody trusts it<\/td>\n<td>The real risk<\/td>\n<td>Say what it is. Fit a certified detector too<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Sources and attribution<\/h2>\n<p>All text, wiring guidance and code in this project are original Siratek work.<\/p>\n<ul>\n<li>Sensor behaviour, the preheat and burn-in periods, the 150 mA heater, the gas-density siting advice, the baseline technique and the safe testing method with alcohol are as set out in <em>Smoke and Gas Sensing with MQ-2<\/em>, which cites the MQ-2 datasheet.<\/li>\n<li>The Timer 2 conflict affecting PWM on pins 3 and 11 is as set out in <em>Play Tones with a Passive Buzzer<\/em>.<\/li>\n<li>The optocouplers, the coil-supply jumper and the <strong>coil voltage discrepancy on product 3398<\/strong> are as set out in <em>A Two-Channel Relay Module<\/em>, read from the Siratek product photographs.<\/li>\n<li>The five-state design, the latching alarm, the plausibility and stuck-reading checks and the distinct fault signal are Siratek\u2019s own design decisions for this project.<\/li>\n<\/ul>\n<p>Thresholds are specific to one sensor in one room after burn-in, so the tutorial gives a procedure for measuring them rather than values to copy. <strong>This project has not yet been built and run on hardware.<\/strong> The limits of what this sensor can be trusted to do are stated at the top of the page and are not softened anywhere below it. No third-party tutorial text, diagrams, photographs or code has been reproduced here.<\/p>\n<p><\/p>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>A box that watches the air near an LPG cylinder, sounds an alarm when the level rises, latches until somebody acknowledges it, switches on a fan, and tells you plainly when it cannot be trusted.<\/p>\n","protected":false},"featured_media":0,"template":"","siratek_tutorial_level":[],"class_list":["post-52243","siratek_tutorial","type-siratek_tutorial","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Project, a Gas Leak Alarm - siratek<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Project, a Gas Leak Alarm - siratek\" \/>\n<meta property=\"og:description\" content=\"A box that watches the air near an LPG cylinder, sounds an alarm when the level rises, latches until somebody acknowledges it, switches on a fan, and tells you plainly when it cannot be trusted.\" \/>\n<meta property=\"og:url\" content=\"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/\" \/>\n<meta property=\"og:site_name\" content=\"siratek\" \/>\n<meta property=\"og:image\" content=\"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/\",\"url\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/\",\"name\":\"Project, a Gas Leak Alarm - siratek\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/siratek.net\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/#primaryimage\"},\"image\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/gas-leak-alarm-wiring.svg\",\"datePublished\":\"2026-11-01T10:50:45+00:00\",\"breadcrumb\":{\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/#primaryimage\",\"url\":\"https:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/gas-leak-alarm-wiring.svg\",\"contentUrl\":\"https:\\\/\\\/siratek.net\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/gas-leak-alarm-wiring.svg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/gas-leak-alarm\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/siratek.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tutorials\",\"item\":\"https:\\\/\\\/siratek.net\\\/index.php\\\/tutorials\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Project, a Gas Leak Alarm\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/siratek.net\\\/#website\",\"url\":\"https:\\\/\\\/siratek.net\\\/\",\"name\":\"siratek\",\"description\":\"Your Best Electronic Retail Shop\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/siratek.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Project, a Gas Leak Alarm - siratek","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/","og_locale":"en_US","og_type":"article","og_title":"Project, a Gas Leak Alarm - siratek","og_description":"A box that watches the air near an LPG cylinder, sounds an alarm when the level rises, latches until somebody acknowledges it, switches on a fan, and tells you plainly when it cannot be trusted.","og_url":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/","og_site_name":"siratek","og_image":[{"url":"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/","url":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/","name":"Project, a Gas Leak Alarm - siratek","isPartOf":{"@id":"https:\/\/siratek.net\/#website"},"primaryImageOfPage":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/#primaryimage"},"image":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/#primaryimage"},"thumbnailUrl":"http:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg","datePublished":"2026-11-01T10:50:45+00:00","breadcrumb":{"@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/#primaryimage","url":"https:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg","contentUrl":"https:\/\/siratek.net\/wp-content\/uploads\/2026\/11\/gas-leak-alarm-wiring.svg"},{"@type":"BreadcrumbList","@id":"http:\/\/siratek.net\/index.php\/tutorials\/gas-leak-alarm\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/siratek.net\/"},{"@type":"ListItem","position":2,"name":"Tutorials","item":"https:\/\/siratek.net\/index.php\/tutorials\/"},{"@type":"ListItem","position":3,"name":"Project, a Gas Leak Alarm"}]},{"@type":"WebSite","@id":"https:\/\/siratek.net\/#website","url":"https:\/\/siratek.net\/","name":"siratek","description":"Your Best Electronic Retail Shop","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/siratek.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial\/52243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial"}],"about":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/types\/siratek_tutorial"}],"version-history":[{"count":0,"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial\/52243\/revisions"}],"wp:attachment":[{"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/media?parent=52243"}],"wp:term":[{"taxonomy":"siratek_tutorial_level","embeddable":true,"href":"https:\/\/siratek.net\/index.php\/wp-json\/wp\/v2\/siratek_tutorial_level?post=52243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}