Introduction: IoT Water Alarm

I have recently experienced kitchen drain backup. Had I not been at home at the time, it would have caused floor and drywall damage in my apartment. Fortunately, I was aware of the problem and ready to scoop the water out with a bucket. This got me thinking about purchasing a flood alarm. I discovered plenty of affordable products on Amazon, but the ones with internet connectivity had a significant percentage of negative reviews, primarily because of issues with proprietary notification services. That's why I decided to make my own IoT water alarm that would use trustworthy notification means of my choice.

Step 1: Principle of Operation

The alarm has an AVR ATtiny85 microcontroller as its brain. It takes voltage readings from the battery and the water sensor and compares them with pre-defined value to detect the presence of water or a low-battery condition.

The water sensor is simply two wires placed approximately 1 mm apart. One of the wires is connected to 3.3 V, and the other one is connected to a sensing pin on the microcontroller, which is also connected to ground through a 0.5 MOhm resistor. Normally, resistance between the sensor wires is very high (well over 10 MOhm), so the sensing pin is pulled all the way down to 0 V. However, when there is water present between the wires, resistance drops to less than 1 MOhm, and the sensing pin sees some voltage (in my case about 1.5 V). When ATtiny85 detects this voltage on the sensing pin, it activates a MOSFET to power up a buzzer, and sends the wake-up signal to the ESP8266 module which is responsible for sending alerts (email and push notifications). After a minute buzzing, the alarm is disarmed, and can be reset only by power cycling.

This unit runs off of two alkaline or NiMH cells. The microcontroller is asleep most of the time to conserve the batteries, waking up intermittently to check the water sensor as well as the voltage of the batteries. If the batteries are low, the microcontroller wakes up the ESP8266 module to send a low battery warning. After the warning, the alarm is disarmed to prevent battery over-discharge.

Since the ESP8266 module is responsible for sending both low battery warnings as well as flood alerts, it requires a control signal from ATiny85. Due to the limited number of pins available, this control signal is generated by the same pin responsible for battery LED indication. During normal operation (the alarm is armed and the batteries are charged), the LED blinks intermittently. When the low battery condition is detected, the LED turns on to provide high signal to the RX pin of the ESP module. If water is detected, the battery LED will be off while ESP8266 is awake..

Step 2: Design and Assembly

I designed the circuit to be built on a double-sided 4x6 cm protoboard using mostly 0805 SMD parts. The schematics presented are based on this build, but it can be adapted easily for through-hole components (tip: to minimize space, solder through-hole resistors vertically).

The following parts are required:

- Resistors: 330 Ω x 1; 470 Ω x 1; 680 Ω x 1; 1 kΩ x 1; 10 kΩ x 3; 470 kΩ x 3;
- One 10 µF ceramic capacitor
- One logic-level N-channel MOSFET (e.g. RFP30N06LE or AO3400)
- One red and one yellow LED (or other colours if you like).
- Two-wire screw terminal connectors x 3 (they are not absolutely necessary, but they make it easier to connect and disconnect periphery during testing)
- A loud piezo buzzer that's good for 3.3 V
- An ATtiny85 microcontroller (PDIP version)
- An 8-pin PDIP socket for the microcontroller
- An ESP-01 module (it can be substituted by another ESP8266-based module, but there will be a lot of changes in the layout in that case)
- A 3.3 V DC-DC boost converter capable of delivering 200 mA (500 mA burst) currents at 2.2 V input. (I recommend because of its ultra-low quiescent current)
- One 3 pin female header
- Two 4-pin female headers or one 2x4 header
- 22 AWG solid wires for the water sensor
- 22 AWG stranded wire (or another type of thin exposed wire to create traces)

I recommend the resistor values listed above, but you could substitute most of them for similar values. Depending on the type of the LEDs you want to use, you may need to adjust the current-limiting resistor values to get the desired brightness. The MOSFET can be either through-hole or SMT (SOT23). Only the orientation of the 330 Ohm resistor is affected by the type of the MOSFET. A PTC fuse (e.g. rated for 1 A) is recommended if you are planning to use this circuit with NiMH batteries. However, it is not needed with alkaline batteries. Tip: the parts required for this alarm can be purchased cheaply from ebay or aliexpress.

In addition you will need a breadboard, several through-hole 10k resistors, multiple male-male and female-male jumper ("dupont") wires and a USB-UART adapter in order to program the ESP-01 module.

The water sensor can be made in a variety of ways, but the simplest one is two 22 AWG wires with exposed ends (1 cm long) spaced approximately 1 mm apart. The goal is to have less than 5 MΩ resistance between the sensor contacts when water is present.

The circuit is designed for maximum battery economy. It draws only 40-60 µA in the monitoring regime (with the power LED removed on the ESP-01 module). Once the alarm is triggered, the circuit will draw 300-500 mA (at 2.4 V input) for a second or less, and after that the current will drop below 180 mA. Once the ESP module is done sending notifications, the current consumption will drop to below 70 mA until the buzzer switches off. Then the alarm will disarm itself, and the current consumption will be under 30 µA. Thus a set of AA batteries will be able to power the circuit for many months (likely over a year). If you use a different boost converter, say with a quiescent current of 500 µA, the batteries will need to be changed much more often.

Assembly tips:

Use a permanent marker to label all traces and component on the protoboard for easier soldering. I recommend proceeding in the following order:

- top side SMT LEDs and insulated wire bridges

- top side MOSFET (note: if you have a SOT-23 MOSFET, place it diagonally as in the photo. If you are using a through-hole MOSFET, place it horizontally with the gate pin in position I3.)

- top side through hole parts (note: the buzzer isn't soldered and doesn't even have to be mounted to the PCB)

- reverse side SMT parts and traces (e.g. individual strands from AWG22 wire)

Step 3: Firmware

C code for ATtiny85

Main.c contains the code that needs to be compiled and uploaded to the microcontroller. If you are going to use an Arduino board as a programmer, you can find the wiring diagram in this tutorial. You need to follow only the following sections (ignore the rest):

– Configuring Arduino Uno as a ISP (In-System Programming)

– Connecting ATtiny85 with Arduino Uno.

To compile and upload the firmware, you will need either CrossPack (for Mac OS) or AVR toolchain (for Windows). The following command needs to be executed to compile the code:

avr-gcc -Os -mmcu=attiny85 -c main.c; avr-gcc -mmcu=attiny85 -o main.elf main.o; avr-objcopy -j .text -j .data -O ihex main.elf main.hex

To upload the firmware, run the following:

avrdude -c arduino -p attiny85 -P /dev/cu.usbmodem1411 -b 19200 -e -U flash:w:main.hex

Instead of "/dev/cu.usbmodem1411" you will likely need to insert the serial port to which your Arduino is connected (you can find it in the Arduino IDE: Tools --> Port).

The code contains multiple functions. deep_sleep() makes the microcontroller enter a very low power state for approximately 8 seconds. read_volt() is used to measure the battery and sensor voltages. The battery voltage is measured against against the internal voltage reference (2.56 V plus or minus a few percent) whereas the sensor voltage is measured against Vcc = 3.3 V. Readings are compared against BATT_THRESHOLD and SENSOR_THRESHOLD defined as 932 and 102 respectively, which correspond to ~2.3 and 0.3 V. You may be able to reduce the battery threshold value for improved battery life, but it is not recommended (refer to Battery considerations for detailed information).

activate_alarm() notifies the ESP module about water detection and sounds the buzzer. low_batt_notification() notifies the ESP module the battery is low and also sounds the buzzer. If you don't wish to be awakened in the middle of the night to change the battery, remove "| 1<<BUZZ_PIN" in low_batt_notification().

Arduino sketch for ESP-01

I chose to program the ESP module using Arduino HAL (follow the link for set up instructions). In addition I used the following two libraries:

ESP8266 Send Email by Górász Péter

ESP8266 Pushover by the Arduino Hannover team

The first library connects to an SMTP server and sends an alert to your email address. Just create a gmail account for your ESP, and add the credentials to the code. The second library sends push notifications via the Pushover service (notifications are free, but you have to pay once to install the application on your phone/tablet). Download both libraries. Put the contents of the Send Email library into your sketch folder (arduino will create it when you open the arduino sketch for the first time). Install the Pushover library via the IDE (Sketch -> Include Library -> Add .ZIP library).

To program the ESP-01 module you can follow the following tutorial: No need to bother with resoldering one row of pins as shown in the guide — just use female-male dupont wires to connect the pins of the module to the breadboard. Don't forget that the boost converter and the USB-UART adapter have to share ground (note: you may be able to use the 3.3 V output of the USB-UART adapter instead of the boost converter, but most likely it won't be able to output enough current).

Step 4: Battery Considerations

The firmware code supplied is preconfigured to send a low battery warning and shut down at ~2.3 V. This threshold is based on the assumption that two NiMH batteries are used in series. It is not recommended to discharge any individual NiMH cell below 1 V. Assuming both cells have equal capacity and discharge characteristics, both of them will be cut off at ~1.15 V — well within the safe range. However, NiMH cells that have been in use for many discharge cycles tend to differ in capacity. Up to 30% difference in capacity can be tolerated as it would still result in the lowest voltage cell cut-off point around 1 V.

While it is possible to reduce the low battery threshold in the firmware, doing so would remove the safety margin, and could result in battery over-discharge and damage while only a marginal increase in battery life is to be expected (a NiMH cell is >85% discharged at 1.15 V).

Another factor that needs to be taken into account is the ability of the boost converter to provide at least 3.0 V (2.5 V according to anecdotal evidence) at 300-500 mA peak current on low batteries. The low internal resistance of NiMH batteries causes only a negligible drop of 0.1 V at peak currents, so a pair of NiMH cells discharged to 2.3 V (open circuit) will be able to provide at least 2.2 V to the boost converter. It is, however, more complicated with alkaline batteries. With a pair of AA batteries sitting at 2.2-2.3 V (open circuit) a voltage drop of 0.2-0.4 V is to be expected at peak currents. Although I've verified the circuit works with the recommended boost converter with as little as 1.8 V supplied at peak currents, this likely causes the output voltage to dip momentarily below the value suggested by the Espressiff. Thus the cut-off threshold of 2.3 V leaves little safety margin with alkaline batteries (keep in mind that a voltage measurement performed by the microcontroller is accurate only within plus or minus a few percent). In order to ensure the ESP module doesn't glitch when alkaline batteries are low, I recommend increasing the cut-off voltage to 2.4 V (#define BATT_THRESHOLD 973). At 1.2 V (open circuit) an alkaline cell is about 70% discharged which is only 5-10 percentage points lower than the degree of discharge at 1.15 V per cell.

Both NiMH and alkaline cells have advantages and disadvantages for this application. Alkaline batteries are safer (do not catch fire if shorted), and they have a much lower self-discharge rate. However, NiMH batteries guarantee reliable operation of ESP8266 at a lower cut-off point thanks to their low internal resistance. But ultimately, either type can be used with some precautions, so it's just a matter of personal preference.

Step 5: Legal Disclaimer

This circuit was designed by a non-professional hobbyist for hobby applications only. This design is shared in good faith, but with no warranty whatsoever. Use it and share with others at your own risk. By recreating the circuit you agree that the inventor will not be held liable for any damage (including but not limited to impairment of assets and personal injury) that may occur directly or indirectly through malfunction or normal usage of this circuit. If the laws of your country nullify or prohibit this waiver of liability, you may not use this design. If you share this design or a modified circuit based on this design, you must credit the original inventor by indicating the url of this instructable.

Wireless Contest

Participated in the
Wireless Contest