MQTT Smoke Detector Monitoring
The smoke detector used in this demo is from Universal Security Instruments, https://www.universalsecurity.com/.
This manufacturer provides turnkey products that have been designed, tested, and certified for use.
It is recommended that these products not be modified when used for life safety applications.
This post is for demonstration purposes only, do not replicate if used for anything other than lab testing.
The intent of this post is to demonstrate how to handle external conditions and operate an IoT device with minimal complexity and impact on the host device and its power source.
Here is a demo of smoke detector monitoring using an IoT device, but it requires an external power source.
This demo is similar, but the design uses the smoke detector power source.
The second video is limited to a host device IC supporting external triggering. These chips are originally designed to work with a series of multiple detectors that work in tandem. In an event, all of the detectors alarm. Typically a panel monitors all of the detectors. This provides a central point of control to identify what zone the event occurred, as well as triggering an alarm globally and dispatching for help.
The smoke detector made by Universal Security Instruments has its IC chip located inside the sealed detection unit containing Americium 241, https://en.wikipedia.org/wiki/Americium-241. It was sealed for a reason and it stays that way. All but a few are out of their element when it comes to radioactive materials.
The IC is a 16 pin DIP with its leads accessible on the opposite side of the PCB. Attempts to identify a triggering pin as demonstrated in the second video were unsuccessful, so a different design approach was used.
Using the alarm seems to be the common theme. The characteristics of that signal needs to be known before using it as an input. The IoT device used in this example is a Wemos Mini with 3.3 volt input limits. Exceeding that input voltage will damage the IoT device. Below is an image of the alarm signal readings.
A prompt to ChatGPT explaining the signal input and the goal resulted in a suggestion of using a mono-stable configured 555 timer IC. From there the output signal from the 555 timer can turn on a voltage regulator. This in turn powers on the Wemos module so it can run its code.
The AI suggestion lacked the details and needed further refinement. Refer to the schematic below for details. The alarm input logic needs to be inverted for the 555 timer to work as expacted. This is done using the Q1 MOSFET with the 555 timer pin 2 connected to a pull up resistor. Driving the voltage regulator directly from the 555 timer also presents a problem. The Wemos module and regulator draws more current than what the 555 timer can handle. The Q2 MOSFET handles this load with the voltage regulator input pin connected to a pull down resistor. Noise filtering capacitors C2 and C3 keep the output voltage steady for the Wemos. The timed on length for the regulator from the 555 timer is done with the RC values of R1 and C1 respectively. Monitoring the battery level is done through a voltage divider with R7 and R8. Since the 9 volt battery is highly likely to be reversed when installed, a reverse polarity protection circuit is used with the Q3 MOSFET, kindly demonstrated by Afrotechmod’s youtube video, https://afrotechmods.com/tutorials/about/. The 555 timer needs to have a low standby current, such as the TLC555CP which can run at 250 uA, see https://www.mouser.com/ProductDetail/Texas-Instruments/TLC555CP. Here are the schematics of the final design.
Here is the code used on the Wemos.
// Libraries and Declarations #include <Arduino.h> #include <ESP8266WiFi.h> #include <PubSubClient.h> WiFiClient espClient; PubSubClient MQTTclient(espClient); // Variables float sensorValue = 0; float batteryValue = 0; // Enable Analog Input Pin // Also be aware that the WiFi function can interfer with the pin making readings // So always make readings before enableing WiFi ADC_MODE(ADC_TOUT); // Define MQTT Broker and Wireless Network Connection Details const char* mqtt_server = "MQTT-Broker"; // Put your MQTT Broker here const char* myssid = "SSID"; // Put your SSID here const char* mypassword = "PASSWORD"; // Put your PASSWORD here // MQTT Callback Function void callback(char* topic, byte* message, unsigned int length) { String messageTemp; for (int i = 0; i < length; i++) { messageTemp += (char)message[i]; } if (String(topic) == "Womos-SmokeSensor/Reboot") { if(messageTemp == "Reboot"){ ESP.restart(); } } } // MQTT Reconnection Function void reconnect() { // Loop until we're reconnected while (!MQTTclient.connected()) { // Attempt to connect if (MQTTclient.connect("Womos-SmokeSensor")) { // Subscribe // Do you not subscribe to my methods? // Womos-SmokeSensor/# for everything, or Womos-SmokeSensor/Uptime for just the Uptime MQTTclient.subscribe("Womos-SmokeSensor/#"); } else { // Wait 5 seconds before retrying delay(5000); } } } // MQTT Publish Function void UpdateStats() { delay(250); MQTTclient.publish("Womos-SmokeSensor/Firmware", "Womos-SmokeSensor_ver1"); String StringUptime = String(millis()); MQTTclient.publish("Womos-SmokeSensor/Uptime", StringUptime.c_str()); String StringHWAddress = String(WiFi.macAddress()); MQTTclient.publish("Womos-SmokeSensor/HWAddress", StringHWAddress.c_str()); String StringWifiSignal = String(WiFi.RSSI()); MQTTclient.publish("Womos-SmokeSensor/WifiSignal",StringWifiSignal.c_str()); String StringFreeHeapSize = String(ESP.getFreeHeap()); MQTTclient.publish("Womos-SmokeSensor/FreeHeapSize",StringFreeHeapSize.c_str()); String StringHeapFragmentation = String(ESP.getHeapFragmentation()); MQTTclient.publish("Womos-SmokeSensor/HeapFragmentation",StringHeapFragmentation.c_str()); String StringMaxFreeBlockSize = String(ESP.getMaxFreeBlockSize()); MQTTclient.publish("Womos-SmokeSensor/MaxFreeBlockSize",StringMaxFreeBlockSize.c_str()); String StringSketchSize = String(ESP.getSketchSize()); MQTTclient.publish("Womos-SmokeSensor/SketchSize",StringSketchSize.c_str()); String StringFreeSketchSpace = String(ESP.getFreeSketchSpace()); MQTTclient.publish("Womos-SmokeSensor/FreeSketchSpace",StringFreeSketchSpace.c_str()); String StringCpuFreqMHz = String(ESP.getCpuFreqMHz()); MQTTclient.publish("Womos-SmokeSensor/CpuFreqMHz",StringCpuFreqMHz.c_str()); String StringChipId = String(ESP.getChipId()); MQTTclient.publish("Womos-SmokeSensor/ChipId",StringChipId.c_str()); String StringsensorValue = String(sensorValue); MQTTclient.publish("Womos-SmokeSensor/Sensor Reading",StringsensorValue.c_str()); String StringbatteryValue = String(batteryValue); MQTTclient.publish("Womos-SmokeSensor/Battery",StringbatteryValue.c_str()); delay(250); } // Wifi Network Connection Function, initiallizes MQTT client void WifiConnect() { WiFi.begin(myssid, mypassword); while (WiFi.status() != WL_CONNECTED) { delay(250); } MQTTclient.setServer(mqtt_server, 1883); MQTTclient.setCallback(callback); } // Primary Function - reads analog pin, calculates voltage reading, Wifi connect, and MQTT publish void CheckForNetworks() { sensorValue = analogRead(A0); batteryValue = ( (sensorValue / 1024) * 3.3 ) * 13.86; delay(1000); WifiConnect(); if (!MQTTclient.connected()) { reconnect(); } MQTTclient.loop(); UpdateStats(); } void setup() { } void loop() { CheckForNetworks(); }
When the Wemos is powered on it first takes a reading on its A0 pin of the battery voltage level. This value is 10 bits in length and ranges from 0 to 1028. That value is calculated and the result is saved as the battery voltage. This step must be done before activating the WiFi hardware on the Wemos because the A0 pin is deactivated when WiFi is on. Now the Wemos is ready to connect to a WiFi network, MQTT broker, and publish its readings. This will repeat every second until the 555 rc time is reached and power is disconnected to the Wemos.
The length of time that the smoke detector can run on a single battery change varies. In a scenario where the smoke detector remains silent and is never activated from a detection or test, the battery should last 2 months. This is based off of a 9 volt battery with a 500mAh rating and the load at 300uA.
If you need a smoke detector that has IoT capability, go buy one that has been properly designed by experts. But this demo hopefully gives you an idea of what’s behind the smoke and mirrors.