Thursday, April 24, 2014

Post 54: More about Ultrasonic Rangefinders (and Arduino)

Back in post 50, I complained about the background load variation of Linux causing me inaccurate rangefinder results. So I bought an Arduino Micro. Since I had worked in C language off and on for 20+ years, that part of the transition was no particular problem. And after a bit of trouble I got my HC-SR04 device yielding more consistent readings than I had gotten from the Pi.

I suppose many Raspberry Pi addicts started with an Arduino -- or maybe not. But there is a vast gap between them:
                                          Raspberry Pi        Arduino Micro
                     CPU speed        700MHz              16MHz
     avail. program memory       200+mb              32k (flash RAM)
                      file system       gigabytes             0
             operating system        Linux                  i/o support, boot loader

And the programming environment exists exclusively on a host computer. On my iMac it's the Arduino.app -- which connects via USB micro plug. This connection provides power, downloader, data-in, data-out and a pseudo console. It all "seems" pretty smooth. Arduino source programs are called "sketches." And they are kept track of conveniently on my Mac. My main problem is that program memory is flash RAM. It (necessarily) persists whether or not power is maintained. Maybe it's my setup (Arduino.app / Arduino Micro) but when I compile and download a new sketch this often fails: download is supposed to do a reset (there is also a button) so the new program can take over, but this doesn't always work. Things hang in "downloading" and other problems. Irritating, but not impossible.


But this is supposed to be a Raspberry Pi blog. 


But No. 2: there are lots of systems that involve Arduinos slaved (wired or wireless) to a Pi.


Wednesday, April 16, 2014

53: I Try the "Prototyping Pi" Shield

As I grew tired of breadboard clutter and pulled out wires, I fell for Adafruit's $16 shield. Here's a pic of my still-messy setup:
The good bit: those screwed-down wires are going to stay put! The adjacent sockets are nice and tight, too.

Small complaints: it would be convenient to have extra screw (or insertion) connectors for GND, 3.3v and 5v. Also, When I screwed patch wires into the out-facing connectors the Pi footprint gets big.

Bigger complaint: Note the drawn-on red arrow and dotted line in the photo: That's the Pi camera ribbon cable. The dotted line indicates the approximate location of the camera socket beneath the shield. Before I added the shield the camera worked. But not after. As you can see, the camera is offset from the motherboard plug. Pushing the shield down twisted the ribbon and scratched off a few ribbon wires. Luckily, I have a spare cable but I'm not risking it with the Prototyping Pi. It's back to ye olde breadboard for me.

Two other thoughts:
1. Before I ever ordered the Pi camera I suspected that that cable was going to be trouble.

2. I take no pleasure in soldering. I would like a better breadboard where adding a new wire doesn't cause two previous wires to be loosened or pulled out. Any of you familiar with ZIF connectors?
ZIF standing for "zero insertion force." PCs used to come with these things so the enterprising could trade up chips when they inevitably got faster, denser or cheaper. ZIFs have fallen out of favor now that manufacturers have realized that upgrading chips diminished computer sales. But I digress.

What I'd like is a ZIF-like breadboard. The little lever above is in the open position. Once the chip was plugged in you you merely push the lever down and, voila, you have a reliable, semi-permanent circuit. Now, my perfected breadboard couldn't be just one big ZIF. Here's an off-the-cuff example:
What do you think?


Monday, April 14, 2014

52: Another Mistake of Mine

Back in post 49 I complained that the breadboard T-connector that I ordered from mpja.com was wired backwards in relation to the breadboard rails. But that was only because I plugged it into the wrong end of the breadboard. The two ends are not symmetrical in relation to the positive and ground rails. So here is a picture of it plugged in correctly:


So, it's a pretty good deal after all. Except for my comments in post 45.

Monday, March 17, 2014

51: Raspberry Pi Audio Out

I had a little battery powered Bluetooth speaker that also had a 3.5mm "Line In" jack. I foolishly expected that to work with the audio out jack on the Pi. But it didn't and I learned quickly that the details of Linux audio are arcane and nasty. So I just bought an earphone plug speaker from Radio Shack for $20. The Auvio brand rechargeable unit works fine for my purposes -- and has a builtin volume dial.

To go with it, I downloaded the "festival" text-to-speech software. It's crude but ok in a 1980s sort of way.

Saturday, March 15, 2014

50: Programming an Ultrasonic Rangefinder
-- revised --

I got the device below from mpja.com.

And I followed wiring and programming advice from--

http://www.raspberrypi-spy.co.uk/2012/12/ultrasonic-distance-measurement-using-python-part-1/

Running their sample program gave consistent results (within 5cm at 5m, within 1cm at 3m). But that was with no load on the Pi. When I ran my 10,000-place pi calculation (code listed in an early post) in the background, I got wildly longer readings -- 5m went to 7m.

Here's my mod of pi-spy code:
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO_TRIGGER = 8
GPIO_ECHO = 7

#print "Ultrasonic Measurement"
GPIO.setwarnings(False) #
# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Send 10us pulse to trigger
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()
while GPIO.input(GPIO_ECHO)==0:
  start = time.time()

while GPIO.input(GPIO_ECHO)==1:
  stop = time.time()

# Calculate pulse length
elapsed = stop-start

# Distance pulse travelled in that time is time
# multiplied by the speed of sound (cm/s)
distance = elapsed * 34000

# That was the distance there and back so halve the value
distance = distance / 2

print "Distance : %.1f cm" % distance

As you can see, the two while loops make this a cpu hog. I suppose I could make 3 readings and keep the shortest one.

Comments?

Added 12/16:

I have tried modifying the process priority of the rangefinder.py script. I tried the Unix/Linux nice(1) command. It was named "nice" because a non-super-user can only lower priority, not raise it. Anyway, didn't help.

I tried the code at--
http://www.raspberrypi-spy.co.uk/2012/12/ultrasonic-distance-measurement-using-python-part-2/

Also, inconsistent. So I finally changed the python script above to do 3 readings and only keep the lowest. That worked pretty well (within 2cm at 2m). But (reasonably) accurate back-to-back readings will be 2 seconds apart. Not much help for a vision-impaired person checking for the next curb.

What I really need is for the ECHO pin to cause an interrupt (instead of the code looping)!




Sunday, February 16, 2014

Post 49: Another Problem with the  mpja Breadboard T-connector
(see post 45)

So, since I'd gone to the trouble of identifying the pin-outs, I decided to use the connector. It's a wonder I didn't burn out my Raspberry Pi!
As you can see from the image above, the connections to the breadboard power rails are reversed from every one of the 4 breadboards I own (including the one that came with the T-connector). I (foolishly) assumed that the T plug would connect Ground to Blue and voltage to Red. Nope. It's backwards. So nothing I tried worked. I wasted a couple hours and luckily I didn't harm my Pi.

Friday, February 14, 2014

48: Clone (or back up) your Raspberry Pi SD card
modified 2/7/2018

I've recently bought my 2nd Pi. This led me to try to make a copy of my Pi-1's SD card. I've been backing up that SD card by moving it to an SD reader plugged into my iMac (by USB). There, I used the Terminal "dd" command to make a literal 16gb copy of the card. When I screwed up the card (stupidly changed a GPIO connection while the Pi was powered up and running) I successfully fixed the SD from the iMac back up. But, in this case, I was copying from and to the same SD card.

When I tried to do the same thing to a different 16bg card it didn't work. The 2 cards did not have exactly the same number of data blocks -- off by 1(?).

After trying that a couple useless times, I went looking for something different. And this is it:

https://github.com/billw2/rpi-clone

This is a different approach.  rpi-clone is a long-ish shell command that runs on the Pi and copies your working SD content to the second card (I moved my USB reader to the Pi).

Advantages:
1. It worked!
2. I didn't have to shutdown the Pi or move its SD card.
3. It was faster than the literal 16gb copy.
4. It can do partial updates to an existing card copy.

Actual rpi-clone command (assuming you named it rpi-clone.sh);

% sudo sh rpi-clone [ -f ] sda

(Assuming that a list (ls command) of /dev/sd* listed "sda")

The only problem I had was that I ran it via the Mac Terminal "ssh" interface. The first time I tried rpi-clone I left it (took 25 minutes) and before I returned ssh had timed out my connection to the Pi -- and that aborted the last question from rpi-clone. The 2nd try, I stuck around.

One further advantage of rpi-clone: The last thing that the command does is unmount the SD copy. But if the copy is for a new Pi system you'll want to make a few changes first. For example: you can change /etc/hostname and /etc/network/interfaces. In another Terminal window you can --

cd /mnt/clone/etc # that's where the new card is mounted
nano hostname # change the name?
...
nano network/interfaces 
...

etc.

Note all of the above has to be run with sudo. Be careful!

Oh, and congrats to Bill Wilson for writing rpi-clone.

Sunday, February 9, 2014

About the DS18B20 Temperature Sensors
{Revised!}

I bought my first one from Adafruit, I followed their wiring plan, and I copied their Python source code. But since the .py program just executes Shell commands I wonder why is Python needed at all? Hers's a .sh file that seems to work just as well:

if [ ! -d /sys/bus/w1/devices ]; then
sudo modprobe w1-gpio
sudo modprobe w1-therm
fi
a=`cat /sys/bus/w1/devices/28num-a/w1_slave` 
b=`expr "$a" : ".*YES.*t=\([0-9][0-9]*\)"`
len=${#b}
if [ $len -ge 2 ]; then
f=`expr $b \* 18 / 10000 + 32` # Note: expr only handles integers
echo $f
else
echo "DS18B20 Read Error"
fi

The above seems to work every time I've tried it. The "28num-a" bit above has to match the unique serial number of your device.

A weakness of the expr command (I wrote the original version in 1975) is that it doesn't do fractional numbers. So instead of--

expr $b \* 1.8 / 1000 + 32


You have to multiply by 18 and divide by 10000 to display Fahrenheit.

The heart of the mystery, though: the Adafruit wiring layout shows GPIO pin 4 connected to the DS's data wire but there is no reference to pin 4 in the code above. Since I want to connect 3 DS18B20s to my Pi, do they each take another pin? Or does the code in "w1-therm" only support a single device?

{Since no one answered my question, I found out for myself: You can read several devices with the modprobe software.}



Another worry: those 2 "modprobe" statements obviously leave something running. You can find it by executing the terminal command "ps -ax" -- and here's the culprit process:

 2980 ?        S     16:05 [w1_bus_master1]

That thing is a relative CPU hog; 16 minutes in about a week. 

Thursday, February 6, 2014

Pi to Human Communication

If you have a Pi set up to monitor sensors then you will want to notify someone when things go (potentially) wrong. Assuming your Pi has Internet access (DSL, cable, cellular 3G/4G hotspot modem) you can program it to send out alerts from the Linux Shell, like so:

E-mail:
echo "Warning: Temp below 35F" | mail -s Temp person@some-mail.com

SMS (text message):
echo "Warning: Temp below 35F" | mail cell-phone-number@gateway-name.com

To get the text message to work you have to know what carrier serves the phone number. There's a list at--

  http://www.sweetnam.eu/index.php/List_of_Internet_to_SMS_gateways

Note: In terms of speed, both the e-mail and the text got to me in under 60 seconds. But people are probably more alert to texts.

Tuesday, February 4, 2014

Irritation with the mpja breadboard I mentioned (touted?) in the previous post

Here's a photo of the T-connector:
The RED and BLUE notations are all mine. I had to buzz all the pins out to identify them (well, the left side row was guess-able, I suppose). No help from the supplier, though. This isn't the only mystery, though. The cabling is non-obvious, too.
The T-connector end of the ribbon is keyed -- but not the Pi end! Luckily, I tested the circuit all the way to the other end of the ribbon. Maybe you can make out the dim "2" (upside down) on the Pi end (meaning even-numbered pin side). I never would have guessed that cable twist.

"Other than that, how did you like the play, Mrs. Lincoln."

Tuesday, January 28, 2014

Post 44: New Stuff

I guess my habit is serious. I just got my second Model B, Rev 2 Raspberry Pi (so I can have a "stable" one and one to mess with).

I received the order from www.mpja.com (mentioned in the previous post). Delivery was quick and everything worked (but the default delivery by UPS Ground is pricey -- I switched to U.S. Mail).

I particularly like the tiny PIR detector -- about 1/2" across, $3.95.
Note that the connector pins point straight back. The whole thing will fit inside a 3/4" OD plastic tube. It lacks adjustment pots but works with my existing software.

Now I've ordered this breadboard and connector:
The GPIO pins are labeled. Plus 3.3v, 5v and Ground are already connected to the edge rails. And unlike other such connectors, only one row of pins are covered up. I could wish it was less than $19.95.

Things I'd like to have:
1. A selection of longer Pi camera ribbon cables. The camera works fine but the 15 cm wire is a pain. 
2. A way to get from the solderless (but easily messed up) breadboard to something secure (if not permanent). Soldering a proto-board will be a chore. Maybe there could be a breadboard that works like a zif connector -- flip the lever and the jumper wires are clamped solidly. Eh?

Thursday, January 9, 2014

Interesting Pi-Related Web Retailers

http://www.mpja.com/
A site with a large variety of interesting stuff, especially sensors -- some that I haven't found anywhere else. These include devices for detecting various kinds of gas leaks. Also seemingly low prices on some items -- e.g.: PIR motion detector for $3.95. They also have a huge variety of power supplies, junction boxes, motors, etc.

http://www.cooking-hacks.com/ehealth-sensors-complete-kit-biometric-medical-arduino-raspberry-pi
As the name suggests, this is a tool for remote medical diagnosis. The site claims that up to 10 biometric sensors can be simultaneously attached. If the patient and doctor both have broadband and webcams then the patient could seemingly have an "office visit" without going to the office. The site claims that the "platform" (their term) is available for order starting 1/7/2014 for 450. Add a well-equipped Pi and the whole remote setup would be under $750. Chickenfeed next to the current market. It also occurs to me that their platform contains all the sensors that one would associate with traditional lie detectors!

. . .

Standard disclaimer: I have no financial interest in either of these outfits and I have no information on their reliability. However, I have ordered a few things from mpja and I will report back if I learn anything interesting.

Wednesday, January 8, 2014

My Pi-Controlled LED Strip Porch Light Project

I bought these online for about $25.
5 meter, 18 watt LED strip and 30 watt 12 volt power supply

I plan to stick the LED strip under the outer edge of the soffit. These things are surprisingly bright. And the length is just right to span my deck, the front door and the steps up on either side. I also ordered (but haven't gotten yet) a new PIR motion detector that is small enough to fit inside a 1" PVC pipe ($1!). I need to recess the PIR to limit its angle of view (otherwise it would be constantly tripped by blowing plants or varmints). The detector will be pointed so it covers someone standing in by the front door. In simplified terms my Pi program will work like this:

Only if it's dark:
  Test the PIR every 3 seconds
  If the PIR has detected motion:
    Turn on the LEDs for at least 30 seconds, continue if there is more motion
         
There is a handy soffit vent to bring out the PIR sensor and 12v for the LEDs. This vent is only about 12' from my Pi. I plan to run 5 22 gauge wires, 3 for the PIR (5v, ground and 3.3v signal) + 2 12v for the LEDs.

As an over-ride to my program sketched above, I have already programmed a web interface that will turn the lights on/off from my iPhone.

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--

http://learn.adafruit.com/adafruit-led-backpack/0-dot-56-seven-segment-backpack

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 --

Adafruit-Raspberry-Pi-Python-Code-master/Adafruit_LEDBackpack

(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:

#!/usr/bin/python
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
    sys.exit(0)
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
while(True):
  now = datetime.datetime.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
  segment.setColon(1)

  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

See

http://raspi-online.info/

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--

http://www.skpang.co.uk/blog/archives/637

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 raspi-online.info 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

and

  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
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

RelaySw1 = 8 # Pi pin 24

GPIO.setup(RelaySw1, GPIO.OUT)

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

GPIO.cleanup()

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 http://arduino-info.wikispaces.com/ArduinoPower)! 

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 bw.py program (which assumes you are passing it an RGB file name):

#!/usr/bin/python
import StringIO
from PIL import Image
import sys

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

im = Image.open(sys.argv[1]).convert("L")
file, ext = sys.argv[1].split('.')
im.save(file + '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:

http://www.pythonware.com/media/data/pil-handbook.pdf

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.