Your laundry is done

Have you ever forgotten your wet clothing inside the washer for a whole day? I have. Even for two days. They smell. You have to wash them again and you know you might end up forgetting about them again!

Actually that is happening to me since me moved to an old house in a town north of Barcelona. Instead of having the washer in the kitchen, like we used to, now we have it in the cellar, in a place I don’t normally pass by to notice the laundry is done.

So I started thinking about monitoring the washer to get notifications when the laundry is done. And since I was at the same time playing with ITead’s Sonoffs, which has an AC/DC transformer and a powerful controller with wifi, it looked like a nice project to put together.

EXTREME CAUTION: live mains are very dangerous. Don’t work with them unless you know what you are doing and what the consequences might be.

Wiring the ADC pin

The Sonoff does not bring out the ADC pin on then ESP8266EX. Some Sonoff TH versions do bring out GPIO14 and latest Sonoff TH 10A/16A probably do the same through a jack interface. But that’s not the case for TOUT aka ADC pin.

No problem, follow me:  grab the iron with a narrow tip, a short thin cable and a magnifier, because you are going to need it. If you are not really good at soldering (and I’m not) you can still do it, but you will have to check and double check for bridges between the ADC pin and its neighbours. The ADC pin is the 6th in the left side of the chip (with the dot on the top left corner).

First solder a 3 pin header on the unpopulated holes for the RF module. If you use the first 3 counting from the relay you will already have GND and 3V3 on the first two, so you just need to connect the ADC pin in the Espressif chip to the third header. Take your time, do not apply heat for more than a second and leave it cool before doing it again. Check with your continuity tester after and prepare a simple gig to test your hack: a 10k potentiometer with a 20k resistor to build a voltage divider will do.


Don’t work with the board connected to mains! Again: Don’t work with the board connected to mains! After testing for shorts and continuity hot glue everything to prevent the cable from comming loose and create a potentially fatal short between mains.

Bringing out the ADC GPIO on the ESP8266

That was tricky! Bringing out the ADC GPIO in the ES8266EX to a 3 pin header using the unpopulated RF header of the Sonoff…

Sensor board

Now that I had the ADC pin I prepared a simple stripboard with a current sensor and a simple voltage bias circuit. The current sensor I use is a chep (and not very accurate) Talema ASM-010. It outputs a small voltage proportional to the current flowing through the hole. According to the charts in the datasheet the ratio is about 300A per 1V. That’s a very poor value, and even thou I could pass the cable twice, reducing the ratio to 150A per V the YHDC SCT-013-030, a very common non invasive current, has a ratio of 30A per 1V, 5 times more accurate. But I just need to know whether there is current flowing or not.

The board has two resistors (nominal 10k and 56k) to build a voltage divider to bias the output voltage by 0.5V so the ADC will always read positive values, and a 10uF capacitor to soften signal.

Sensor board

The sensor board with one of the live cables doing two turns inside the coil. There are also two resistors to bias the voltage and a capacitor.

Sonoff and the sensor board inside the enclosure

The Sonoff and the sensor board inside the enclosure.

Adapting the EmonLib

The EmonLib is the unofficial standard library to monitor current on an Arduino and alikes. But it doesn’t support ESP8266 based boards yet. Current issues are:

  • It only supports 10 bit ADCs (ESP8266 ADC is 10bits too, but it only has one analog pin, so chances are you will use an external ADC chip in some projects, like de 16bits ADS1115)
  • Voltage reference calculation doesn’t take into account non-atmel chips (the ESP8266 ADC is 1V referenced)
  • Analog reading is hardcoded in the library, again, what if you are using and external chip with I2C communication?

The usual approach is to include parts of the library code into your code and monitor analog pin 0. You could also use and external ADS1115 like Tisham Daar does.

This is not the first project I use current monitoring on a ESP8266, so I decided to wrap all the functionality I wanted in a proper library. And so EmonLiteESP was born. As the name says it’s a lite version of the EmonLib, since it only supports current monitoring at the time (only apparent power). But truth is that naming it after the EmonLib could be misleading since it is not API compatible (and maybe I’m violating some trade mark, didn’t check that).

The library main features are:

  • Customizable ADC bit count
  • Customizable ADC voltage reference
  • Read ADC values via callbacks

And its easy to use:

#include "EmonLiteESP.h"

EmonLiteESP power;

unsigned int adcBits = 10; // ADC bit resoltion (normally 10)
double referenceVoltage = 1.0; // 1.0V for a bare ESP8266 chip
double currentRatio = 30; // 30A 1V for a YHDC SCT-013-030
double mainsVoltage = 230.0 // EU standard
unsigned int samples = 1000; // 1000 samples each time we measure current

unsigned int currentCallback() {
   return analogRead(0);

void setup() {
   power.initCurrent(currentCallback, adcBits, referenceVoltage, currentRatio);

void loop() {
  double current = power.getCurrent(samples);
  Serial.print(F("Power now: "));
  Serial.print(int(current * mainsVoltage));

Now that…

Some time ago, at a previous job, our CTO was very concerned about unnecessary code. He had a list of anti-patterns to identify bad practices when developing a new feature. The YANGNI (You Are Not Gonna Need It, meaning just code what you are going to use now) was his favourite one. Another favourite was the YAQUE (spanish for “Now that…”). Now that we are touching this code, why don’t we add this cool feature?

So breaking the YAQUE rule I added a DHT22 sensor because I could, and because we have moisture related problems in the cellar. The sensor is connected to the GPIO14 pin already available in the Sonoff board. I soldered a 10K SMD0805 resistor between the left-most 2 pins of the DHT22 (VCC and DATA) and drilled a hole in the case to place the sensor outside the box.

Another improvement was to add a case mounted momentary button on the enclosure, soldered to the onboard button, so I can manually switch the relay ON and OFF.

Wired Sonoff board

A wired Sonoff board with connections to the current sensor board, to the DHT22 temperature and humidity sensor and to the case mounted button.

Project box

The final project box

I have included all these features in my last ESPurna firmware version. Please check it out at espurna bitbucket repository.

Analyzing the data

So the goal of this project was to get a notification when my laundry is done. You don’t really need an accurate power measurement for that, only monitoring if there is current flowing or not and keeping track on how long has the washer been “quiet”.

First step is to see how the washer power profile looks like. It will probably depend on the washing program you are using but for the one we normally use for day-by-day laundry it looks like this:

So you can see the washer has been working for 27 minutes (from 11:27 to 11:54) with several quiet windows of no more than 2 minutes each. Please note this measurements have been taken every minute averaging 6 readings every 10 seconds. For this program it might be enough to check whether the washer has been quiet for the last, say, five minutes after seeing activity and then emit the notification.

Node-RED driven notifications

Final step is to set a notification when the laundry is done. I’ve been using Node-RED for some time now and I like having everything in one place in a flexible and structured way: notifications, database persistence, cloud service connections (xively, blynk,, thigspeak…), schedulers,…

Now that I have an MQTT topic with the washer power consumption is pretty easy to write a javascript function that monitors it and sends a notification when the washer has been idle for five minutes after some significant activity. To implement that I built a 5 positions ring that stores whether there has been activity or not for the last 5 minutes or last 5 messages. It sets a flag when at least 3 of those messages contain non-zero values (that’s a significat activity). After that, when the buffer empties (5 minutes without activity) it sends the notification and clears the flag.

I’m sure the code will be much more clear than my explanation:

// Configuration
const WASHER_BUFFER = 5;

// Get current state
var washer_flag = flow.get('washer_flag') || 0;
var washer_sum = flow.get('washer_sum') || 0;
var washer_store = flow.get('washer_store') || Array(WASHER_BUFFER);
var washer_pointer = flow.get('washer_pointer') || 0;

// Update state
var current = parseInt(msg.payload) < 100 ? 0 : 1;
washer_sum = washer_sum - washer_store[washer_pointer] + current;
if (washer_sum < 0) washer_sum = 0;
washer_store[washer_pointer] = current;
washer_pointer = (washer_pointer + 1) % WASHER_BUFFER;
if (washer_sum > 2) washer_flag = 1;

    fill: (washer_sum === 0) ? "red" : "green",
    shape: "dot",
    text: "Washer machine state: " + (washer_sum === 0 ? "idle" : "working")

// Notifications
if ((washer_flag === 1) && (washer_sum === 0)) {
    washer_flag = 0;
    msg.topic = "Washer";
    msg.payload = "Your laundry is done!!";
    msg.trigger = {
        'topic': '/trigger/washer/done',
        'payload': 1
} else {
    msg = null;

// Store state
flow.set('washer_flag', washer_flag);
flow.set('washer_sum', washer_sum);
flow.set('washer_store', washer_store);
flow.set('washer_pointer', washer_pointer);

return msg;

The message is then passed to a subflow that sends it to Pushover service and also publishes it to the local MQTT broker.



And voilà: no more forgotten laundries… I hope.

CC BY-SA 4.0 Your laundry is done by Tinkerman is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

28 thoughts on “Your laundry is done

  1. Pingback: Your laundry is done! - Electronics-Lab

  2. Pingback: Your Laundry Is Done! | Hackaday

  3. Pingback: Your Laundry Is Done! | BH

  4. Pingback: Your Laundry Is Executed! | GetUsaNews

  5. Pingback: Your Laundry Is Done! | Ad Pub

  6. manwob

    This is a useful project that I could use to remotely monitor whether a cooker is ON or OFF. Thanks from providing the details.

  7. spants

    Interesting article —- BUT —- please make sure that you have “hot glued” that adc cable down so that it doesnt move. If the pin header end comes undone, it will short against LIVE voltages (240/220/110v) on those two large silver tracks and probably start a fire… (You mentioned that you are a beginner at soldering so this is even more important!).
    Also people reading this… There are live voltages on this board. Do not plug it in when it is not in the case.

    1. Xose Post author

      You are very right. Playing with mains can be dangerous so anyone should do it with extreme caution. Not being good at it doesn’t mean I had not had my fair amount of soldering, and yes: that cable is hot glued. Thanks for your comment!

  8. Tisham Dhar (@whatnick)

    Hey thanks for the shout out to my project. You don’t really need true power measurements so the external ADC is not a must. The Sonoff is a very cost effective ESP8266 AC development option and I might adapt my energy monitor to it to save the dangerous soldering efforts.

    1. Xose Post author

      You are welcome!! The trick to solder the wire to the ADC pin is to have a fine tip and patience, because you should not apply heat for more then a second or so and you will probably have to fix a bridge or two. Have your continuity tester on hand and test all the neighbours pins before doing code tests. When everything is OK don’t forget to hot-glue everything so the cable won’t come loose.

  9. Pingback: How to Build and Flash ESPurna Open Source Firmware to Sonoff POW Wireless Switch

  10. euquiq

    Hi Xose! I’ve been using your library for some time now, excellent work! I got a blog (In Spanish language) where I published my own proyect along with the source code:

    I am wondering if you are getting the same problem as me: Sooner or later, the ESP8266 is reset. I am suspecting the watchdog being tripped. I tried placing yield() everywhere, with no luck.

    In short, it never works for more than 24 hours without resetting. Sometimes it is a couple of minutes after being powered up. Other times is after 10 or 20 hours. I am baffled. Did you experience the same behavior ?

    1. Xose Pérez Post author

      You say the ESP is resetting, not disconnecting from the Wifi? Can you capture the error output from the terminal?
      How many samples are you taking to measure the RMS of the current?
      Also it would be interesting to know the SPS rate, or how much does it take to get the X samples you are reading.

  11. euquiq

    Hi Xose, I’ve been busy investigating this problem. At first I was taking 1000 samples, but not I reduced te sampling quantity to 500 … (and even tried 1500, 200, etc.) it randomly resets just the same.

    It seems to happen entirely at random. I am using a SCT 013 030 (the 30Amps – 1V) clamp sensor. I hooked it directly into the ADC pin on the ESP8266.

    I *suspect* that the sudden reseting may be due to the negative voltage, whenever there is a big enough spike, since the 1v that the clamp delivers is an AC wave (I suspect -0.5 to +0.5v). There is not much information around the web on this sensor and / or arduino projects. I chose this amp clamp sensor because the 1v output seemed ideal for the ADC on the ESP8266.

    I did not factor in the “negative voltage” side of the wave having an eventual harmful effect. But I repeat: This is my suspicion, I am not sure it is due to negative voltage.

    Now I placed an ADS1115 between the sensor and the ESP8266. I found out that the ADS1115 is extremely SLOW measuring analog signals and converting them into 16 bits. So slow, that I had to reduce 10x the sampling quantity (I am in about 100 samples) in order for my ESP8266 to take one measure per second.

    The good side: It has passed several hours by now and the ESP8266 has not reset itself.

    The bad side: The values out of the ADS1115 are not linear, or much consistent at all. Also the parameters I programmed into the ADS1115 in order to work are baffling me (EmonLiteESP is working with referencevoltage: 1 currentratio: 30 adcCounts: 48300 and the ADS1115 is programmed with GAIN_EIGHT, +/- 0.512V 1 bit = 0.015625mV)

    Hopefully this search / investigation is of use to others. On the other hand, my knowledge of electronics is rudimentary, as this is only a hobby (I like to code, which is my job, in “real life”)

    Have a Happy New Year !!

    1. Xose Pérez Post author

      If you only use one ADC there is no need to use a ADS1115 unless you want more accuracy. My experience is that a 10bit ADC is good enough for a CT. BUT, you must ensure that the ADC pin only sees positive voltages. The simplest way is to use a voltage divider to shift the ground to 1/2 Vcc. Check this post in Open Energy Monitor project for more info.

      Actually, there are a lot of projects using the SCT013-030, going no further my latest post use that sensor. You can check the schematics for the Moteino Shield I’m using in that project here:

  12. euquiq

    wow! Thanks, nice posts! It seems that google did not index those links at the time of my web searches. I ditched the ADS1115, went back to 10bit ESP8266 ADC, put two resistors and an electrolytic capacitor (I had only a 4.7 uf one) … and I got it working with better precision than before (where I catched, I suppose, just half of the AC wave). Now let’s see if it keeps reseting or not. I am confident it will NOT reset, as it is properly connected with no negative voltage from the SCT013-30 entering the ESP8266, thank you!

  13. Marco Sturiale

    I would like to use directly a Wemos to calculate power.
    I tried to connect it directly to the sensor, but I think it’s not optimal.
    Could you share the circuit that you used to interface it?

    Thank you!

  14. Daniel

    Hi Xose,
    this solution looks exactly, like what I am currently trying to implement.
    I am using an Edimax SP-2101W smart plug (
    for the power metering and since there is a node available, it is easy to integrate with Node-Red.

    For maintenance purposes I would prefer to use standard nodes for the monitor logic (machine off, running or finished), what you did with the java script code. And here I am stuck right now.
    I have no real clue, how to work with buffers and the like.
    Would you have an idea on how to implement you logic using standard Node-Red nodes?

    Best regards,

  15. Sergio Rius

    Estimat Xose,
    Thanks for making public this excellent work. I’ve learned so much with it. I really like the callback functionality.
    Although I’m trying to use it in slightly different manner and I can’t get good values. Perhaps you can give me a hand.

    I’m using a 5V Arduino, and trying to plug four STC013-030, along with other sensors, so I decided to use two ADS1115 in difference mode.
    If I understand well, my init should be:
    power.initCurrent(currentCallback, 15, 5, 30); // ADS1115 = 15bit + sign, 5V, 30A SCT.
    and in my callback I run:
    return ads.readADC_Differential_0_1() * getMultiplier(ads); //0.0625F

    But that makes it read 13721.800W for a 100w bulb

    Can you please instruct me on how to use it with an ADS?
    Thank you.

    1. Xose Pérez Post author

      Don’t have any ADS1115 here now to test (I have like 120 of them at the office, but not here). What I see in your code is that you are using a GAIN 2 so your refference voltage should be 2.048 when in difference mode. Also don’t think you have to use the getMultiplier() method, the reading will be automatically scaled.

  16. Pingback: Painfully Obvious → Laundry Spy, Part 1: The hardware

  17. Pingback: Sonoff Pow – що е то? – MiraLabs

    1. Xose Pérez Post author

      I did this two years ago. There are many new products available since then that would do this without having to solder thin wires close to mains… Check the Blitzwolf BW-SHP2 or the HomeCube SP1. These are smart switches with power monitoring features. You can flash ESPurna on them and make the report the readings via MQTT.


Leave a Reply (all comments are moderated, be patient)

This site uses Akismet to reduce spam. Learn how your comment data is processed.