Wednesday, December 18, 2013

My 7-Segment Display

I ordered the device from Adafruit. The main reason was to check out getting a second I2C device to work. Here's how I wired it from the Pi:

To get that far I followed the directions at--

I found soldering the 24 tiny pins to connect the display to the "backpack" a trial, but surprise, surprise -- it worked with their example 24-hour clock program first try. I had previously downloaded --


(Do you think they could make the directory names any longer?)

I wanted my clock to display 12-hour/AM/PM time. Here's my rework of the software:

import time
import datetime
import signal
import sys
from Adafruit_7Segment import SevenSegment

def signal_handler(signal, frame): # to stop the clock
    print 'You pressed Ctrl+C!'
    SevenSegment(address=0x70) #clear display
signal.signal(signal.SIGINT, signal_handler)

segment = SevenSegment(address=0x70)

lastHour = -1

print "Press CTRL+C to exit"

# Continually update the time on a 4 char, 7-segment display
  now = # get 24-hour time values
  hour = now.hour
  pm = False
  # Set hours
  if hour != lastHour:   # don't change display
    lastHour = hour
    if hour > 11: # change to 12 hour clock
      hour -= 12
      pm = True
      if hour == 0: # just after midnight
        hour = 12
      if int(hour / 10) == 0:  # turn off leading zero
        segment = SevenSegment(address=0x70)  # turns all digits off
    if int(hour / 10) != 0:    
      segment.writeDigit(0, int(hour / 10))     # Tens
    segment.writeDigit(1, hour % 10)          # Ones
  # Set minutes
  minute = now.minute
  segment.writeDigit(3, int(minute / 10))   # Tens
  segment.writeDigit(4, minute % 10, pm)        # Ones + PM dot
  # turn on colon

  time.sleep(60)    # update in 1 minute -- may be 1 minute slow 

One of the irritations of Python is that a program like this can only be executed from the directory its local "import" file is in. There are ways around this but it's enough to make C language attractive. 

Most importantly, both of my I2C-connected devices still work. And I can add more. From two GPIO pins (3=SLA, 5=SCL), many devices!

Monday, December 16, 2013

More about my Raspberry Pi's Web Site


It now allows someone (with the password) to operate the 8 relays connected by I2C from the Pi. At the moment the relays themselves aren't connected to anything much --  but they could be. It looks like this:
I have one 8-switch Sain relay, but I think that two 16-relay boards would work, too. I adapted code in C language that I found at--

I would have preferred to work in Python but code I've found in that language didn't work for me and I was more interested in results than I was in discovering the problem.

The web site does not send data or commands to the Pi. Rather the Pi uploads data on a scheduled basis and checks for change requests. So whenever the relays are changed (whether directly on the Pi or requested from the web) the then-current settings are uploaded to for display as above. When a change is recorded from the web form (above) a temporary file is written and then queried every 2 minutes from the Pi.

Sunday, December 1, 2013

Housekeeping (Drat!)

In Linux it is seductively easy to install new software packages. Of course, it's also a great convenience. Keeping track of what you've installed (and when) is mostly up to you. I say mostly because the following shell expression is a help:

  dpkg --get-selections | grep install

Unfortunately, this gives you the list in alphabetical rather than date order and it lists all the sub-packages -- not just the ones you actually typed in. My list since June is over 1000 lines long. I mentioned June because just before that I did --

  sudo apt-get -y ??? install

And whatever that was (the "???" bit) corrupted the filesystem on my 16gb SD card ("sudo" can scribble anywhere). So I had to re-download the whole system (using my iMac) on to a spare SD card. I then tried to patch the original filesystem using the fsck command. But it didn't help. Since then I have been pretty good about backing things up (covered in earlier posts). The thing I didn't do was write down each time I did an install or update. Duh. And if you DO keep this record, don't just leave the file on the Pi where it could get lost.

Thursday, November 21, 2013

More About Relays

To further test my 8-device relay I built a little LED flashlight like this:
Then I experimented with connecting the "to relay" contacts to an actual relay. Here is an enlarged view of a relay connector:
I've added text above the 3 terminals: NO = normally open, NC = normally closed. Kind of obvious from symbol on the board. So, if I wired my flashlight to COM and NC then the light is on initially (and only turned off on purpose).

But wired to NO and COM the light is off to start with and and only on when programmed (note the red lines above). Like these Python statements:

  GPIO.output(RelaySw1,GPIO.LOW) # turn SW on


  GPIO.output(RelaySw1,GPIO.HIGH) # turn SW off

Ok, so the LOW and HIGH still seem backwards. But I don't have to worry about the relays being all on at reboot.

Monday, November 18, 2013

My Opto-coupled Relay Board

First I did the simplest possible test -- wired as shown:

Here's my Python test program:

import time
import RPi.GPIO as GPIO

RelaySw1 = 8 # Pi pin 24

GPIO.setup(RelaySw1, GPIO.OUT)

for x in range(4): # tries
GPIO.output(RelaySw1,GPIO.HIGH) # SW on
GPIO.output(RelaySw1,GPIO.LOW) # SW off


And running it makes the first relay click on and off 4 times. Big deal. Before testing the relay with house current I wanted to take advantage of the current isolation that the board provides. After a few dim attempts I finally found this at an Arduino site:

 If you want complete optical isolation, connect "Vcc" to Arduino +5 volts but do NOT connect Arduino Ground.  Remove the Vcc to JD-Vcc jumper. Connect a separate +5 supply to "JD-Vcc" and board Gnd. This will supply power to the transistor drivers and relay coils. 
NOTE: Each relay draws about .08A (80 Ma) when on, so if all 8 relays are actuated the board needs about 8*80 or 640 Ma (.64 amps). In this case a separate power supply for the relay board is required. Connect as in preceeding paragraph. A 5 Volt 1 A supply such as THIS  would be good.

Here's the rewired image (that works):

Next, I tried controlling it from my 8-port I2C chip (I don't have 8 spare GPIO pins). But as soon as I plugged jumper into the inactive I2C pin, the relay closed. Oops! this board is "active low." I.e., LOW (ground) turns them ON. This is apparently not a "bug" but a "feature." Ok, I can work it backwards but I'm left with a start-up problem. Let's say my 8 relays control 8 irrigation valves. And I never want them all ON at the same time. So: my very first bit of start-up code has to set all 8 pins HIGH.

Tricky (see! 

BTW: My Python program above is all wrong. The "SW on", "SW off" comments are backwards!

I2C -- another day.

Friday, November 15, 2013

36: Capturing a Grayscale Image with the RasPi Camera

The raspistill command offers at least 30 command line options but no option to capture a grayscale image. There are considerable advantages to that mode for using a Pi as a security camera.

1. All of the BW info is contained in each single 8-bit pixel (looking at the Green value only gives you 70%).
2. The BW image takes up 1/3rd as much RAM and when you save an image to the filesystem the same JPEG quality is 1/10th the size of the RGB image.

Here's my little program (which assumes you are passing it an RGB file name):

import StringIO
from PIL import Image
import sys

a = len(sys.argv)
if a != 2:
print "Usage: bw name.jpg\n"

im =[1]).convert("L")
file, ext = sys.argv[1].split('.') + 'BW.' + ext, "JPEG")

Thursday, November 7, 2013

More about the Pi Camera and Python 

Some years ago the NY Times asked actual children to write reviews of childrens' books. The selections were assigned randomly. A 12-year-old girl got a book on snakes. Her review is reproduced here in its entirety: "That book taught me more about snakes than I ever wanted to know."

If you want to mess with image files in Python you might get to feel like the 12-year old. After getting the camera installed you then have to get PIL (as a guess, Python Image Library):

sudo apt-get install python-imaging

Then there's the documentation:

77 pages!

Concerning my experience with the camera:

My Python program executes the "raspistill" app to get an image. I've learned how to examine the image file. If you do this, you want to capture an uncompressed image: use the "-o bmp" format.

Anyway, I can detect motion, adjust for low light (to some extent), snap a higher-res image and email a warning to myself. However, I can't do anything practical with this because of the 6" cable on the camera module -- unless I buy a second Pi dedicated to the camera.

Above, my latest device: an 8-switch opto-isolated relay board. I haven't got anything connected yet but I had it clicking on and off within a few minutes.

Sunday, November 3, 2013

Post 34: The Raspberry Pi Camera

I bought my camera from Newark/Element 14 which is the only place I found the minimum $25 price. Then I followed the installation instructions from--

(others available). I also looked at--

Which includes Python code for comparing images -- as for a security camera. As it happens, their code resembles what I would have done if I'd had to start from scratch -- by comparing the same pixel position in successive low-res images. Since the G (green) part of RGB contains 70% of an image's grayscale information, R and B values can be ignored for a motion detection application. Thanks to the Raspi org I got my camera working with very little learning curve pain.

The way one captures an image is with the command line program "raspistill". This app has no Unix-style man page but if you know to execute--

$ raspistill -?

You'll get by.

In my little test program I wanted to learn just how how much difference to expect when there should have been no change at all. Here are the counts for 5 pair-wise comparisons of 120x90-pixel images:

0  d: 29008
1  d: 19889
2  d: 4704
3  d: 256
4  d: 71
5  d: 25
6  d: 15
7  d: 13
8  d: 8
9  d: 3
10  d: 1
11  d: 5
12  d: 1
16  d: 1

sum: 54000

What this means is that out of the total pixel count of 6 images (54,000) nearly 30k were exactly the same, 20k were off by one, etc.

BTW: the 15cm ribbon cable is a real pain. The only place listing longer cables seems to be--

Only from the Netherlands? Give me a break!

Sunday, October 27, 2013

I was wrong about a Linux "memory leak"

A few posts ago I was concerned about the apparent diminishing of available RAM as reported by checking "/proc/meminfo". But then I added this command to my midnight RAM test:

sudo /sbin/sysctl vm.drop_caches=3

Which causes the system to clear memory that is temporarily held -- just in case some data might be accessed again.

So, adding that command makes the MemFree number accurate, but probably lowers the efficiency of the OS slightly.

Duh. (but of course, the "/proc/meminfo" data is misleading)

Saturday, October 12, 2013

Controlling My Pi from the Internet

Back in post 28, I described my method for getting data from my Pi to its web page. That's been working for a few weeks now.

A few days back I added a FORM SUBMIT button that can control how the Pi operates. The new feature is at the bottom of The button is labeled "LED On!".

When that button is clicked PHP code in that page writes a particular value into a data file on that server.

Once per minute the Pi reads that same file -- like so:

while true
  a=`curl --silent --netrc -R ftp://ftp.???.com/data/led`
  if [ "$a" = 'ON' ] ;
   curl --silent --netrc -T web/null ftp://ftp.???.com/data/led
   sudo python web/
  sleep 60

So IF the file named "led" has the magic value "ON" THEN that file is erased AND the associated LED is turned on for 20 seconds. 

Note that the way I did this is rather inefficient -- but it works. If I can turn an LED on then I can control anything else the Pi is connected to -- e.g.:

lights, fans, thermostat, irrigation valves, ...

Of course, I'd have add some security to the web interface.

Thursday, October 10, 2013

Post 31: Expanding the number of IO ports with I2C
(added to a few hours later)

First I bought the MCP23008 8-port expansion chip from Adafuit.

Then I followed the install procedure given in:

(sorry about the line break)

Next I wired up a small breadboard as follows (nothing else on the board):

Here's the pin-out of a plain MCP23008 (there are several variants):

I have a Rev 2 Pi so I ran the following from SSH:

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    

Which shows that the MCP chip is recognized and is at the expected address. Then I ran the command that set pins 0 - 6 as output:

$ sudo i2cset -y 0x20 0x00 0x80

And then I tried this--

$ sudo i2cset -y 0x20 0x14 0x01

Which should light the LED wired from GP0. But nothing happens. And no error messages.

Any comments?

LATER that same day:

I went to the site:

And followed their procedure -- a directory of source written in C.

It didn't work either until I read the comments and made the change for my Rev. B Pi. Then the demo C program worked. However, I find the code obscure. I see how you turn an LED on but (not directly) how to turn it off. Plus, I'd much rather work in Python. Drat!


Sunday, September 29, 2013

Memory Leak?

My Pi runs with the following command in the crontab file

0 0 * * * sh memtest >>stats/memavail

Which means "check and record free RAM every midnight" and where memtest contains:

date "+%D %R"
grep MemFree </proc/meminfo

And here's the memavail data since 9/11:

MemFree:          368780 kB (after reboot)
09/11/13 00:00
MemFree:          206572 kB
09/12/13 00:00
MemFree:          199620 kB
09/13/13 00:00
MemFree:          194668 kB
09/14/13 00:00
MemFree:          191468 kB
09/15/13 00:00
MemFree:          381268 kB
09/16/13 00:00
MemFree:           82852 kB
09/17/13 00:00
MemFree:           15280 kB
09/18/13 00:00
MemFree:           15536 kB
09/19/13 00:00
MemFree:           16552 kB
09/20/13 00:00
MemFree:          368384 kB (after reboot)
09/21/13 00:00
MemFree:          182220 kB
09/22/13 00:00
MemFree:          174812 kB
09/23/13 00:00
MemFree:          170820 kB
09/24/13 00:00
MemFree:          168828 kB
09/25/13 00:00
MemFree:          167620 kB
09/26/13 00:00
MemFree:          166388 kB
09/27/13 00:00
MemFree:          164620 kB
09/28/13 00:00
MemFree:          164124 kB
09/29/13 00:00
MemFree:          163124 kB

So, does the free RAM just diminish until nothing will run? Or will there be a miracle garbage collection when things get tight? My little shell file (memtest) could also force a reboot when memfree got below an arbitrary value. But is it necessary?

Anyone know?

Friday, September 20, 2013

29: Perfect Hindsight

From what I know now I would have made several different hardware choices. For instance:

1. I initially blew off the Adafruit ribbon connector from the Pi's 26 pins to the breadboard. It didn't take long for things to get really messy (and it led to wiring mistakes).

2. Another way to cut the mess: lots of short wire lengths. I'm facing a big re-wire to get sane.

3. Here's a device that has caused me grief -- it won't stay connected:
This DHT22's pins are so fine that they don't make a reliable connection with female breadboard wires. I finally had to tin the pins (VERY carefully). A better choice (for a couple $ more) is the wired AM2302 version:

4. I certainly learned something, but controlling a solenoid with a transistor was a lot more trouble than using a Darlington array -- and the array will do 8 devices:

5., 6. I suppose every Pi beginner starts with buttons and LEDs. I mentioned (back many episodes) that I didn't know that polarity mattered with LEDs, but I got over that. However, the buttons I bought don't stay put on the breadboard. Half the time when I release the button it jumps out of its socket. Luckily, I've learned to control the Pi -- first from SSH and now from a Web page.

I also got some 3-wire spring connectors (hopefully to make reliable connection to stripped wires). That probably works but do they ever waste breadboard real estate.

Wednesday, September 18, 2013

Post 28: How I got my Pi to upload files to the Web

I first tried to "automate" FTP. But that command is oriented toward human (rather than programmed) input. That led me to CURL. I didn't bother to learn what the "c" stands for but the "url" part is obvious. So (in SSH) I typed--

  curl --help

And I got a "command not found"-type message. So then I blindly typed--

  sudo apt-get update # always a good idea


  sudo apt-get install curl

Ha! That worked too.

Then I set up my ".netrc" file. Which looks like this:

login your-user-name-at-yourplace
password your-pw-there

And make it secure (from ls -l .netrc)--

-rw-r----- 1 yourpi yourpi (file length) Sep  3 16:47 .netrc

Then you can enter a curl command like this--

curl --netrc -T file-to-send

And if that works, you can make a bash command file like this--

for i in your-list-of-files ...
 if [ -f $i ] ;
  if [ $i -nt uploadtime ] ; # only send files that are "new"
    curl --silent --netrc -T $i
    echo $i
date >uploadtime # save the time stamp

Then add it to your crontab tasks (to run as often as you need). You need to know about crontab!

Anyway, that's (sort of) how my Pi's data gets to

Wednesday, September 11, 2013

Episode 27: Extending Sensors using Ethernet (CAT5) cable

I bought 4 RJ-45 breakout circuits:
So I hooked 2 of them up to my DHT22 temperature sensor with 50' of 24-gauge CAT5 cable between them:
And it worked.

The DHT takes 3 of the 8 wires, but one is ground (which could be shared).  So I could probably extend 4 devices with one pair of these interface cards. That's way better than using 3-wire electrical extension cords. My 4 plugs cost about $20 with shipping. The 50' CAT5 was $15.

Tuesday, September 10, 2013

There was an old lady Raspberry Pi who lived in a shoe shoebox...


covered up

My wife was tired of the messy-looking wires. So now the Pi resides in its box. From there, it updates its Web page every few minutes (see The states of the water valve and door switch are not currently being reported. The box has only raised the CPU temperature only a few degrees (I cut a dozen holes) but I'm going to add heat-sinks, anyway.

Friday, September 6, 2013

25: RaspBerry Pi — Farm Worker

Here's my current idea for the equipment layout:

The UPS will allow the Pi to ignore momentary power glitches and to shutdown gracefully if the outage lasts more than a few minutes. In case the UPS doesn't signal power failure, the photosensor shown above is a cheap solution.

Everything in the diagram adds up to no more than $300. But the trick to making it reliable will be in the software.

Tuesday, September 3, 2013

My Raspberry Pi will be Controlled from a Web Page

My Rpi now has a web page. It is still very crude and will only be available at my convenience.

The UNIX/Linux cron daemon (runs programs per a schedule) automatically sends sensor updates to the site.


Friday, August 23, 2013

More about Extending Raspberry Pi Sensor Wiring

It's been pointed out (by Ted Hale) that using regular 3-prong extension cords offers the chance of someone plugging an end into a 110V circuit resulting in a fried Pi. So I looked for alternatives.

How about Cat5 (ethernet) cables? They contain 8 wires; generally stranded, in twisted pairs; sometimes shielded; in 22- 24- or 26-gauge. Pre-made cables come with RJ-45 plugs on the ends. Some cables go straight through and some (older?) swap the normal transmit/receive pairs. Straight through is better.

To break out for GPIO/sensor wiring the following neat device is available:

Note that you can connect by either screw terminal or the 8 pins. I've seen prices for these between $8 to $12.

Bulk cable is the best deal. You can cut it to exact lengths but you also need to buy male plugs (50 for $20) and a crimp tool ($20 and up). Prices for 1000 feet of 22-gauge are all over the place — $.10 to $1.50 per foot.

Note: getting a good plug crimp can take some practice.

I'm going to give this a try.

Monday, August 19, 2013

Post 21: Solenoid Success At Last

Thanks to Joe Dohm, my water valve now works! I should have looked up the pins on the transistor. Here's the image Joe sent me from a Fairchild web page:
And here is my revised (and working!) wiring diagram:
It helps to know what you are doing.

A different topic -- and my first practical use of my Rpi:
Several time a week my Frontier-supplied, Netgear-built DSL modem/wifi stops working. The Frontier complaint guy explained my problem as a "feature" rather than a failure. Apparently, there are a limited number of locally-assignable IP numbers and sometimes a number gets reused on a connected device that really hadn't gone away (merely quiet for a while). When the sleeping gadget wakes up the modem doesn't know what to do, so it stops working (forever?). Cycling power to the Netgear fixes things -- but it takes a few minutes and is irritating. Now, I admit that my immediate neighbors and I may sometimes have a dozen computers, phones and tablets connected -- all at once. But, so what?

The solution I dreamed up is as follows:

Leave the Rpi "on" 24/7 running the following BASH script (appended to the .profile file):
 ps ax >/tmp/j
 grep 'python' </tmp/j >/dev/null
 if [ $? -ne 0 ] ; then
   nohup python &
   echo starting DSL test

The first two lines above are to avoid starting another copy of the ping program.

import time
last = 0
res = 9
res2 = 9

def post(msg):
tm = time.strftime("%y, %m/%d:%H:%M:%S")
s = "echo "+msg+": "+tm+" >>stats/DSL"

post("Rpi Up")
while 1:
time.sleep(60) # probably 300 sec. would be better
res = os.system("ping -c 1 >/dev/null")
if res != 0: # internet failed?
    res2 = os.system("ping -c 1 >/dev/null")
    if res2 != 0: # 2nd failure?
       if last == 0: # previously ok
        res2 = os.system("ping -c 1 >/dev/null")
        if res2 != 0: # 3rd fail
  post("DSL Fail") # turn modem off/on!
last = 1
    if last == 1: # just stopped failing
        last = 0
post("DSL Up")

# don't print repeat messages but keep looping

I was planning to attach a 110V switch to the Rpi  to cycle the modem power (see "DSL Fail" line above). But since I started letting this run, have had NO failures. No doubt my pinging is resource-piggy, but they brought it on themselves.  A few lines of code added to the Netgear's software could fix the problem but the Telcos are probably saving bandwidth the way things are.

As mentioned in the code, I probably should increase the sleep time. Also, I chose to ping because the site gave me quick echos. Very casual sampling, however.

Thursday, August 8, 2013

More Solenoid Frustration

Well, I drew a new diagram:
And wired it that way (things spread out):

As soon as I connect the 9V wires the solenoid clicks. Running the program makes no change. Here's my Python code:

import time
import RPi.GPIO as GPIO
Solenoid_pin = 7

GPIO.setup(Solenoid_pin, GPIO.OUT)

for x in range(5): # wait 5 sec
print x
GPIO.output(Solenoid_pin, GPIO.HIGH)
print 'Valve OPEN.'
for x in range(5): # wait 5 sec
print x
GPIO.output(Solenoid_pin, GPIO.LOW)
print 'Valve CLOSED.'
for x in range(5): # wait 5 sec
print x


Nothing tricky. I even tested my GPIO pin 7 with an LED -- worked fine.

Comments, anyone?

Wednesday, August 7, 2013

Raspberry Pi vs. a Solenoid-operated Water Valve

I've had a few problems with GPIO devices up till now, but not like this dratted solenoid. I got mine from Adafruit ($6.95 for plastic). I also ordered the suggested transistor, diode and 9V power supply.. To be extra careful and protect the Rpi from the wrong voltage, I also bought a second breadboard and a multimeter. I wired up the breadboard following (as best I could) the seemingly-identical diagrams below.

(both borrowed from the Web)

Anyway, when I try it, the solenoid activates as soon as I connect the 9V+ and –. Changing the poles of the TIP102 doesn't work.

I need help. Any suggestions?

Thursday, July 25, 2013

Raspberry Pi Status

I've done much of the simple GPIO stuff. LEDs, buttons, temperature sensors, PIR motion sensor, photosensor. I've also learned (the hard way) about protecting the Pi and backing up the work I've done.

Now I'm about to break into transistors, higher voltage and a more interesting device, e.g., a solinoid-operated water valve.

If any of this confuses you, you should scroll back a few episodes in my blog.

Wednesday, July 17, 2013

Raspberry Pi Photo Resistor (light sensor)

I ordered 2 of these a couple weeks ago along with the capacitors listed at Adafruit plus heat shrink tubes and extra breadboard wires. Anyway, these things are so tiny I thought they'd been left off the order. But before complaining, I went through my Pi stuff again and found them.
(a dozen of the sensor bit would fit on a dime)

I had a couple problems getting this device to work:

1. I wired it up like the Adafruit lesson shows (1 mF capacitor and GPIO on the ground side), straight to 3.3V pin on the other side. That didn't work. Looking around some more, I found--

Their example added a resistor on the ground side of the circuit. This eventually worked.

2. My batch of assorted resistors from Radio Shack comes with a list of how many of each kind in the package but the taped-together strips are not labeled. The "pi-spy" interface to the photo sensor added for a 2.2k resistor on the 3.3V side of the circuit. I did a google for "resistor 2.2k" but the color coding shown didn't match anything from my Shack assortment (after a non-trivial search using a magnifying glass). The on-line color-band "calculators" seem difficult, but then I found a "resistor widget" app for my Mac.
The user interface to the widget could be better: you click on the bands repeatedly until it adds up to the value you want. But it's better than the alternatives. Guess what? I found that code among the Shack's jumble.

Here's my Python test program ("adapted" from various sources):

import RPi.GPIO as GPIO, time, os

PHOTO_pin = 22


def PStime (pin):
        reading = 0
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.LOW)

        GPIO.setup(pin, GPIO.IN)
        # Takes about 1 millisecond per loop cycle
        while (GPIO.input(pin) == GPIO.LOW):
                reading += 1
                if reading > 1000: # don't loop forever!
                        return -1
        return reading

for x in range(20):
        print PStime(PHOTO_pin)

The printed results are kind of counter-intuitive. The darker it is, the more loops it takes to get a reading. My setup prints the following values--

  100+ a darkish room
  50     medium interior
  30     light interior
  10     pretty bright

What am I going to use this for? I want my Pi to send a warning if the main 110V power fails. So I'll set it up as follows:

a. UPS backup battery plugged into 110V.
b. Pi and Internet modem plugged into UPS.
c. Photosensor (above) pointed at an LED that's plugged into non-UPS 110V.
d. When external power fails a little Python program (which runs once per minute) notes the sensor change and sends out a text message and an e-mail before shutting itself down.

BTW: Are you familiar with the Linux (and UNIX before it) scheduling service "crontab"? If not, you should learn about it.

Monday, July 15, 2013

Door Sensor Working

I finally got the Magnetic Switch / Door Open sensor working. My wiring isn't "exactly" like anything I saw on the Web.

There are 2 undifferentiated wires out of the device. In the try that worked I connected:

wire 1 to 10K resistor to GND

wire 2 to a GPIO pin (e.g., 25 for code below)

Here's a messy pic:

Here's my crude (but working) Python code:

import time
import RPi.GPIO as GPIO

DOOR_pin = 25 # 1 wire->10kRes->GND, other->GPIO25
LED_pin = 17
GPIO.setup(DOOR_pin, GPIO.IN)
GPIO.setup(LED_pin, GPIO.OUT)

tm = 0
changes = 0
last = 0
h = 0

for x in range(20): # tries
        m = GPIO.input(DOOR_pin)
        if m:  # Mag. sw open detected
                if last != m:
                        GPIO.output(LED_pin,GPIO.HIGH) # LED on
                        tm = time.strftime("%y, %m/%d:%H:%M:%S")
                        print tm #temp -- should log
                if last:
                        GPIO.output(LED_pin,GPIO.LOW) # LED off

        if m==1 and last==0 
                changes += 1
        h += m
        last = m

print "m's:", h
print 'changes:', changes

The 2 halves of the sensor have to be about .5" apart to register "ON" (HIGH).

Now for my photo sensor.

Wednesday, July 10, 2013

My Raspberry Pi — Extending Sensor Circuits

I've been wondering what the best way to do this is — and how far you could go. Here's my inelegant solution:

- I bought a 3' 3-wire extension cord
- I cut the cord part in half
- I also cut 3 M/F breadboard patch wires in half (a black, a red and a yellow)
- I stripped all cut ends (12, in all)
- I soldered the female patch wires to the female half of the of the 3-wire cord
- Ditto, the male with the male
- I chose to color code as follows: red=current, black=ground and yellow=GPIO control
- Heat-shrink tubes and electrical tape finished the job.

Above: female end connected to a PIR motion detector.

After I made sure that the short cord worked I added a 50' 3-wire extension between the 2 plugs shown above.  Guess what? That worked too.

So much for good news — what are the down sides?

1. These cords and plug are heavy and stiff. I have to be careful not to bend patch wire pins.
2. 14-gauge wire is over-kill.

But, so what.

Tuesday, July 2, 2013

After Disaster!

My Raspberry Pi
(if you are new to the site you might want to scroll back a ways)

Lady Bracknell: To lose one parent, Mr. Worthing, may be regarded as a misfortune.
To lose both looks like carelessness.
The Importance of being Ernest,
by Oscar Wilde

Lady B. would have chided me, too. I managed to crash the Linux filesystem on my Pi's SD card. Again! But this time I had a backup image of the entire 16gb card and I have copied individual files back to my iMac, occasionally. But not often enough. My SD image was a month old and the last time I copied files was a week ago.

You might ask, "Why did your Pi's filesystem go bad?" Because I was plugging wires from the GPIO pins to my breadboard while the Pi was powered up. Bad idea! I saw the Pi reboot -- must have grounded a power wire. Afterwards I couldn't talk (via SSH) to the Pi. When I say I "saw" it restart, I mean that the status LEDs went dark and then only the PWR light stayed on. Here's what my LEDs look like, normally:

The REAL info on the Pi's status LEDs:

Anyway, my SD card backup/restore procedure:

From my Mac's Terminal app (PCers use Putty)--

Backing Up

- Shutdown your Pi
- Pull the SD card and plug it into your USB flash memory reader
- Determine what the device name that has been assigned to your SD using diskutil:
   $ diskutil list  (you should be able to tell by the size in GB)
- Then you have to unmount it:
  $ diskutil unmountDisk /dev/disk2 (yours may not be "disk2")
- Now the copy -- you have to be superuser (be very careful):
 $ sudo dd if=/dev/rdisk2 of=raspberry-pi-backup.img bs=1m

Note I copied from the "raw" device (rdisk2) instead of the "block" device -- it's faster. Also, I used "bs=1m" (block size = 1MB), also faster. When I say faster -- the difference for a 16gb SD versus using "bs=1024" is 6 hours!

Restoring (with care you may never have to)

- Plug the same sized SD card into your flash reader (it's good to have a spare)
- Find the /dev name (diskutil list, as above)
- Also like the above, do the unmount
- Now the copy swapping "if" and "of" (in-file & out-file)
 $ sudo dd of=/dev/rdisk2 if=raspberry-pi-backup.img bs=1m

More about the limitations of copying individual files back to the SSH host: You can't usually copy system updates or things like crontab entries. If you don't know about crontab, you should! Try--
  $ man crontab

Wednesday, June 26, 2013

Raspberry Pi GPIO Devices

Disclaimer: I'm a programmer, not an engineer. I've been playing with a Raspberry Pi for the last few months and have learned some things and formed opinions. What I've written below may sound like “information” but it's really just my observations and opinions. Dick Haight, 6/26/13

GPIO devices can be mostly separated as inputs (sensors) or outputs (switches). But first, a few remarks about the practical limits of the Rpi. Here's a picture for Rpi B, rev 2.

The left-most diagram shows the physical pin numbers in the center two columns and what the pins might be used for in the outer columns. The pins (3 and 5) labeled “I2C” can be used to control an I2C add-on bus which can control up to 16(?) more devices. The “SP10” pins are still a mystery, but probably work somewhat like the I2Cs. Pins 8 and 10 can be used for old-fashioned serial I/O (but why not just use USB?). “DNC” simply means “do not connect.”

The middle diagram shows using as many pins for GPIO as possible. 17 is probably enough.

The right-edge Rpi photo shows the 26-pin header plus 8 more possible GPIOs (blue loop). The green line circles the socket for the digital camera ribbon cable.

A word about how many devices an Rpi can reliably handle:
  1. Outputs have negligible software overhead.
  2. Input device overhead is directly related to how often each one needs to be checked. A door-open sensor has to be tested every few seconds; temperature readings could be 100th as often. The photocell (below) has the highest software overhead of the devices listed: many tests .1 second apart.
Basically, a normal mix of a dozen input sensors should be no problem for an Rpi.

Here are some Rpi input sensors that I find interesting:

Temperature/Humidity DHT22, $10

This simple device appears to provide reliable temperature/humidity readings. I also tested the more expensive waterproof thermometer (DS18B20, temp-only); $16. I need to check how long the connecting wires can be and still get accurate readings.

Rpi CPU temperature
According to Asimov's third law of robotics, “A robot must protect its own existence as long as such protection does not conflict with the First or Second Laws.” (which involve protecting people). Therefore, each Rpi has a CPU temperature sensor built in. I read on the Internet that the Rpi can tolerate operating temperatures up to 80C. The testing software should warn (by text message?) at 70C and halt the processor at 75C.

Motion sensor $10
This sensor needs to be tested about every 4 seconds (motion detection seems to stay “hi” for 5-6 seconds. It is supposed to measure out to 25' or so. My device seems to notice movement over about a 90 degree arc. The two adjustment “pots” (green arrows, above) probably change those values.

There is a large variety of these devices. Some ultrasonic, some IR. They cost $25 and up. They typically have a narrow angle of view and a restricted maximum reading.

Digital Camera $30

I haven't looked into this yet, but it could be used as a combo motion-sensor/rangefinder. Or webcam.

Open door/window switch $4

Photocell (power fail) sensor $1
These things are intrinsically analog devices. So the software requires many timed probes (.1 second apart) to get a reading. I hope to use one of these a a cheap way of detecting power failure. Most backup UPSs have a light that goes on when the battery kicks in. Stick a photocell over that lamp and you have a power-fail sensor.

Soil moisture $10
Prices of these things are all over the place. Since the info is analog (voltage leak between the tines of the fork), programming is likely to be like the photocell.

Water level $40
Probably meant for swimming pools. different models can detect up to 12" changes. No code yet for the Rpi. It's another analog thing.

GPS $30
What every traveling Rpi needs. But I don't, for now.

Internet and Text-message inputs
If your Rpi is wifi to a cellphone modem (e.g., Verizon “Mifi”) then it has a phone number and can send and receive text messages – which means that you can control the Rpi from any old smartphone, etc.

Keypad $6
Cheap, but uses a lot of GPIO pins. Why not use a USB device?

Rpi output devices:

LED character displays

Switch 110V AC devices $25
The device shown can handle up to 500W. E.g., operate a fan, etc.

Irrigation control: 8 – 16 valves $150 – 200 (
This is an ambitious device for handling up to 16 water valves. Timing can be controlled by a Google Calendar file in the “Cloud.” Such an irrigation schedule can be modified by the file's owner from anywhere. The 24V power supply ($40) and the actual valves are extra. I believe that this takes 6 of the Rpi's GPIO pins and uses the I2C extension.