Skip navigation

See my wireless motion detection system after this link, it's pretty awesome! Or, carry on...


Disclaimer: I’m an engineer, not a pro film maker. Be advised.

Disclaimer: I’m an engineer, not a pro film maker. Be advised.



This project will retrofit an old washer or dryer to alert you via text message when the clothes are done.


With the IOT market hot right now, many appliances have applications in this realm. Recently we have seen internet connected cooking appliances and refrigerators. Of all the appliances in a house, the one that has remained mostly the same in its process is the washer and dryer. Most people dread using these machines because like baking, you have to wait and tend to the process when needed. With a washer, if you leave your clothes in there for too long without transferring all the clothes to the dryer, you risk having your clothes start to smell like mold or dry out, in which you have to rewash them. If you leave your clothes in the dryer for too long, they will wrinkle. In which you have to send them for another heated spin. Ideally, the clothes get transferred to the dryer as soon as the washer is done and the clothes are taken out of the dryer and folded or hung as soon as the dryer is done. People are either too busy or don’t hear the buzzer when it's done. These days, people are better at responding to their phone than when the dryer or washer is done. At this point, most washer and dryers only have the capability to remind you using a buzzer or chime which is short and sweet. Easy to forget or not hear at all. To make it life easier, why can’t that buzzer or chime reminder be a text message, something we are all now are very good at responding to.


I based this project on another I did some time ago using a Bealebone, but now it's ported to a Raspberry Pi since the Pi 3 has build in WiFi. I had to try it.


For this project we used a Raspberry Pi 3 to text your phone. Yes, that's all you need to send a text. Most people don’t realize that you can send a text (sms) via email. So by hooking up the Raspberry Pi 3 to wifi and using a email server we can send a text via email. The carriers for cell phone service have provided an easy way to do this.


This website popular mechanics list the ways to do this for most carriers:

It is the same way you address an email: provided in the list below:



Raspberry Pi 3

MMA8452Q 3-Axis Accelerometer

USB Battery Pack (Any external pack will work, here is an OK one.)

MicroUSB Cable

2 Industrial Magnets

1 Rocker switch

1 Panel Mount LED

Project Box



The Schematic:

Pi washer texter schematic.JPG

The schematic is simple. The accelerometer is attached to the Raspberry Pi 3 with four project wires.


The hardest part is OPTIONAL, adding an indicator LED and on/off switch. Technically, you can just plug in the Pi 3 to the USB battery very time you want to use it. But, if you want an easy fire-and-forget kind of device, place in that switch and LED!


The build:

How this is built doesn’t matter. At all.


All I did was slap the components inside a project box (enclosure). It can be inside any shape box it will all fit inside. However, with my build I wanted to mitigate any issue.

- I wanted to mount the accelerometer as ridged as possible inside the box. This is to make sure that most of the movement senses is from the machine it is attached to.

- I used two large rare-earth magnets to make sure it attaches to the washer/dryer as firmly as possible. Since the whole system works off of the idea the machine will have some vibration it can sense, it’s best to make sure it doesn’t get shaken off the machine!

- Portability and temporary use needed to be considered. I didn’t want to attach the sensor system to the machines permanently. I would only use it once a week or so anyway. Then I can turn it off and store it.


For those who want to see how I put it all together, see the following gallery:


{gallery} Raspberry Pi 3 washer dryer texter


The main components are attached to the lid of the enclosure, since it is easier to attach standoffs.


The battery and he magnets are hot-glues to the bottom of the main enclosure compartment.


Although project wires are long, they do not interfere with the battery.


The micro-USB connection that powers the Pi 3 is spliced inside the box for the on/off switch and the LED/resistor.





This is the complete system enclosed in the box and turned on.




We created a wireless box that attaches to your washer or dryer via magnets. There is a switch and LED on the top of the box that let you turn on and off the device and show you an indication whether the box is on or off. When the user is using their washer or dryer, they simply turn on the device before they start the washer or dryer and turn it off when they retrieve their clothes after the washer or dryer is finished with the load. The device works by detecting if the washer/dryer is on or off by reading its vibration. There are of course cycle changes in a washer and dryer that would fool the device into thinking that it is off when the motor stops for up to 30 seconds usually. A timer is implemented into the code to determine if the washer/dryer has stopped for 1 minute. Since a cycle change takes less than 1 minute, it only sends a text after 1 minute of no activity. Ensuring that the washer/dryer is done with that load. If the washer/dryer starts back up within that 1 minute then it continues to read the vibration until 1 minute of no activity to send a text. To measure whether the washer/dryer was on or off the accelerometer measures the X axis of the 3 axis provided. This is because the X axis is the horizontal plane of the surface of the dyer that moves the most.


The vibration of the washer/dryer is a side to side motion and less of an up and down. So we only need to use the X axis for measurement. There is a subroutine that measures out 50 readings in 10 seconds. So that is a reading every 200ms. After 10 seconds of readings, the subroutine returns the current state of the device. It returns whether or not the accelerometer X axis numbers are in range of the baseline which is taken when the device is first turned on and the washer/dryer is off. The 50 readings are compared, then calculated, and it is determined whether the values of X axis are in-range or out-of-range. The in-range values indicate that the device does not detect vibration therefore system mode is in standby mode and waiting for the appliance to start. Once the device detects vibration, the mode is then set to ON and the cycle and timing detection starts. When a cycle ends the device vibration readings will go “in-range” and the cycle check mode starts and the 1 minute timer will start. If no activity, the device will go into Finish mode and send a text. Then go back to standby to wait for another start.


The texting part works by sending an email via the Raspberry Pi 3. Since we are using email, we need an email handling service like gmail to send the email which gets translated into a text by the carrier. To set this up you need an email to login to, for example, in python:

#Assign sender and receiver, X represents the digits of the phone number
sender = ''

receiver = ''


#Next we create the message:
header = 'To: ' + receiver + '\n' + 'From: ' + sender

body = 'Laundry is DONE!'


signature = '- Sent From Rpi'


#Load the gmail server and port into the class “mail”

mail = smtplib.SMTP('',587)


#run a subroutine with your email login and password for your gmail.
          def sendText():      





     mail.login('', 'password’)

     mail.sendmail(sender, receiver, '\n\n' + body + '\n\n' + signature)


Running the sendText() function will send your text with the initialized variables loaded into it.

Wifi connection:  

The python code for this project was written in the Raspbian OS using the python 3.4.2 IDE. VNC Viewer was used to View the Raspberry Pi’s Desktop with VNC server installed on the Raspberry Pi. Once the box is connected to wifi using the Raspberry Pi’s wifi IP address, you can ssh into it using a terminal program like putty or VNC viewer to see the Raspbian Desktop. Typing in “ifconfig” into the terminal gives you the IP address of the Raspberry Pi connected via wifi.

-Screenshot of the Raspbian Desktop, showing python code in python 3.4.2 IDE and terminal

I2C Library:

Python has a couple different libraries to use for i2c communication. For this project we used smbus for python 3.4.2. This requires us to install the python3-smbus package by typing “sudo apt-get install python3-smbus” into the terminal. The project code uses the function calls, bus.write_byte_data(device address, register address, data to write) and bus.read_i2c_block_data(device address, start register, and number of bytes to read). The “bus.” is set = at the beginning of the program, bus=SMBus(1). Which sets the variable “bus” to SMBus(1) for easier writing in the code. The SMBus(1) tells the library we are using i2c bus number 1 to read and write on. The Raspberry Pi uses i2c bus 1 by default. We write to the MMA8452Q chip’s configuration registers to configure the chip for use via i2c bus. Especially the register that puts the accelerometer into active mode so we can read values from the digital output registers to retrieve the acceleration data on the Raspberry pi. “bus.read_i2c_block_data()” lets us read the first 7 registers into an array. We then take the X acceleration data from the X output register and parse out that data into variables.    

Accelerometer Connection:

The accelerometer is powered with 3.3V from the Raspberry Pi and communicates via I2C. The python program writes to the configuration registers setting up how the data should display and configuring the mode you want to use. For this project we used the XYZ mode where the device is pulled from the I2C where the X axis values are translated into g’s (acceleration). The python program reads the values from a register on the accelerometer and all mathematical translation from the pulled values to the units it uses to determine its state is done by the python program.

- Sparkfun MMA8452Q

- Alternative Accelerometer here


Program Running Terminal Screenshots:


The program is run via ssh and executed using “sudo python3”

-Running the Python script from the terminal, displays the hardware and variables being initiated

-Showing the readings, current state, and mode

-Showing the device reading the appliance vibration meaning its ON 

-Starting the 1 minute timer when the values are back in range.

-Checking if the stop of vibration was a cycle change or finished

-Checking timer to see if 1 minute has passed without activity.

-1 minute has passed without activity meaning the laundry load is finished, sending text

Text Received:


  • Screenshot of received text on phone

This project is about a digital picture frame aimed at family members, such as grandparents.


The idea is that parents taking pictures of their children, can easily share those pictures with the children's grandparents by making them appear on the picture frame automatically. In turn, the grandparents can "like" the pictures, letting the children's parents know which pictures are their favourites.


By making use of a specific software platform called, multiple instances of this picture frame can be deployed for various family members, without hassle.


Screen Shot 2017-08-29 at 18.34.39.png




The project makes use of different services. Here's an overview:


Screen Shot 2017-08-28 at 16.51.45.png


The picture frame offers following features:

  • simple user interface to navigate the pictures, start a slideshow or like a picture
  • periodically download pictures from a shared Dropbox folder
  • send push notifications whenever a picture is liked
  • Turn the picture frame's display off every evening, and back on every morning


Let's take a closer look at the software and hardware for this project, and how you can build your own connected picture frame.




The following hardware components are used in this project:


Assembly is super easy, following these steps:

  1. Mount the Raspberry Pi 3 to the Raspberry Pi Touchscreen
  2. Connect the jumper wires from the screen's board to the Pi for power
  3. Slide the Touchscreen assembly through the enclosure's front bezel
  4. Screw everything in place

Do not insert the microSD card or power on the frame yet, as the software needs to be

Image-1 (1).jpg




The complexity of the project is in the software. Let's break it down. makes it simple to deploy, update, and maintain code running on remote devices. Bringing the web development and deployment workflow to hardware, using tools like git and Docker to allow users to seamlessly update all their embedded linux devices in the wild.'s ResinOS, an operating system optimised for use with Docker containers, focuses on reliability over long periods of operation and easy portability to multiple device types.

To know more details about how works, be sure to check out this page: How It Works

Sign up for a free account and go through the detailed Getting Started guide. From there, you can create your first application.


Application Creation


Setting up a project requires two things:

  • application name: ConnectedFrame
  • device type: Raspberry Pi 3


Screen Shot 2017-08-26 at 21.38.55.png


After completing both fields and creating the application, a software image can be downloaded for the devices to boot from. The useful part is that the same image can be used for every device involved in the project. Select the .zip format, which will result in a file of about 400MB, as opposed to 1.8GB for the regular .img file.

Screen Shot 2017-08-26 at 21.38.45.png

Before downloading the image, connectivity settings can be specified, allowing the device to automatically connect to the network once booted. Enter the desired SSID and matching passphrase.


Flashing SD Card


Once the image specific to the application is downloaded, it needs to be flashed to a microSD card for the Raspberry Pi to boot from.


There is a tool available for doing just that, by the same people from, called Etcher. It works on mac, Linux and Windows, is simple to use and gets the job done.

Screen Shot 2017-08-26 at 21.50.54.png


Launch Etcher, select the downloaded image file. Etcher should automatically detect the SD card, all that remains is to click the "Flash" button.


The SD card is ready to be inserted in the Raspberry Pi.


Configuration & Environment Variables


Some raspberry Pi configuration changes are typically made by editing the /boot/config.txt file. allows users to do this via the user interface, by defining Device (single device) or Application (all devices) Configuration Variables.


In config.txt, pairs of variables and values are defined as follows: variable=value


Using the Device/Fleet Configuration, the variable becomes RESIN_HOST_CONFIG_variable and is assigned the desired value.


For example, rotating the LCD touch screen is normally done by appending lcd_rotate=2 to /boot/config.txt. As a configuration variable, this becomes RESIN_HOST_CONFIG_lcd_rotate with value 2.

Screen Shot 2017-08-26 at 18.01.22.png


Another type of variables, are Environment Variables, which can again be defined at application or device level.


Screen Shot 2017-09-03 at 09.57.08.png


These environment variables can be used by the operating system, such as "TZ" which is used to set the correct timezone, but also by scripts.


Following environment variables are used by the connected frame Python script:

  • DISPLAY: display to use for the Tkinter user interface
  • DROPBOX_LINK: link to dropbox shared folder
  • IFTTT_KEY: personal IFTTT webhooks key to trigger notifications
  • DOWNLOAD_INTERVAL_HOURS: interval in hours to download photos from the dropbox folder
  • CAROUSEL_INTERVAL_SECONDS: interval in seconds to automatically switch to the next photo
  • FRAME_OWNER: the name of the person the frame belongs to, used to personalise the "like" notification


Most are to be set at application level, though some variables such as FRAME_OWNER are specific to the device.

The link to the shared dropbox folder ends with "?dl=0" by default. This has to be changed to "?dl=1" in the environment variable, to allow the application to download the pictures.


Application Deployment


I've been developing a Python application using Tkinter to create the graphical interface for the picture frame.

The layout is simple: four interactive buttons (two on each side), with the picture centralised.


Deploying an application with requires some additional files, defining which actions to perform during deployment and which command to use to start it. The full code and accompanying files for this project can be found on GitHub.


You can clone the repository for use in your application, reproducing the exact same project, or fork it and modify it as you desire!


git clone 
cd ConnectedFrame/


In the top right corner of your resin application dashboard, you should find a git command. Execute it in the cloned repository.


git remote add resin


Finally, push the files to your resin project:


git push resin master


If all went well, a unicorn should appear!

Screen Shot 2017-08-26 at 17.55.45.png


In case of problems, a clear error message will appear, telling you what exactly went wrong.




"IFTTT" stands for "If this, then that" and is an online platform that enables users to connect triggers and actions for a plethora of services.


For this particular project, the webhooks service is used to trigger notifications to the IFTTT app on a smartphone.

Screen Shot 2017-08-28 at 21.19.27.png


The trigger is part of the code and needs to remain as is, though the action could be modified to suit your own personal needs.




Enough with the theory, let's see the frame in action!



What do you think? Is this something you could see family members use? Let me know in the comments!


Raspberry Pi Projects - How does your IoT garden grow?

Join Les Pounder as he works on his IoT Garden! Watch him integrate technology into his garden and maintain the health of his favorite plants.

Check out our other Raspberry Pi Projects on the projects homepage

Previous Part
All Raspberry Pi Projects
Next Part




Gardening is a delightful hobby, but it can be a chore and one particularly bothersome job is watering the garden. Water it too often and the plants can die, too little and they can also die! But surely technology can offer a solution to this age old problem? Well yes it can, and in this tutorial we shall be using the Raspberry Pi Zero W, the lower power Pi with added Bluetooth and WiFi, along with two sensors, a soil moisture sensor to check if our garden needs water and an Adafruit Flora UV sensor to measure the ultraviolet index of the sun. This data is then emailed to our preferred inbox via a Gmail account that we can use to send the messages on demand.



Our soil moisture sensor sensor will need an analog to digital converter to convert the analog voltage from our soil moisture sensor into something that the Pi can understand. In this case we shall be using the MCP3008 via an add on board from Rasp.IO called Analog Zero.


So let's get started by looking at the bill of materials for this project.


All of the code, and a detailed circuit diagram can be found on the Github page for this project. (Zip Download link)


Building the hardware Analog Zero

Aside from our Pi Zero W, the main player in this project is the Rasp.IO Analog Zero board, which provides us with an analog to digital converter, the MCP3008. Yes you can buy the chip on its own for only a few dollars / pounds, but the Analog Zero board is a convenient form factor that offers a “less wires” alternative.


Vellemen Soil moisture SensorAdafruit Flora UV Sensor

The two sensors that we are using are a simple soil moisture sensor from Velleman, and an Adafruit Flora UV sensor based upon the SI1145 IC. The moisture sensor is a simple analog sensor, hence the use of the Analog Zero, but the Flora UV sensor uses I2C so we need to have access to those GPIO pins, which luckily the Analog Zero provides.


The Analog Zero will take a little time to solder, and we shall also need to solder the pins for I2C and solder the 3V and GND pins for later. We will also need to solder wires from the Flora UV sensor to attach to our Analog Zero.

Once soldered, attach the Analog Zero to all 40 pins of the GPIO and then connect the sensors as per the diagram.


Diagram of the circuit


Now connect up your keyboard, mouse, HDMI, micro SD card, and finally power up the Pi Zero W to the desktop. You will need to setup WiFi on your Pi Zero W, and make a note of the IP address for future use. Now open a terminal and enter the following command to configure SPI and I2C connections.



sudo raspi-config




Yes we can use the GUI “Raspberry Pi Configuration” tool found in the Preferences menu, but having raspi-config available to us over an SSH connection is rather handy should we need it.



Once inside raspi-config, we need to navigate to “Interfacing Options” then once inside this new menu go to the SPI option and press Enter, then select “Yes” to enable SPI. Then do the same for the I2C interface.




While not strictly necessary, now would be a great time to reboot to ensure that the changes have been made correctly. Then return to the Raspbian desktop. With the hardware installed and configured, we can now move on to installing the software library for this project.


Getting started with the software

We only have one software library to install for this project, and that is a Python library for working with the SI1145 sensor present on the Flora UV sensor. But before we install that library we need to ensure that our Pi Zero W has the latest system software installed. So open a terminal and type the following to update the list of installable software, and then install the latest software.



sudo apt update && sudo apt upgrade -y


With the software updated we now need to run another command in the terminal, and this command will install the Python library for our UV sensor.



git clone



Now change directory to that of the library we have just downloaded.


cd Python_SI1145

Now we need to run an install script so that the library will be available for later use. In the terminal type.


sudo python3 install

This library was designed to work with Python 2 but it installs cleanly and works with Python 3. But if you try out the built in examples you will need to add parentheses around the print statements, in line with Python 3 usage.


We can now close the terminal and instead let's open the Python editor, Thonny, found in the main menu under the Programming sub menu.

Once Thonny opens, immediately save your work as


As ever with Python, we start by importing the libraries that we shall be using.

The first library is GPIO Zero, the easy to use Python library for working with the GPIO. From this library we import the MCP3008 class that will enable us to use the Analog Zero. Our second library is time, and we shall use that to add delays to our code, otherwise the project will spam our mailboxes with emails! Our third library is the SI1145 library that we shall use to read the data from our UV sensor. The fourth, fifth and sixth libraries are used to send emails, the smtplib enables Python to send an email, and the email.mime libraries are used to construct an email.


from gpiozero import MCP3008
import time
import SI1145.SI1145 as SI1145
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

So we now move on and create two objects, one that is used to create a connection to the Flora UV sensor, called “sensor”. The other object is called “soil” and here we make a connection to the soil moisture sensor that is currently connected to A0 (Channel 0 of the MCP3008) via the Analog Zero.



sensor = SI1145.SI1145()
soil = MCP3008(channel=0)



Our main body of code is a while True loop that will ensure that our code runs continuously. Our first few lines in this loop will read the UV sensor and store the value into a variable, UV, which is then divided by 100 to give us a UV index value, which is then printed to the Python shell for debug purposes.



while True:
    UV = sensor.readUV()
    uvIndex = UV / 100.0
    print('UV Index:        ' + str(uvIndex))



In order to get the reading from our soil moisture sensor, we first need to make a new variable called soil_check and in this variable we store the value that is being sent A0 / Channel 0 of the MCP3008. Typically this would be read as a voltage, with 100% conductivity providing 3.3V But in this case the MCP3008 class from GPIO Zero returns a float value between 0.0 and 1.0 With 0.0 being no conductivity, so dry soil, and 1.0 meaning we have perfect conductivity and probably an over watered garden. You will also notice that we round the figure to two decimal places, as the value returned from the soil moisture sensor is quite precise and goes to many decimal places. We then print this value to the Python shell before sleeping for a second. Now for the purposes of testing the delay between checks is rather small, but in real life this delay would be measured in hours.



    soil_check = round(soil.value,2)
    print('The wetness of the soil is',soil_check)



So now that we have the data, let's use it. For this we need an if condition to check the value stored in soil_check against a hard coded value. In my case I used 0.1, but you are free to alter this to suit the plants / garden that you have. In my case I wanted to know if the soil became really dry, so any value equalling or lower than 0.1 will trigger the alert.


   if soil_check <= 0.1:

Now we start to construct the email that will be sent should the alert be raised. The first part of any email is to say who the email is from and who it is being sent to.


        fromaddr = "YOUR EMAIL ADDRESS"
        toaddr = "EMAIL ADDRESS TO SEND TO"

Next we construct our email as a MIME multipart message, in other words we can add more content to our email than a standard email. For this project we use multipart to enable the use of a subject line. But this could also be used with attachments such as video / images. Here we set up with our from and to email addresses, and then we set up the subject of the email.


        msg = MIMEMultipart()
        msg['From'] = fromaddr
        msg['To'] = toaddr
        msg['Subject'] = 'Garden requires water'


The next line we come across forms the body of our email, and it is made up from the readings taken by our sensors. These values are stored as floats in the variables soil_check and uvIndex and we then use concatenation to add them to a string readings which is then stored in the body.


        readings = 'Soil is '+str(soil_check)+'wet and the UV index is '+str(uvIndex)
        body = readings



Then we attach all of the email contents ready to be sent.



        msg.attach(MIMEText(body, 'plain'))



In order to send the message we need to have a connection to the Gmail server.



        server = smtplib.SMTP('', 587)



So we now need to ensure that our connection is secure, so we use Transport Layer Security.





Now let's login to our Gmail account obviously you will need to use your own account.



server.login(fromaddr, "PASSWORD")



Our next step is to create a new variable text which will contain our email message converted to a string.



        text = msg.as_string()



We can now finally send the email using our email address, the address of the recipient, and the text that we have just converted.


        server.sendmail(fromaddr, toaddr, text)



Our last two lines of code close the connection to the Gmail server, and then instructs the project to wait, in this case for 10 seconds, but in reality this value will be much longer, otherwise you will receive lots of email spam!






So that’s it, we have now built and coded the project and it is ready to be tested. To test the code in Thonny, click on the “play” button located in the menu, or press F5. Now as there is no conductivity between the prongs of the soil moisture sensor the code will trigger it to send an email. So check your inbox to see if it has arrived. Once checked, place something conductive between the two prongs and you will see that the output is just printed to the Python shell and no email is triggered. When you are finished press the red stop button to halt the code.


So now that we have code, how can we make it executable? In order to do this there are two steps to take. First we need to add a line to the top of our Python code which instructs Python where to find the interpreter.






With that complete, we now need to go back to the terminal, and we need to issue a command to make the Python file executable from the terminal. The command is.



sudo chmod +x



Now in the same terminal, launch the project by typing






Now the project will run in the terminal, printing output to the shell, and the emails should start to be sent as there is no connection between the two prongs of the sensor.


So how can we have the code run on boot? Well this is quite easy really. In the terminal we need to issue a command to edit our crontab, a file that contains a list of applications to be run at a specific time/date/occasion. To edit the crontab, issue the following command in the terminal.



sudo crontab -e



If this is the first time that you have used the crontab, then it will ask you to select a text editor, for this tutorial we used nano, but everyone has their favourite editor!


With crontab open, navigate to the bottom of the file and add the following line.


@reboot /home/pi/


Then press Ctrl + X to exit, you will be asked to save the file, select Yes.


Now reboot the Pi Zero W and for now ensure the soil moisture sensor has no connection between the prongs. After a about a minute, the project should be running, and your inbox should start to receive emails.



Power down the Pi Zero W, place it in a waterproof container along with a USB battery power source, ensure the soil sensor is out of the box, but keep the UV sensor inside the box, oh and make sure the container is transparent! Place the project in your garden, and make sure the soil moisture sensor is firmly in the ground. Power up the Pi Zero W, and now you can wait for your garden to tell you when it needs watering.


Next time...

In the next blog post in this series, we shall build a system to automatically water our garden when an alert is triggered.

Filter Blog

By date: By tag: