Introduction: Internet of Things (IoT) Extension Lead

About: Geek and total tech head. My age is 1111111.

Hi Makers!

Intro

It's about time I shared this one with you all. This project has been going so long, you would not believe. I started this before our Hack Space existed [2011 ish?], and has continued to be in a transient 'not finished, might finish, needs improvement' state forever. This Instructable will hopefully inspire you to go and do something similar with your own take on what this idea aims to accomplish and/or solve.

Objective

I intended to make a cheap/custom version of a Managed PDU that would monitor your internet connection, and power-cycle your modem/router/gateway device on the assumption that it had crashed, and "turning it off and on again" [the network engineer's favourite cop-out/easy fix!] would fix all that.

History

This project started life as a concept plus a few hastily-bought bits, and the idea was demonstrated at a Bar Camp many years ago in my current home town of Newcastle upon Tyne in England. Since starting the project, I have had the device on show at several Maker Faires and Tech Events of a similar nature, but the servos were simply set to randomly turn on-and-off often enough to impart how the mechanical aspect worked.

Why Servos?

A lot of people have wondered why I chose to use Servos linked to switches instead of, maybe, perhaps, Solid State Relays or something similar. The reason for this is quite simple: Accessibility and safety. This solution means that no-one needs to mess directly with dangerous 240v mains electricity, so it widens the base of Makers that would be able to take on this project, or something similar. It also means you have a neat row of sockets to plug everything in, no messing with double-gang space-wasting sockets. :D

Right, with all that lengthy pre-able out of the way, better get cracking with the project documentation...

Step 1: Gather You Materials

These are the minimal items you'll need to complete this project:

  • 6x 9g Servos
  • 1x 6-Way Individually Switched Extension Lead
  • Copper Wire
    (I think I got mine from a 240v 5A solid-core lighting cable)
  • Hot Glue
  • Small Breadboard
  • 1x Arduino
    (or compatible)
  • 1x Arduino Ethernet Shield
  • 1x Raspberry Pi
  • 1x SD Card
  • USB A to USB B lead
  • Micro USB lead
  • Ethernet cable
    (the sort typically used with printers)
  • Male-Male jumper wires
  • Female-Female jumper wires
  • 5v PSU with USB Port [a.k.a. USB Charger]
    (minimum 1 amp)
  • Red single-core breadboard wire
  • Black single-core breadboard wire

Step 2: Gather Your Tools

The minimum tools you'll need to complete this project are:

  • Wire strippers
  • Small wire snips
  • Needle nose pliers
  • Soldering iron
  • Glue gun
  • Sand paper
  • Sharpie/small permanent marker
  • Drill
  • Drill bit (to fit the copper wire diameter)
  • Windows (Vista/7/8/8.1/10) Computer

Step 3: Prep the Servos

So that the servos will stick to the 6-way better with the hot glue...

  1. Check the position of the servo against the 6-way
  2. Remove the label from the side that will be glued to the 6-way
  3. Roughen-up the smooth plastic surface of the servo body with sandpaper
    (I actually used a Jeweler's Screwdriver...)
  4. Roughen-up the smooth plastic surface of the 6-way
    (Mine was already a matte/rough finish)

Step 4: Position and Fix the Servos

  1. Hold the servo in position on the 6-way
    (This should be in line with the switch)
  2. Mark the position of the servo with a sharpie or small permanent marker
  3. Hot glue the servo in place
  4. Repeat for the other five servos

Step 5: Copper Linkage

This step really does require patience, skill, dexterity...and time...

NOTE: If you prefer 3D printed levers, see the '3D printed levers' step.

  1. Cut a length of copper for the switch lever
    • Roughly double the length and add a bit extra to accommodate the hoop/eye
      (Have a look at the pictures above for guidance)
  2. Bend the lever to shape
  3. Position the lever on the switch to check for good fit between switch and servo
  4. Repeat steps 2 & 3 if necessary!
  5. Cut a length of copper for the link arm
    • Add extra to accommodate the hoop/eye at each end
      (Have a look at the pictures above for guidance)
  6. Bend the link arm to shape
  7. Repeat steps 5 & 6 if necessary!!
  8. Check and mark the position of the link on the servo arm
  9. Drill the arm hole out a bit bigger if necessary
  10. Link all the bits together
  11. Hot-melt glue the lever onto the switch
    (Use a bit of electrician's/masking/whatever suitable tape to hold things in place)

Step 6: 3D Printed Levers

If, instead of the copper-wire levers, you would like 3D printed levers, follow these instructions. It may be good to refer back to the 'Copper linkage' instructions that detail how to create the copper levers, as there is a bit more detail about how to correctly size and position the linkages.

  1. Download the STL
  2. Open in your favourite slicing software
  3. Slice it for your printer
  4. Print out six of them
  5. You may need to drill out the holes to properly accommodate the copper link wires
  6. Make some new linkages out of copper wire
    (If you previously made the other linkages, they won't fit - you may benefit from reading the 'Copper linkage' step about correctly sizing the copper wire linkages.)
  7. Glue the levers to the switches
  8. Switch the switches to the 'on' position
  9. Move the servo arms to the 'on' position
  10. Remove the servo arms
    (First, you'll need to remove a screw from the servo shaft)
  11. Hook the linkages into the servo arm and the lever holes
  12. Re-attach the servo arms

Step 7: Test Your Servos

It will be fine for you to test that all your servos adequately operate the switches, if you hook them up one-by-one.

[Typical] Servo wire colour guide

These 9g servos normally have three wires that come from the motor housing and terminate in a 3-pin female header/connector. The wire colour key is typically as follows:

  • White/Yellow: Signal
    (The signal is a PWM frequency - you can find out more here)
  • Red: +5v/Vcc
  • Black: Ground/GND

NOTE: If you want to be 100% certain, please check the manufacturer's specification/technical sheet for your servo model.

Connect a servo

The following connections will work for the example 'servo sweep' sketch:

  • White/Yellow >> PWM pin 9
  • Red >> 5v power pin
  • Black >> GND power pin

Upload a test sketch

The test sketch you can use is on the Arduino.cc site:
https://www.arduino.cc/en/Tutorial/Sweep

Observe

Keep an eye on the servo as it sweeps through its full rotation. The cheap 9g servos seem not to be very accurate, and don't seem to correctly sweep a full 180 degrees. YMMV! Watch out for the servo 'binding', where it gets jammed by a limitation in the mechanics of your linkage and lever setup. If it binds, you may want to modify the minimum/maximum angles for the servo.

Step 8: Set Up Your Raspberry Pi

Make sure the model you choose has an Ethernet port, so *any* Model B will suit very nicely. I am using a classic Model B v1r1, which has the original board layout with black audio socket and just 256Mb RAM. In this guide, I'm making the assumption you're using a Windows computer, and the assumption you've initially got the Raspberry Pi connected to a Display, Keyboard and Mouse.

  • Install Minibian on an SD card using Win32DiskImager [or equivalent] on your Windows computer
    NOTE: You may need to get an older version of Minibian (as I did) if you use an older Raspberry Pi. I used the version dated 2013-10-13, as this was the last version before it got updated for compatibility with the B+ boards.
    Minibian Home Page
    Minibian Pre-B+ Download
    Minibian Latest Download
  • Plug the SD into your Raspberry Pi
  • Connect other things...
    • Keyboard
    • Mouse
    • Display
    • Network Cable
  • Turn on your Raspberry Pi
    Username: root
    Password: raspberry
  • Expand the partition to fill the SD card
    How-to guide
  • Update the installation
    # apt-get update && apt-get upgrade && reboot

Step 9: Install MQTT Broker

You need a 'Message Broker' [the MQTT server], to which clients publish and subscribe to 'Topics'. In this case, the Raspberry Pi will run the Message Broker, and will also subscribe to the Topics for each of the extension sockets.

Pre-Requitsites

In your Raspberry Pi console, enter the following commands...

cd
apt-get update #always a good idea
apt-get install gcc g++ make #essentials
apt-get install libc-ares-dev uuid-dev daemon xsltproc docbook-xsl #mosquitto

Install MQTT

In your Raspberry Pi console, enter the following commands...

cd
wget <a href="http://mosquitto.org/files/source/mosquitto-1.4.2.tar.gz" rel="nofollow"> http://mosquitto.org/files/source/mosquitto-1.4.2...</a>
tar zxf mosquitto-1.4.2.tar.gz
cd mosquitto-1.4.2
make install
ldconfig
mkdir /etc/mosquitto
cp mosquitto.conf /etc/mosquitto
nano /etc/mosquitto/mosquitto.conf

Uncomment and Update the following lines in 'mosquitto.conf'...

pid_file /var/run/mosquitto.pid
user mosquitto
port 1883
protocol mqtt
listener 9001

...exit the editor and save the file. Next add the 'mosquitto' user - you may need to provide a password. Press enter on any other user fields...

adduser mosquitto
nano /etc/init.d/mosquitto

...add the following code into the empty 'mosquitto' init script...

#!/bin/sh
### BEGIN INIT INFO
# Provides: mosquitto
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mosquitto MQTT v3.1 message broker
# Description:
# This is a message broker that supports version 3.1 of the MQ Telemetry
# Transport (MQTT) protocol.
#
# MQTT provides a method of carrying out messaging using a publish/subscribe
# model. It is lightweight, both in terms of bandwidth usage and ease of
# implementation. This makes it particularly useful at the edge of the network
# where a sensor or other simple device may be implemented using an arduino for
# example.
### END INIT INFO

set -e

PIDFILE=/var/run/mosquitto.pid
DAEMON=/usr/local/sbin/mosquitto

# /etc/init.d/mosquitto: start and stop the mosquitto MQTT message broker

test -x ${DAEMON} || exit 0

umask 022

. /lib/lsb/init-functions

# Are we running from init?
run_by_init() {
	([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
	start)
		log_daemon_msg "Starting Mosquitto message broker" "mosquitto"
		if start-stop-daemon --start --quiet --oknodo --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} -- -c /etc/mosquitto/mosquitto.conf ; then
			log_end_msg 0
		else
			log_end_msg 1
		fi
	;;
	stop)
		log_daemon_msg "Stopping Mosquitto message broker" "mosquitto"
		if start-stop-daemon --stop --quiet --oknodo --pidfile ${PIDFILE}; then
			log_end_msg 0
			rm -f ${PIDFILE}
		else
			log_end_msg 1
		fi
	;;
	reload|force-reload)
		log_daemon_msg "Reloading configuration not supported" "mosquitto"
	;;
	restart)
		log_daemon_msg "Restarting Mosquitto message broker" "mosquitto"
		if start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile ${PIDFILE}; then
			rm -f ${PIDFILE}
		fi
		if start-stop-daemon --start --quiet --oknodo --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} -- -c /etc/mosquitto/mosquitto.conf ; then
			log_end_msg 0
		else
			log_end_msg 1
		fi
	;;
	try-restart)
		log_daemon_msg "Restarting Mosquitto message broker" "mosquitto"
		set +e
		start-stop-daemon --stop --quiet --retry 30 --pidfile ${PIDFILE}
		RET="$?"
		set -e
		case $RET in
			0)
				# old daemon stopped
				rm -f ${PIDFILE}
				if start-stop-daemon --start --quiet --oknodo --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} -- -c /etc/mosquitto/mosquitto.conf ; then
					log_end_msg 0
				else
					log_end_msg 1
				fi
			;;
			1)
				# daemon not running
				log_progress_msg "\(not running\)"
				log_end_msg 0
			;;
			*)
				# failed to stop
				log_progress_msg "\(failed to stop\)"
				log_end_msg 1
			;;
		esac
	;;
	status)
		status_of_proc -p ${PIDFILE} ${DAEMON} mosquitto && exit 0 || exit $?
	;;
	*)
		log_action_msg "Usage: /etc/init.d/mosquitto \{start|stop|reload|force-reload|restart|try-restart|status\}"
	exit 1
esac
exit 0

...configure the init script to run at bootup...

chown root:root /etc/init.d/mosquitto
chmod +x /etc/init.d/mosquitto
update-rc.d mosquitto defaults
update-rc.d mosquitto enable
/etc/init.d/mosquitto start

...and finally reboot the Raspberry Pi...

reboot

Step 10: Set Up the Arduino

In Windows...

  1. Download the Arduino MQTT library
    Arduino MQTT Download Page
    Arduino MQTT Direct Download
  2. Extract the ZIP file contents to the Arduino 'library' folder
    Library Folder Guide
  3. Navigate to your Arduino Sketchbook folder and create an 'IoTExtensionV2' sub-folder
  4. Copy the IoTExtensionV2.ino file from above into the folder

On the Raspberry Pi...

  1. Connect the Raspberry Pi and the Arduino to the same network
  2. Boot up the Raspberry Pi
  3. Log in to the Raspberry Pi [default un: 'root', default pw: 'raspberry']
  4. Type 'ifconfig' to find out the Raspberry Pi IP address
    (The IP address is needed for the Arduino)

On Arduino IDE...

You'll need to set your Arduino board type and make sure the correct USB port is selected so the upload is successful.

  1. Click 'Tools'>'Board'
  2. Choose your Arduino borad type
    (Mine is 'Duemillanove', but yours might be the newer 'Uno')
  3. Click 'Tools'>'Serial Port'
  4. Choose the serial port of your Arduino board
    NOTE: There should be a 'tick' icon next to the active Serial Port.
    (I am assuming it'll be 'COM#' where # some number that is greater than zero.)
  5. Click 'File'>'Sketchbook'>'IoTExtensionV2'
    (The sketch now loads into the Arduino IDE)
  6. Set the Arduino IP address to one that is not used on the network
  7. Set the Message Broker (Server) IP address to your Raspberry Pi IP address
    (Previously noted from typing 'ifconfig' on the Raspberry Pi console.)
  8. Set the 'SERVO_OFF' degrees
    (This '#define' constant is set to 10 degrees by default - adjust to suit your own Servos and Switches OFF position.)
  9. Set the 'SERVO_ON' degrees
    (This '#define' constant is set to 170 degrees by default - adjust to suit your own Servos and Switches ON position.)
  10. Set the 'SERVO_COUNT' constant to the number of Servos on your Extension
    NOTE: The current maximum is FOUR (4) servos. I have hit limitations in the Arduino several times, and have been unable to overcome this one. More than four servos causes the Arduino's connection to the MQTT Broker to repeatedly fail. I see this as odd behaviour, and reckon it is a resource limitation such as RAM.
  11. Click the 'Upload' button
  12. (The sketch now compiles and uploads via USB to the Arduino)

This sketch forms the basis of the 'IoT' of the extension lead - it makes use of the Arduino MQTT library. MQTT is a lightweight publish/subscribe messaging protocol that is used where a 'small code footprint' or low network bandwidth is required.

Step 11: Test MQTT

On the Raspberry Pi console...

  1. Type 'mosquitto_pub -t extension/socket0/isOn -m 1'
    You should see the servo for Socket 1 turn to the 'on' position.
  2. Type 'mosquitto_pub -t extension/socket0/isOn -m 0'
    You should see the servo for Socket 1 turn to the 'off' position.

Try testing the other socket numbers out.

As you can see from the topics above, the subtopics 'socket0', 'socket1'...'socketNNN' are a zero-based representation of the physical sockets. 'isOn' holds the current state of the socket, so zero (0) is 'off' and non-zero (usually 1, but anything other than zero will do) is 'on'.

The topics are designed with scalability and future-proofing in mind. Some other possible parameters could include configurations like setting/getting the servo on/off angles, or current draw of a socket in milliamps (given the right measuring equipment).

Step 12: Power Distribution

The 9g servos may be small, but the little motors still demand a high burst of current (at the start of a move) that is quite demanding and is not ideal for the 5v power rail on the Arduino board. In this step, we'll make a simple 'power distribution' board, which will supply 5v power from the USB PSU directly to the Raspberry Pi, Arduino and Servos.

  1. Chop the USB-A to USB-B cable in half
  2. Strip back the wires
  3. Solder the +5v and GND wires of the USB-A half to the strip board
  4. Solder the +5v and GND wires of the USB-B half to the strip board
  5. Chop the USB-A to Micro-USB cable in half
  6. Strip back the wires
  7. Solder the +5v and GND wires of the Micro-USB half to the strip board
  8. Solder a 10cm length of red solid-core wire to the +5v line on the strip board
  9. Solder a 10cm length of black solid-core wire to the GND line on the strip board
  10. Enclose/seal the circuit board to prevent shorts.
    (I used hot-melt glue.)

This setup will now provide power to the Raspberry Pi via Micro-USB, the Arduino via USB-B and to the Servos via the solid-core breadboard wires.

Step 13: Wrap-up

What Next?

This project is something I see as a small step, or a 'module' in the bigger picture of your 'Internet of Things'. Enabling a bunch of devices with MQTT means you can easily have them all subscribing and publishing to the same message broker(s), so they can all interact.

In this case, you might be going on holiday for a week. In this situation, you'd set your house to 'holiday mode' and certain devices might need to be powered off. This could be done automatically via this IoT Extension Lead.

My plan is to add a Web Server to the Raspberry Pi, along with a secondary 'Web Sockets'-enabled Broker that is bridged to the primary 'MQTT'-enabled Broker. The web pages would also be 'Web Sockets'-enabled and configure the IoT Extension Lead via pub/sub messages.

Final Words...

Well, that was yet another rather epic Instructable. I really hope you enjoyed [at least] reading the project, if not [even better] managing to follow the guide and successfully creating your very own IoT Extension Lead :) At the very least, it should be a little inspiration for you to go and create your own interpretation of this IoT-oriented project.

Happy Making!