Sunday, November 30, 2014

AcuRite Weather Station, Raspberry Pi and a USB interface; Part 1

This is a long drawn out story.  Sorry.  I'm going to go into more detail than I usually do and the project will span more than one blog entry.  That's because it is really complex and deals with stuff that most of us would rather not mess with.  We want to monitor and control our house, not do a dissertation.  But, in this case, you can't have enough background information or advice.  There are things that can happen that you need a minimum of background to overcome.  I hope to give you enough to repeat the project.

It all started when one of my readers asked me if I had looked into a weather station for the house. Well, I had, but there were two problems, the good ones cost a fortune, and the others don't have a lot of capabilities. I was going to buy one of the sensor sets sold by SparkFun. They have a really nice one for about $70 that would do the job pretty well. As luck would have it, I was in Costco drooling over the multi-terrabyte disks and noticed they had a Acu-Rite weather station for $80, display and all. It had a sensor head with windspeed, rainfall, temperature, humidity and wind direction. The console was an LCD color display with a USB output that promised I could plug it into a computer and send data out on the web.


Yes, I left with it.

Heck, I couldn't buy the sensors and assemble them any cheaper, plus I'd have to learn all about reading rain gauges and anemometers.  This sounded like a great deal, and it was.  There was only one thing missing, being able to get the data into some kind of database so I could play with it.  Yes there was some pretty slick software that would upload the data to the AcuRite site, but you all know how I feel about relying on someone else for my data.  Also, the software ONLY runs on a Windows PC.  That means I have to keep a PC running all the time to get the data uploaded.  What?  This is the 21st century people, what's up with keeping a big old power hungry PC running 24/7?

I went looking for solutions and found a couple of interesting things.  A site called Weather Display <link> that had some nice software and a driver for Linux, but the poor developer had recently lost the source to his work <link>, and he wanted $70 bucks for it.  Another one, Valley Information Systems <link> who, it turns out, does the driver for the AcuRite software for the weather station.  V.I.S. had a forum as well <link>, so I prowled it and found out that they didn't have a Linux driver, and basically weren't interested in doing one.  I got this from a long rambling discussion with the author (you know me, I can't shut up) where he flat out told me it wasn't worth his time.  I spent several more hours looking for leads on a Linux driver with no luck at all.

So, I didn't want to spend $70 on a system that the source was being rebuilt from scratch for, and I didn't want to run it on a PC since that would tie up my machine and hook me to a wire 24/7; I guess the only solution was to write something myself.

But, what to do?  I could get a receiver and capture the RF sent from the 5 in 1 sensor I mounted on the roof:


(people tell me it looks like a rabbit setting up there)

I could also buy one of their 'bridge' devices.  This is basically an RF receiver hooked to an ethernet plug through some kind of processor.  This device was listed at $80, the same price as the weather station, and it wasn't even wireless.
It did meet the requirement of not having to have a PC plugged in and tethered to the display though.  I guess it's AcuRite's way of overcoming an obvious shortcoming ... for a price.

Or, I could try and conquer the USB interface to it on my Raspberry Pi.  Since I have years of experience dealing with RF in various forms, what do you think I did?  Right, I decided to hack into the USB interface.

The only problem is that I know exactly zero about USB and how to interact with it ... sigh; here I go again.

A while later, I had learned that there were several ways to interface with USB on the Pi, something called pyusb written in python, but there was so little documentation on it that frankly, I couldn't make heads or tails out of it.  There was libusb that had tons of documentation, but all of it was written in a language I couldn't understand --- USB jargonese.  There was something called libusbx, but it looked exactly like libusb.  There were a ton of examples, but nothing that showed how you could actually get data off the darn thing.  If I wanted to list the devices, I could find an example almost instantly, but actually get some data, basically nothing.

Fine, first I'd play with the USB, and get a feel for what was going on.  Maybe that would give me a few keywords that I could use in a better refined google search.  I learned all about lsusb and several other tools that can enumerate the devices hooked to a machine.  I looked at USB sniffers and how they worked.  I found out that HID stood for Human Interface Device and it had a special driver that was dealt with differently than other USB devices.  I learned all about how to modify udev rules to make a touchpad behave like a joystick; everything except how to get data from this weather station.

I decided to just start playing and see what happened.  I plugged the weather station into the Pi and started looking around.  The very first thing I found out was that a normal user on the Pi, like the user pi, can't read the device that is created when you plug the weather station in.  You can tell if this is the problem; look for the device in /dev and check its permissions

crw------- 1 root root 249, 0 Dec 31  1969 /dev/hidraw0

See, what happens is that the device isn't recognized by udev (the process that watches the USB bus) and it assigned the hidraw driver (the most basic generic driver of this type) to the device.  The hidraw driver defaulted like this can only be read and written to by root.  The situation was that the device would identify itself as a HID device, but it wasn't recognized properly and udev would default to the hidraw device driver.  OK, I started looking for how to use this device.  It turns out there's quite a bit of information on the hidraw driver and how to use it.  So I put together some code and gave it a try.

Nothing worked as advertised.  Nothing.  The weather station might have been assigned the hidraw driver, but it wouldn't act like one to Linux.  That was a bust.  I wrote some code to read the various descriptors from the device and noticed a couple of errors in its implementation that might have been causing the problem, but nothing that could solve the problem.  All of this was running as root on the Pi since a normal user couldn't talk to the device.  Yes, I could change the permissions on the device, but that would only last until it was unplugged.  When the device was plugged back in, the device was created root-only all over again.  I could also set the bit such that the code would run as root, but that could create a monster if I messed up in the code.  I really didn't want to risk that.  And, I was getting tired of dealing with the problems of a default device that wouldn't work, so I decided to conquer that item first.

When dealing with USB, the devices can come and go at will.  When we unplug the device, the system notices it and dismantles the connection to it.  Everything is restored when the device is plugged back in.  Although, the device may come up with a different mount point which means the device name changes.  For example on my Pi, since I don't have a keyboard or mouse, the weather station shows up as hidraw0.  On some other machine it could be hidraw1, hidraw2, whatever the next number after the devices already plugged in happens to be.  That's just the nature of USB.  This stuff works by a set of rules that are in the secret directory /etc/udev/rules.d.

I'm not going to drive you nuts with an in-depth discussion of udev and how it works, but I will tell you how to fix the permission problems so the device can be read by a normal Linux user (not root).

First, you have to find out what the OS sees the device as.  This is logged in the system log when you plug the device in and udev does its thing.  So, plug the weather station into the Pi and do the command 'dmesg'. You're interested in a device from Chaney Instrument, so look in the dmesg output for something like the following:
[    2.399920] usb 1-1.2: new low-speed USB device number 4 using dwc_otg
[    2.536425] usb 1-1.2: New USB device found, idVendor=24c0, idProduct=0003
[    2.538128] usb 1-1.2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[    2.541669] usb 1-1.2: Product: Chaney Instrument
[    3.127499] udevd[156]: starting version 175
[    5.553287] bcm2708-i2s bcm2708-i2s.0: Failed to create debugfs directory
[   12.559829] hid-generic 0003:24C0:0003.0001: usb_submit_urb(ctrl) failed: -1
[   12.561497] hid-generic 0003:24C0:0003.0001: timeout initializing reports
[   12.563452] input: Chaney Instrument as /devices/platform/bcm2708_usb/usb1/1-1/1-1.2/1-1.2:1.0/input/input0
[   12.569076] hid-generic 0003:24C0:0003.0001: input,hidraw0: USB HID v1.11 Device [Chaney Instrument] on usb-bcm2708_usb-1.2/input0
I used the command 'dmesg | grep -i usb' to capture this, and it means the HID USB driver grabbed the device because it is listed as type 3 (HID) in its descriptor.

Edit: A short time after I wrote this, I found a significant problem.  It's all detailed in a later post (I'm working on it right now).  Net, DON'T CHANGE THE COMMAND LINE.  It won't destroy your machine or anything, but it will make the weather station USB interface fail in a really annoying fashion.  Skip down to the description of the udev changes and go on from there

That needs to be fixed, but first a tiny bit about cmdline.txt.  This is used to feed parameters into the Linux boot up process, for example many folk have a cmdline.txt file like this when they first boot their Pi:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

My Pi, before this change looks like this:

dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

I had to remove the console entries for other projects, so the command is smaller.  To stop the HID driver binding to the weather station USB port from happening, add this phrase to /boot/cmdline.txt, but be careful, messing up this line may cause the Pi not to boot back up.

usbhid.quirks=0xXXXX:0xYYYY:0x04

Replace XXXX with the idVendor above and the YYYY with the idProduct above, the 0x04 is HID_QUIRK_IGNORE, leave that alone. Just put the phrase somewhere in the line, you'll see what I mean when you look at it.  It seems the HID driver has allowances for 'quirks', things that just don't work the way you expect them to - like this device.  After I made the changes, my /boot/cmdline.txt looks like this:

dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline usbhid.quirks=0x24c0:0x0003:0x04 rootwait

Edit: This is where you want to pick up again.  Yes, I could have just edited this out and gone on with life, but that isn't fair.  We all make mistakes and admitting them and correcting for it is part of the fun.

Now you need to make a new usb device usable by someone other than root for the weather station, so go to the directory /etc/udev/rules.d (remember that from above) and create a file named 10-local.rules which contains the line:

SUBSYSTEM=="usb", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="YYYY", SYMLINK="weather" MODE="666",GROUP="users"

The reason for the obscure file name is due to the way the file is read. The XXXX and YYYY are replaced with the idVendor and idProduct as described above. This will cause udev to make the device usable by a normal user.   My /etc/udev/rules.d/10-local.rules looks like this:

SUBSYSTEM=="usb", ATTRS{idVendor}=="24c0", ATTRS{idProduct}=="0003", SYMLINK="weather" MODE="666",GROUP="users"

Yours will probably look exactly the same since the vendor and product number won't change.  This rule will set the permission and create a symbolic link in the /dev/directory called 'weather' for the station.  Be careful with the equal and double equal signs; one is a comparison and the other is an assignment.  I fought this mistake for a hour before I noticed what I did wrong.  After you reboot the machine to make it read the changes, take a look at /dev/weather:

lrwxrwxrwx 1 root root 15 Dec 31  1969 /dev/weather -> bus/usb/001/004

The permissions are right and the link is into the USB bus structure.  To test that a normal user can get to the file, do 'hexdump < /dev/weather' while logged in as pi and make sure you get something on the screen.  The reason for hexdump is to prevent control characters from getting to the screen and messing up settings.  You're not really interested in what the data is, just that you can get it.

Once all these usb related changes are done you're all set with an entry in /dev called weather that can be read and written by a normal user.  You can unplug the device and /dev/weather will disappear; plug it back in and /dev/weather will come back.  This is the way it's supposed to work.  I actually did a 'tail -f  /var/log/messages' and watched as I plugged and unplugged the weather station.  It had taken a lot of research and experimentation to get to this point, and I wanted to enjoy it.  DO NOT DO THIS!  I now have a plug on the back of the weather station console that is flaky.  It's ok to unplug it, but don't be like me.

Edit: Note that the hidraw device will still be there, that's a good thing and is explained in a later post.  The new device 'weather' is also there and the permissions are necessary.

So, when do we get to the part about actually reading the darn thing.  Maybe in the next post, but there's much more to come.  We have to get libusb sorted out; that's a story in itself and will probably bore you to tears.  Then we have to discuss how to actually implement a user-space-usb-reader.  That's part of the jargon that I picked up learning about this.  Eventually, we'll actually decode the bit stream the weather station provides; yes, it's a dog gone bitstream.

I promise, I won't take months and months to get the rest of it up, but I don't want to make these too long.

Part 2 of this is now here <link>

Tuesday, November 18, 2014

Raspberry Pi, CherryPy, Process Communication, Part 2

Part 1 of this project is here <link>

Last post I talked about experimenting with a different method of process communication: using HTTP between the processes.  This will allow me to move some of my work to another machine, and increase my ability to monitor the various items.

I got into this mess because of the plethora of different devices and protocols I'm messing with.  Each set of devices has a different protocol, some invented by me, others invented by industry.  If you have two different ZigBee devices that can't talk to each other, you need something to translate in the middle.  This isn't too hard, but it gets complex when you're chasing a bug around and can't poke the pieces to see what happens.  So, I started with my Wemo devices, and added a minimal webserver to the code.  This allows me to talk to and check the status of the switches using a browser as well as a separate process that collects the data.

It turned out to be relatively easy, but I (again) had to learn a new jargon.  I'm finding over and over that the key to doing anything in the home automation realm is the language.  When you look at a library or implementation, be prepared for a few hours with google to understand what they're saying.

CherryPy turned out to be pretty slick.  It works differently than the big servers like Apache, but it can be used pretty easily.  I started off with the CherryPy tutorial and just started adding things I needed until I had a skeleton.  That's described in the last post.  Then I took the skeleton in one window and the existing code in another and started the cut-and-paste process of combining them.  It turned out pretty well.  I have several web-like interfaces to the Wemo code that I can interact with, and so far, it's holding up pretty well.  For example, I have a human interface that is really easy to use; I just type in 192.168.0.205:51001 as a URL and I get back:

Current Wemo Light Switch Status

Front Porch is Off  
Outside Garage Lights are Off  
Cactus Spot Lights are Off  
West Patio Lights are Off  

The status is immediate, meaning I actually send off a UPNP request and get the state.  The buttons work and will operate the lights.  It's basically a tiny web server to control the lights without all the hassle of bringing up Apache and a ton of other things.  Yes, it could be extended to use pictures and really cool looking interfaces, but that wasn't what I was going for, this is a nice side effect.

The machine interface is different.  If I type in 192.168.0.205:51001/status, I get:

[{"cactusspot": "Off"}, {"frontporch": "Off"}, {"patio": "Off"}, {"outsidegarage": "Off"}]

Just the bare essentials: the names of the switches and their states right now.  Notice that I have to type in less characters for the human interaction than I do for the machine interaction?  Yep, that's on purpose, I'm lazy.  If you want to see how lazy I am, I have to type in:

192.168.0.205:51001/pCommand?command=OutsideLightsOn

To turn on a single light with the process interface, and it doesn't return anything because it updates the SQLite3 database I use instead.  Sure, it's a painful thing to do, but who cares?  I don't have to type it, it's constructed by code.  To illustrate how a web page can be constructed, here is the code for the human readable page I put up:

    @cherrypy.expose
    def index(self):
        status = "<strong>Current Wemo Light Switch Status</strong><br /><br />"
        status += "Front Porch is " + get("frontporch") + "&nbsp;&nbsp;"
        status += '<a ><button>Toggle</button></a>'
        status += "<br />"
        status += "Outside Garage Lights are " + get("outsidegarage") + "&nbsp;&nbsp;"
        status += '<a ><button>Toggle</button></a>'
        status += "<br />"
        status += "Cactus Spot Lights are " + get("cactusspot") + "&nbsp;&nbsp;"
        status += '<a "><button>Toggle</button></a>'
        status += "<br />"
        status += "West Patio Lights are " + get("patio") + "&nbsp;&nbsp;"
        status += '<a "><button>Toggle</button></a>'
        status += "<br />"
        return status

The entire page is constructed as a string and just sent back to my browser.  I used the simplest buttons and web techniques I could to make it as easy as possible.  Still, it works and doesn't look bad.  Notice that when you click on a button, it goes for the URL ./wemocommand ?  That's the code that will toggle a particular light.  I also use URL parameters (that's what the '?' is for) because they turned out to be easy to parse out.  I could have made this smaller by using a list, and I may some day, but this is much easier to understand for folk that are trying to copy the idea.  It also makes it simple to code for acting on the incoming HTML request:

    @cherrypy.expose
    def wemocommand(self, whichone):
        # first change the light state
        toggle(whichone)
        # now reload the index page to tell the user
        raise cherrypy.InternalRedirect('/index')

Yes, that's all there was to it.  I already had the toggle() routine to support the old interface and I simply redisplay the first page because it will go get the new state of the switches.  At this point in my experiment, I was beginning to really like CherryPy.

Just to round out this a bit, here is the code for the JSON string return I do for the process interface:

    @cherrypy.expose
    @cherrypy.tools.json_out() # This allows a dictionary input to go out as JSON
    def status(self):
        status = []
        for item in lightSwitches:
            status.append({item["name"]:get(item["name"])})
        return status

Notice that CherryPy already has a JSON translator built in?  Is that cool or what?  All I had to do was get the lights state in a list and then return it.  It makes the code a little hard to understand, but it was so simple to put together.

If you want to see the entire module, it's under the branch wemoHTML in my GitHub repository.  If you haven't figured out how to get to that yet (took me some time), here's a link <link> that should get you directly to it.  The module is wemocontrol.py in the house directory.

I still haven't adapted the other pieces necessary to fully implement the idea.  I have to change the web code (php) that handles commands and also the presentation page for my control web page.  I don't expect to have too much trouble with it, but I'll probably have to learn the meaning of some new words.

Part 3 of this project is here <link>

Saturday, November 15, 2014

Taking Another Look at Process Communication - CherryPy

I've been using SysV interprocess communication between the various processes that control and monitor the devices around the house, and it's been working fine.  But, at some point I'm going to want to separate the processes into different machines.  A Pi for the lights, a Pi for the devices I hope to have somewhere else, and a pet project of mine, a Pi to control the functions of the pool.  SysV doesn't talk between machines.  I can use TCP for this, but I don't want to invent a protocol on top of it, I want something I can just pick up and use.  How about HTTP?

I could bring up a web server on each machine and hook it into the processes that are involved, but that would take a bunch of research.  So I got to looking around and there were two nice solutions, Tornado <link> and CherryPy <link>.  They're both nice, but CherryPy is simpler to use, so I chose it as my first experiment.  Besides, it's cool to be running CherryPy on a Raspberry Pi, ... right?

It came up on the first try using their tutorial and worked.  That looks promising, but what about doing something else besides just waiting for an HTTP request?  How to have several of them running on the same machine talking between processes?  How do I keep track of the various addresses?

In my usual form, I just started writing code to see what would happen.  CherryPy uses a publish, subscribe philosophy, and provides some basic published items.  I subscribed to their 'main' and used that to run my tiny timer, and suddenly, it could do something besides just wait for HTML to come in.  So, I have my timers, the ability to periodically check device status and probably do some other stuff.  Now would be a good time to expand the experiment.

The idea is to be able to communicate with each control or monitor process to see what is going on with a browser from my recliner as well as a running process that accumulates everything for presentation.  Hopefully, this will make it much easier to tell what is going on when something quits working properly.  I hope to use JSON as the data transfer protocol and then we'll be able to read it as well as use it easily in code. Eventually, I want to be able to separate the processes between Raspberry Pi's and have them keep working.  My very own tiny data center setting on a shelf over there somewhere.

But, I'm a bit sick of changing things, breaking them, and not having a clue what I did to break them.  Enter GitHub <link>.  I've put my current Raspberry Pi source on GitHub so I can track changes and back out things that just didn't work well.  I can also create a fork for massive experiments, load them on another Pi and play until it works.  A side effect is that you folk can grab the source without having to copy and paste from a window.  There have been many problems with python and its indentation rules, this should fix that.  Also, if you find a bug, you can fix it and then I can grab it as well.

The latest test of my move to CherryPy is in the file cherrytest.py in the other-stuff directory in my GitHub repository <link>.  The house directory is where I put the code I'm running right now on my Pi to control the house.  When I start testing using CherryPy to communicate, I'll fork off a new version and play there until I can tell if it is going to work out.

My very own little sandbox to play in.

Part 2 of this project is here <link>.

Monday, November 10, 2014

Wemo Light Switches and Intermittent Failures ... Found it!

I have four Wemo light switches operating around the house on outside lights.  You know the ones.  They're the switches that you remember after you get in bed and have the covers pulled up.  In my case, I just grab a phone and turn the darn things off from the bed ... except ...

Every once in a while they don't respond.  This has driven me nuts ever since I got the switches and I'm not alone.  There are other folk out there that have been annoyed by this behavior.  After I simplified my code running the switches <link>, and the problem was still there; I set out to see what the heck was going on.  At first the code would hang waiting for a response from the switches, so I put a timeout on the socket read.

When the inevitable timeout came, I at least had a clue; the switch just quit responding.  So, I caught the timeout and printed the URL that was involved.  A few days later, it timed out again and I discovered that the IP address was ok, but the port number the Wemo was listening to had changed.  There's simply no reason for the port number to change ... unless the switch had done it intentionally.  Naw, no one would do that.

Then, the power failed to my house and everything rebooted.  Fine, I'd wait until it happened again.

One evening, one of the switches failed.  I got an email telling me the switch had gone off line.  Yes, an email.  One of the great things about working on a Pi is that it can do things like this.  I had put code in to send me an email when one of the switches got into this state.  I checked the logs (another great thing) and sure enough, the port number had changed.  A little while later, another switch failed, then the other two as well.  The period of working was roughly three days, and then, the switches would change the port number they responded to.

I don't have definitive proof, but I firmly believe they reboot the switches every three days.  Over time I could probably accumulate evidence to support this, but I don't want evidence; I want the darn switches to work.

What I had done in the code was to set a timeout on the socket receive from a polling request to the switch.  When it timed out, it would send me mail and then my process would exit.  Since the process is controlled by upstart (google it), it would start right back up and rediscover the switches.  Everything should be fine then because the new port number would be recorded and control would be set up correctly.  I actually rebooted the control process to just start over.  Not very elegant, but it worked.  When the four switches went south, the process restarted each time and got control back.

Ha, take that Belkin.

Of course there's a downside.  During the time the process is restarting, there could be a command to the switches missed.  It takes about 30 seconds to discover the switches and get all set up so the window is small, but it's there.  I think I can live with that.  I removed the code that sends mail to keep the changes I make to Miranda to an absolute minimum and have the changes running right now.  After a couple of weeks, I'll know how well it worked out.

It's very important to me to avoid relying on an external service to control something around my house, so things like If This Then That, are not an option.  Sure, I like the Wemo app for checking the lights from town, but I don't want to rely on it.  The Internet is just too flaky, companies change policies, and people like to muck with other people's stuff.  I want control inside my own house.

I'm getting closer now.

Sunday, November 9, 2014

OK, Now I Have a Question I Need Help With

I ran across a forum discussion that got me to thinking <link>.  I was researching (again) measuring power with some non intrusive method when I ran into a typical snarky set of responses to a person showing a possible solution.  The author of the post showed this picture of a clamp current meter and some wiring:
Granted, it looks like it won't measure anything since both lines go through the current clamp, but I'm here to tell you this works.

Yep, if the direction is reversed using a loop in the wire it will measure total current through the two lines.  I actually tried it with a current clamp and some 14 gauge wires to a 220V light bulb in an Edison socket.  As further proof, here's a picture of the wiring inside my smart meter:
Look closely, you can zoom if you need to, but notice how one of the power legs goes through the current transformer in the opposite direction?  Here's another picture of the wires removed from the meter:
One current transformer and two wires to measure the total current being used by my house.  I asked the guy from the power company why they didn't just put the current transformer around the neutral and he said people could avoid part of the bill by referencing to ground avoiding the neutral path.  That actually makes sense in a very unsafe fashion.  There's a number of things you can do with current transformers that I hadn't thought of until now.  You can run both wires through in the same direction and tell if there is current to ground; that's how the GFCI you have in the bathroom works.  You can loop a wire around the transformer and double the voltage out to measure smaller currents.  Heck, there's a bunch of configurations that can help us measure things if we learn how they work.

My question is, how the heck does this work?  I know it does, I've done it, and the meter manufacturer has also.  I just can't get my head around the physics of it.

This also points out how folk on the web jump on someone who is correct and belittle them.  I guess we've all been there some time or other.  The author of the picture showed a heck of a lot more restraint than I would have in the same circumstances.

Saturday, November 8, 2014

Adding a USB Stick to the Raspberry Pi

If you beat the heck out of your SD card on a Raspberry Pi by having code that constantly updates a database, you're eventually going to start having problems with the card.  These little SD cards are tough little critters and (some of them) work really well, but they have a finite life.

I started noticing increased problems with database locks, Occasional corrupted data, the kind of thing that goes along with the SD card starting to fail.  It wasn't a really bad problem, but I don't want to have to deal with a bad problem, so I got one of these:


I picked this particular one after reading about a thousand reviews of various USB sticks and took the plunge for this particular device.  The idea is that I wanted one that wouldn't die in a couple of days, would serve other purposes if I decided to do something else on the Pi, and had enough capacity to be relevant for a long time.  16GB should last me a while on the Pi, and if it became photo storage later, it would handle a lot of them.

I let it set on the shelf for quite a while before I finally decided to use it as the main storage on my Pi.  It's Saturday, I really don't want to dig on the drainage trench I've been working on for two weeks, and the neighbors blocked my driveway with a backhoe, so it's time to do this.

When I went looking on the web for instructions to do this, there were literally thousands of them out there.  Most would work, but I don't want to do most of it on the PC and then stick the device on the Pi and hope.  I was amazed at how many Mac instructions there are; I thought Mac users were all artists that couldn't understand real computers (heh).  But I found a set of simple instructions created by pauly that fit the bill nicely <link>.

Since I'm a coward, I backed up the SD card first, then rebooted the Pi and started down the instructions.  Every single step worked exactly as pauly described, and in about an hour I rebooted using the SD card for the boot partition and the USB card for the main file system.  I didn't do anything about expanding swap space yet, nor did I mess with removing the old file system on the SD card.  Those may become useful at some point, but I don't need to mess with it now.

The Pi booted faster, but that's not very important since I don't boot it very often.  I noticed a slight decrease in load average, and time will tell if I see a decrease in the number of problems I've been having.  It's only been up for a couple of hours so I can't speak from experience yet.

I do need to look at the mount point I used for the usb stick though.  I used the default /dev/sda for it, and if I plug in another USB stick, I may have a problem with the default name.  There's the by-id device to look at and I should use it so the name is constant.  But, for now, I'll just get some experience with the setup and see if it holds together.  That's mostly why I have a backup and also kept the file system on the SD card.

This particular Pi has two XBees on it.  As I mentioned in previous posts, I had to do this because the default Digi network and Lowe's Iris devices don't play well together.  This was the third device I added to the USB buss; so I have a powered hub in place to take care of the fact that my USB buss probably uses more power than the computer that runs it.  I'm currently using one of these:
It has seven ports; I hope I don't need all of them, and came with a power supply that can handle that many devices.  I've been bitten by devices like this that just can't cut it when I plugged in a few power hungry peripherals.  It's really annoying to have to hunt down a power supply when you want to try something.  This little guy has worked well.

So, here's a possibility for you folk that are nearing the failure point of the SD card.  Most people that play with the Pi's don't run them 24x7 for months on end with a database and web server beating on things, so they'll never get to this point.

But, some of us do.