Motion-sensing, Arduino-based Washing Machine Alarm
I don’t iron clothes. Heck, I don’t even own an iron - quickly folding clothes right when I remove them from the dryer works for most of them (and a steamer does the job when that fails).
Problem: my current machine has a very low and short audio warning, so I often miss when it is done, ending up with wrinkled clothes. 😔
I thought it wouldn’t be too hard to build a device that detected when the machine stopped moving and alerted me in a more extravagant way. Having never played with raw accelerometers before, I would at least have some fun trying!
This instructables tutorial was a good starting point, but I had to change a few things:
- Instead of a power adaptor (requires a power outlet, not available near my dryer), I used a set of 4 AA bateries;
- To conserve battery power (and also to make it less bulky), I chose the Arduino Nano (actually, a cheap clone I got for CAD$ 8 at Home Hardware)
- The Memsic 2125 accelerometer used for motion sensing on that tutorial is a bit expensive. A cheaper one like the ADXL-345 does the job for CAD$ 4.50.
- Sending SMS is cool (and I’m considering something like that for an upgrade; see below), but requires expensive (and power-hungry) add-ons. For this first run, I used a (you guess - cheap) piezo speaker I had in my electronics drawer.
The piezo is easy to wire: (-) to Arduino GND, (+) to any Arduino digital pin (I chose pin 8). The accelerometer can be powered from the Arduino (connect their GND and 5V pins) and works out of the box with the Arduino Unified Sensor Driver if you connect the SDA and SCL pins to Arduino pins A4 and A5, respectively:
The on-off switch is actually built in my battery holder (which is AA, not AAA as in the illustration). It serves a dual purpose: saving power when the circuit is not in use, and providing a simple way to to turn the alarm off when I tend to the clothes.
Tested the idea using this prototype:
For the final version, I cut a piece of protoboard to the right size, soldering jumpers for the connections:
Yes, I used random pieces of wire from the magic drawer. The different colors are ugly, but make connections easy to check. I fixed the board on the battery holder with Durepoxi (a magic plastic adhesive I had to bring from Brazil - if you ever find it for sale online or in Toronto, please let me know).
The final result was not too shabby:
The software checks the accelerometer every few seconds (putting the board in full sleep between checks), and sums the change in acceleration for each of the axis (x, y and z). If that sum is greater than a given value, the device is considered to be moving.
Once we get a certain number of “not moving” consecutive measurements, we decide the dryer has stopped shaking it, and trigger the sound. That’s it.
| | // washing_machine_alarm.ino | | | // | | | // Copyright by Carlos Duarte Do Nascimento, 2017 | | | // Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php | | | // More info: https://chester.me/archives/2017/12/motion-sensing-arduino-based-washing-machine-alarm/ | | | | | | #include <Wire.h> | | | #include <Adafruit_Sensor.h> | | | #include <Adafruit_ADXL345_U.h> | | | #include <LowPower.h> | | | | | | #define SPEAKER_PIN 8 | | | #define MOTION_SENSITIVITY 0.15 /* smaller values = more sensitive */ | | | #define MEASUREMENTS_TO_CONSIDER_STOPPED 3 | | | | | | Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); | | | sensors_vec_t old_acceleration; | | | sensors_event_t event; | | | | | | bool moving() { | | | accel.getEvent(&event); | | | float motion = | | | abs(old_acceleration.x - event.acceleration.x) + | | | abs(old_acceleration.y - event.acceleration.y) + | | | abs(old_acceleration.z - event.acceleration.z); | | | old_acceleration = event.acceleration; | | | return (motion > MOTION_SENSITIVITY); | | | } | | | | | | void play_music() { | | | while (true) { | | | tone(SPEAKER_PIN, 1000, 500); | | | LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); | | | } | | | } | | | | | | void setup() { | | | accel.begin(); | | | pinMode(SPEAKER_PIN, OUTPUT); | | | } | | | | | | int no_movement_count = 0; | | | | | | void loop() { | | | LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); | | | | | | if (moving()) { | | | no_movement_count = 0; | | | } else { | | | no_movement_count++; | | | } | | | | | | if (no_movement_count == MEASUREMENTS_TO_CONSIDER_STOPPED) { | | | play_music(); | | | } | | | } |
view raw washing_machine_alarm.ino hosted with ❤ by GitHub
The values of MOTION_SENSITIVITY
and MEASUREMENTS_TO_CONSIDER_STOPPED
were tweaked to match my dryer.
As-is, the code will just play an annoying beep, but you can replace the play_music()
function with anything. For example, I threw a MIDI file with the Animaniacs opening theme into a MIDI To Arduino Code converter. Here is the result (as I manually turn the machine off):
I’m happy with how it turned out, but there is room for improvement:
- The power consumption can be reduced by disabling one or both the LEDs and tweaking with power regulation, but that requires cutting the board, which I’m not in the mood for - yet.
- What if I’m wearing headphones? I wish I could trigger Google Home (currently hard), or maybe play a sound on my computer. If I can come with something not too power-hungry or overcomplicated to make that, I guess I’ll tinker with this again…