Sunday, September 8, 2013

Driving a Relay using GPIO

The next Raspberry Pi project I am working on is controlling my garage door.  To control the garage door I will need to use a relay.  Unfortunately, I used my one and only, easy to use, and very compact, "Relay Module" with my sprinkler project.  I could order another, but that would take time, and I wanted to get something working over the weekend.

Luckily, I had a pack of 5V relays in my electronics component collection.  I had ordered a 10 pack for $6 off of Amazon some time ago.  (do a quick search for "5V Relay", there are numerous options)
QIANJI JQC-3F(T73) Relay

Controlling a relay from a Raspberry Pi is not as easy as simply connecting it to a GPIO port.  First, the GPIO port is only 3.3V and most small relays require 5V.  Luckily the Raspberry Pi does have a 5V rail we can use, but we need a way to switch that on and off.  That is where the transistor comes in.  Our GPIO port will turn the transistor on and off, which will in turn turn the 5V lead to the relay on and off.

In theory this GPIO -> Transistor -> Relay are all that is needed, but of course we need a bit of protection to not fry the components (or the Pi).  This involves a few resistors and a diode.  The resistors will limit the current, and the diode will wrap the relay to dissipate the back current (a relay is just a coil with a magnet, and coils store energy).  This mess is why the compact pre-built Relay Modules are so very nice!

I found an excellent article, by Kevin Sangeelee, that provides a great explanation and a sample schematic for driving a simple relay.  Kevin describes the use of the diode as:  "The diode in the circuit is there to conduct the current generated by the de-energising coil back across the coil (e.g. when switched off), allowing the power to dissipate more gradually, avoiding a voltage spike." (source)
Schematic for a relay via GPIO on the Raspberry Pi (source)

I did not have all of the exact components listed in Kevin's schematic, but I did have several close components that I traded with, from my electronic component box.  (If you don't have a box for all these various small components, you really should, as you never know when you will need one).  For the transistor I used a 2N2222 A338.  For the relay I used the 5V QIANJI JQC-3F(T73) relay from Amazon.  For the diode I used a generic, nondescript, one I also had in the component box.  With my setup, the 1K resistor was too high to drive my transistor, so I reduced it to a 100 Ohm resistor, and this seemed to work fine.  I also connected up a resistor and LED on the load side, to verify that the relay was functioning, as if the noisy relay clicking wasn't enough.

I then put together a little bit of Python code to produced this fun clicking light show:

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)

try:
    while True:
        print "On"
        GPIO.output(25, GPIO.HIGH)
        time.sleep(.1)
        print "Off"
        GPIO.output(25, GPIO.LOW)
        time.sleep(.1)
finally:
    print "Cleaning up..."
    GPIO.cleanup()

The next step is to connect it to the garage door opener, and then get some open/close sensors so I can tell when the door is open or closed.  Eventually, I am going to write up a proximity application for my cell phone to automatically open the garage door on my way home from work.



Saturday, September 7, 2013

Data Logging with the Internet of Things - Xively

Sensor Graphing

The Raspberry Pi is great for collecting data points from various sensors.  For historical reasons, the sensor values can be stored in some sort of database, and retrieved for later usage.

In an article of The MagPi (Sep 2012), there was a recommendation to use the "Internet of Things" web service COSM to store data points.  COSM also provides the added benefit of graphing features.  Since this Sep 2013 article ran, COSM has been renamed to Xively.
Xively - The Internet of Things

The first step was sign up for a free Developer Account.  Then from the "Development Devices" select "Add Device".  Each device can have numerous data feeds, so I created my device with a generic name of "Raspberry Pi".

To see a sample of various feeds, and graphing options, the following is the feed from my web server.

The next step is to populate the device with data streams called "channels".  Each channel would represent an individual sensor.  The sensors can be added from the web interface, or dynamically added using the Xively API.

Xively has a simple REST based API that is fairly easy to use.  There are also numerous libraries for various programming languages, such as Python, C and Java.  Having a bit of an infatuation with Python, I of course chose to go with the Python library.

Installation of the Xively Python library was fairly easy.  There is a dependency on the external "requests" Python library that has to be installed first, and it does require Python 2.7 or higher.
# Xively Library Installation 
git clone https://github.com/kennethreitz/requests
git clone https://github.com/xively/xively-python
cd xively-python
ln -s ../requests/requests

# verify import throws no errors
echo "import xively" | python

Note: If you get an error about "ImportError: No module named requests.auth", make sure the "requests" python library is installed.
Note: If you get an error about "params = {k: v for k, v in (    SyntaxError: invalid syntax", make sure you are using Python 2.7+.

I put together this simple script for dynamically updating the channels.  I then plugged this directly into the various sensor reading scripts.

#!/usr/bin/python2.7

# NOTE: xively requires Python 2.7+

import sys
import datetime
import xively

API_KEY = "API_KEY"  # set to your API Key
FEED_ID = "FEED_ID"  # set to your Feed ID

if len(sys.argv) != 3:
    print "Usage: {0} <channel> <value>".format(sys.path[0])
    sys.exit(1)

channel = sys.argv[1]
value = sys.argv[2]

api = xively.XivelyAPIClient(API_KEY)
feed = api.feeds.get(FEED_ID)
now = datetime.datetime.utcnow()
feed.datastreams = [
    xively.Datastream(id=channel, current_value=value, at=now)
    ]
feed.update()

This script can then be run with a simple:
./xively-update.py sensor1 42

Although the live graphing options are nice, I also wanted to be able to embed the graph into a web site.  Xively provides an API to do this as well:

The following dynamically generated CPU graph was generated from a simple query URL, which can be embedded into a web site:

Now that I have my sensor data being stored and graphed, the next task will be to extend the Python script to be able to pull the raw data back and perform some trending calculations.




Monday, September 2, 2013

Automated Sprinkler System First Look


Our sprinkler system is now controlled by a Raspberry Pi! Achievement Unlocked.

Raspberry Pi Sprinkler Controller


With a little bit of Python and web development, we can now control the sprinkler system from a simple to use web interface and Google Calendars. The Raspberry Pi controller was actually pretty simple to setup. I simply connected several free GPIO pins to an relay module, connected the sprinkler valves to the relay module, and then control the relay module with a Python script.
8 Channel Relay Module(~$15)

A standard sprinkler system uses a 24 VAC line to power a sprinkler valve. When 24 VAC is applied to the line, the sprinkler valve opens and the lawn is watered. Remove the 24 VAC and the valve closes. Obviously we could not connect 24 VAC directly to the Raspberry Pi, so instead we hide it behind a relay (electrically operated switch) which physically isolates the two circuits.

To build a relay circuit would requires a transistor-resistor-diode-relay. As our sprinkler system has 8 "zones", and each zone would require one of these transistor-resistor-diode-relay circuits, this would have been quite a mess to assemble. Luckily there are numerous pre-built Relay Modules, such as the SainSmart 8-Channel 5V Relay Module for Arduino($15), that come in a variety of sizes to fit one's needs.

To connect the Raspberry Pi to the relay module, connect the 5V GPIO pin to the VCC pin on the relay module, then connect the Ground GPIO pin to the GND pin on the relay module, and finally connect 8 (or as many zones as you have) free GPIO pins to the relay module. Next connect one sprinkler valve line to each relay, and finally connect the common ground line to the other side of each relay. Now the sprinkler valves can be turned on and off from the Raspberry Pi using the GPIO output functions.

Schematic of Raspberry Pi Sprinkler Controller

With some Python, HTML and Javascript I then created a simple web interface that my wife could turn on and off the sprinkler system with.
Sprinkler Control Web Interface

When a zone is activated, the web interface highlights that zone and blinks on/off till the watering program has completed.
Zone 1 Activated

Finally, I wrote a Python daemon that runs in the background, probing Google Calendars. This allows the sprinkler system to be scheduled out in advance. Originally I was using a simple Cron Job scheduler, but I wanted something simple that my wife could also set.

Google Calendar Scheduling

The remote web interface access also allows for a really cool, and obvious, feature. We can now walk out into the back yard, with our tablets / cell phones, and control the sprinkler system right in front of our eyes. Instant gratification.

This remote control capability has led to a silly game that my kids absolutely enjoy. We would turn on a sprinkler zone at one side of the yard, and the kids would run towards it. Then we would turn on the sprinkler zone at the other end of the yard, and the kids would run there. They would enjoy this back and forth game until they were too cold to continue. Oh the sweet, simple things of life.






Remote Control Machines

Remote Control Machines Construction Kit

My loving wife asked me what I wanted for my birthday this year.  I asked for some sort of Legos-like-build-your-own-robot-kit that I could control with the Raspberry Pi, and simple enough that I could build it with my son.  Well happy birthday to me, as she came through with this excellent Remote Control Machines Construction Kit ($46).
It comes with enough pieces and instructions to build 10 different models, 3 electric motors and an infrared remote control.  Inserting the Raspberry Pi should be as simple as swapping out the remote control receiver with a Raspberry Pi and a simple motor controller.





The MagPi

The MagPi Magazine
While out of town, at VMworld 2013, didn't have the opportunity to play with my Raspberry Pi, so instead occupied my free time reading this excellent free Raspberry Pi magazine I found:

The MagPi magazine: The magazine for Raspberry Pi users. Articles cover include coding, robotics, and electronics.

The magazine can be read online, or downloaded as a PDF (preferred).





Sunday, August 18, 2013

Ideas for the Raspberry Pi



A collection of brainstorming ideas that the Raspberry Pi: (in no particular order)

Hardware
  • Turn on / off lights
    • Lights on when you enter and off when you leave room 
  • Sprinkler control
  • Motion detectors
  • Weather monitoring station
  • Security system
  • Garage door open / close
    • Proximity opening
    • Driveway monitoring
  • Day time / night time lighting
  • Sensors Sensors Sensors
    • Temperature, humidity, acceleration
    • Magnetic reed sensors (good for garage doors and windows)
    • Mercury tilt switch
    • Dry contact switch
    • Pressure switch
  • Control relays - for pretty much anything
  • Detect mini fridge being opened (or left opened)
  • Heated toilet seat
  • Monitor summer home / construction

Software
  • Media Center
  • Web server
  • Automated notifications and event reminders (maybe based off of sensors)
  • Broadcasted messages
    • OSD pop up messages on desktops

More
  • Deep freeze UPS monitor
  • Internet sprinkler controller
  • Security system monitor
  • Proximity garage door opener
  • Cubicle entry early warning system
  • Better power options
  • battery powered
  • solar powered
  • directly wiring (bypassing usb)
  • Wifi remote controlled car
  • RC controlled car
  • Laser tag RC cars
  • Christmas lights
  • Security camera system
  • Environmental daily snapshots
  • Spy camera
  • Kitchen recipe station
  • Media center
  • Robot wars
  • GPS tracker for car
  • Car media center





A Better Way To Power The Pi

Generally one powers the Raspberry Pi using a recommended setup of a standard USB Cable (type A to Micro-B), used by many cell phones, connected to a 5V USB wall adapter that is capable of supplying at least a recommended 1000 mA of power, which is then connected to the Micro USB Power port on the Pi.  This works great.  But, are there other ways, that might better fit your particular setup?

USB Cable - Type A to Micro-B
USB Cable - Type A to Micro-B
5V USB Wall Adapter
5V at 1000 mA (or more) USB Wall Adapter

Words of Caution

First, a couple words of caution:

Warning: There is both a Mini and a Micro USB type, and Micro is the one you want. (which is unfortunate because I have a bucket full of Mini USB cables)

Warning: It is not recommended to try and power the Raspberry Pi from a computer's USB port.  The USB spec says that a USB port should supply up to 500 mA of power, which is below the 700 mA requirement for the Raspberry Pi (Type B), and well below the recommended 1 A.  Although, you might be able to get away with it, if you use a Raspberry Pi (Type A) with nothing connected.

USB Powered Hub

As USB devices are connected to the Pi, such as a mouse, keyboard and Wi-Fi adapter (the big consumer), the Pi is eventually no longer able to supply sufficient power and will begin to behave erratically (reboots, power on failure, CPU hangs, CPU stalls).  At this point it is recommended to move the USB devices to a USB Powered Hub.

If you were like me, this initially involved two power adapters connected to the wall, and a mess of wires running to the Pi.  I then found a recommendation that said, if the USB Powered Hub is capable of supplying the appropriate power to each port, you could actually connect the Raspberry Pi to the USB Powered Hub and have only one power adapter connected to the wall.  I immediately tried this, and it worked great!

"It is possible to power the Rpi from a powered USB hub the Rpi controls, but only on 'dumb' devices, that allow the port to supply the full current without waiting for the usb device to ask for it. As the power input of the Rpi doesn't have its data leads connected, there is no chance for a communication loop of some sorts." [source]

GPIO Header

The next trick is you can power the Raspberry Pi directly through the GPIO header.  If you have a project that is not using wall power (like a mobile robot), and is using some type of alternative power supply (like a car battery with regulator), this can be a handy way of powering the Raspberry Pi.  Just make sure you regulate the power to exactly 5V (+/- .25V), and that the power supply can supply the required current.

"As the 5V rail is brought out in the GPIO pins, you can power the Rpi from there too. You should mind however, that those are behind the power protection circuitry, so you should provide your own." [source] 

Checking 5V Power

So how does one tell if you have an adequate power supply?

The Raspberry Pi conveniently includes 2 test points (labeled TP1 and TP2) that you can quickly check the voltage with a voltmeter / multimeter.  Set your multimeter to DC V and touch the red probe to TP1 and the black probe to TP2.  You should see a voltage between 4.75 V and 5.25 V.  If you see negative values just swap your probes around.  Anything outside of this range is bad.  Anything close to the edges of this range may cause problems.

Voltage Test Points
Voltage Test Points

When I test my two Raspberry Pis, I see 4.86 V on one and 4.89 V on the other (both being powered by USB Powered Hubs).

"You should see a voltage between 4.75 and 5.25 volts. Anything outside this range indicates that you have a problem with your power supply or your power cable, or the input polyfuse F3. Anything inside, but close to the limits, of this range may indicate a problem." [source]