Quantcast
Channel: Desert Home
Viewing all 218 articles
Browse latest View live

Acid Pump - Fine, I Give Up.

$
0
0
I've been working on an Acid Pump system to automate the injection of acid into my swimming pool.  There are a ton of details on this effort on my Swimming Pool page.  Well, it failed again today.  After a few months of perfect operation, all four of the check valves have failed and the pump itself is not priming at all anymore.  I replaced the check valves as they failed and now, the pump diaphragm itself doesn't work any more.  So, either I go through the process of getting the pump replaced again or just give up.

I give up.

That doesn't mean I give up on the idea, just that I'm finally going to give up on the Hanna Dosing Pump.  This darn thing isn't made from material that can withstand the chemicals it is supposed to be designed to handle and does little but fail annoyingly often.  Although it did work for a few months without a problem, I noticed that the stainless steel screws that hold the pump head on are starting to corrode, the steel around the rate control is starting to corrode as well.  The environment is just to harsh for this pump to work over a prolonged period.  Yes, I could do more work to isolate it from the environment, but what the heck?  They advertise a pump that is supposed to work with extremely harsh chemicals and it should do just that.

As my Accounting 101 professor told me a long time ago, there is such a thing as "sunk cost."  That's where you finally realize that putting more time, research, and money into something just isn't worth it and you kiss the previous effort goodbye.  Smack.  Goodbye. Now, I'm back looking at peristaltic pumps.  I didn't like them because the devices can have a failure in the flexible tubing that the rollers use to create the pumping action. This would result in a bunch of acid being released into the pump head destroying that whole section of the device.  That's still a concern, but with a check valve on the pool side where the pressure is and a little help from gravity to allow the acid to drain back into the reservoir when a breech happens, maybe I can get this to work.  The big name in these devices is Stenner, but darn, they are really expensive.  There are other devices, some are available on ebay, mostly for use in aquariums.  I've got some more stuff to learn.

At least the knowledge I picked up on materials and environment can help me tell if something is actually going to work.  I'm going to dismantle the check valves I tried using to see what the heck happened to them.  They are rated way beyond the usage I put them to and worked real well for a short period; there must be something going on I don't understand....yet.  There were four of them in the flow path and they failed differently.  One would allow flow both ways; another plugged up and wouldn't flow at all; two of them would allow a little reverse flow; obviously, there is something odd here.  The problem is that they are small and sealed really well so dismantling them will be a pain.  I have a lead on a check valve that has a barbed fitting on one end and 1/4 inch MPT fitting on the other; that would be perfect for this application, if its construction can withstand the acid.  I can't get enough information on it though so I may have to buy one of the darned things to see how it's made.

Sigh.

Charting Things

$
0
0
I was stumbling around the site where I store my data Cosm.com (it used to be Pachube.com) and noticed that they have updated their charting capabilities considerably.  This made the data on my Detail Usage Charts page mess up, but also added capabilities that I didn't know I had.  I edited this page and was able to display a years worth of data (NICE).

There seems to be some kind of bug though because if I ask for a data using months as a parameter, it takes forever to return the data, whereas if I use 30 days, it returns it quickly.  The charts on my detail page use 365 days as a parameter and it only takes a few seconds.  I can live with that.

They have another chart that will allow you to get the actual reading for any point, but I haven't figured out how to use it yet.  Over time, I bet I will.

Outdoor Temperature

$
0
0
I've had an outdoor temperature sensor for quite a while now.  It's a simple temperature sensor hooked to an Xbee that gets power from a wall wart I picked up on ebay.  The description of this little device is here.  Well, I decided to make it work like it should and actually start measuring the outdoor temperature.  This means I have to enclose it and find a place to mount it that will allow proper operation.

So, I had to build a Stevenson Screen.  At first I had no idea how to do this, then after a few hours of searching and reading I figured out I simply needed a louvered box, painted white, setting somewhere on a pole.  So, I picked a fence post out in the yard and ran a conduit to it.  I mounted a short piece of pipe and installed an outlet.
Above you can see the wall wart a couple of wires and the XBee with its temperature sensor soldered on the side (click on the picture for full size).  I chose to use a wall outlet and regular wall power because I don't want to have to worry about changing batteries every few weeks.  Yes, I could use rechargeables and a solar cell, but those things wear out here in the desert.  Believe it or not, the coating over the top of the inexpensive solar cells used in yard lights turns yellow and starts to flake off in about a year of exposure.  The batteries cook and die after about 8 months; basically solar lights are annoying.  Yes, I could use a good solar cell (with glass) and a lithium ion battery, but pricing those devices and the charge controller that would be required brings the power supply cost to roughly $75.  Conduit and wire ran me around $8.  Additionally, there's not much information on the lifetime of a lithium ion battery in 100+ heat day after day.  Understand my thinking now?

I found several Stevenson Screen projects on the web; one even used flower pot bases which was an intriguing idea, but the cost of those made the enclosure run around $35.  So, I had some scrap wood left over from anther project and decided the good old wooden box painted with glossy white paint would be the best route.  However,  I didn't have enough scrap wood to build a regular Stevenson Screen so I decided to build it in a triangular shape to save wood.  Don't do this.  The angles and complexity of a triangle over a simple 90 degree box drove me nuts.  It did come out reasonably nice though:
There's enough room inside to eventually mount a sensor for humidity and the top is flat so I could mount a wind sensor as well.  The humidity sensor is a good idea, but I would rather sense wind speed and direction from the roof; that will be a complex project that will have to wait for another day.  Since I don't want birds building nests inside this new installation, I lined the inside with aluminum screen wire.  There should be plenty of air flow and the rain can't get through the louvers.  It has several coats of white enamel paint to reflect the sun and limit heating to the minimum so I should have accurate measurements of the air temperature.
 
This is a chart of my temperature recordings over the last 24 hours.  On day one (today), the readings reflect badly because the sensor was in the house, then in the sun, then in the enclosure, but it will be working properly after about noon on July 7th, 2012.


Outdoor Temperature - Holy Cow

$
0
0
It's 9:30AM here and the temperature outside is 110F.  WHAT??  I had no idea it got that hot that early in the day here.  Fine, I've lived here for several years now and lived through 120F plus days and watched the plants shrivel up and die, but 9:30 in the morning and hitting 110 already??

Yes, I checked the temperature against another device with a bi-metal spring and it corresponds.  I also dragged a cooking thermometer out there and put the probe in the shade where it could sample the air temperature - same thing.  So, my outdoor temperature device is working and doing what it's supposed to do; I just don't like the data it's giving me.  That explains why the interior temperature of my barbecue was over 200F before I turned it on yesterday.

I think I'll work on inside projects today.....sigh.

Acid Pump - Back in Service.....Again

$
0
0
A few posts back I declared that I was done trying to make the Hanna Dosing Pump work.  That was a fact, I've just had too many problems with this device and am totally tired of messing with it.  I did some more research and turned up another alternative.  Since there are only two types of pumps that are used for this kind of thing, peristaltic and diaphragm, and diaphragm had too many problems, I went for a peristaltic device.  I found this one that somehow avoided my research the first time:

This is a Rola-Chem RC-25 and comes complete with everything in the picture.  It can handle either chlorine or muriatic acid in the concentrations used for swimming pools.  I normally try to use 30+ percent muriatic acid in my arrangements, so this thing should do the job just fine.  Notice that they provide a brass fitting for the pool injection?  They explain this by illustrating that the tubing should be pushed way down into the pipe so the water flow from the pool pump should dilute and carry it away from the fitting.  This might just work since the flow rate of pool water is many gallons a minute and the pipe is two inches (usually) in diameter, the acid should dilute and move away quickly.

One of the major problems with the diaphragm pump was the force of the fluid motion.  The diaphragm was solenoid operated and really shoved the fluid out hard.  This wouldn't be a problem except for the operation of the various check valves: they were pounded by the movement of the water and that caused the diaphragms in the valves to wear very quickly.  I discovered this by ripping apart several of the valves after they had failed.  There were distinct wear marks on the internal diaphragms that would leak fluids both directions.  This pump produces a relatively gentle flow that will build up to enough pressure to overcome the pools flow and its own check valve quite nicely.

This pump is made of plastic on the entire exterior.  I couldn't find any place that would dissolve in the muratic, so it should stand up better than the last attempt.  It comes with several feet of vinyl tubing to hook it up with.  This led me to a discovery that I wish I had run across earlier: Vinyl is actually PVC.  Yes, vinyl tubing (if it really is vinyl) should stand up nicely to muriatic acid.  The resistance of PVC is lower than other materials, but the tubing will wear out due to exposure in about a year and need to be replaced anyway, so that shouldn't matter.  Also, vinyl tubing is cheap and easy to get; just go the Home Depot, Lowes, or Ace and pick some up.  The pump also uses standard size tubing and fittings that you can get most anywhere; just avoid nylon fittings, look for pvc or vinyl and you should be fine.  The pump tube (the one inside) comes in two materials: Tygon and Norprene.  Tygon is resistant to most chemicals and is used a lot in the food industry.  Norprene is actually a form of Tygon that is specifically formulated to be UV resistant, flexible, and extremely durable.  Rola-Chem recommends the black Norprene for muriatic and the clear Tygon for HCL.  This is mostly because the acid is extremely corrosive and a little leak will mess things up over time; best to be safe.

So, I modified the box I had on the wall holding the Hanna pump and installed the Rola-Chem pump.  This is after running the Rola-Chem into a bucket for a couple of weeks to be sure it worked and I understood how to use it.  I discovered that the pump puts out about a cup (8 ounces, 225ml) every 8 minutes so I'll start out at 10 minutes and see how the acid level holds up in the pool, adjusting as necessary.  I'm not using the timer control on the pump because I want to control the device from my House Controller; I just turned the switch to 'On' and hooked it up.  It was relatively easy since I already had an injection point I installed for the previous pump and the bucket with level sensing has been working fine.  I ran it for a couple of days on water to be sure it didn't leak and the timer controls were working correctly.  Today, it was filled with acid and put into service.  I was surprised how well it worked.  This little device self primes in about a minute and the just rolls away moving the fluid through the tubes.  Yes, I'll have to replace the pump tube twice a year and the other tubing every winter, but that's not a big deal at all.  The internal tube costs about U$20 and the other tubing is less than that (remember, you can get it at Home Depot).  It also needs lubrication periodically; I checked the label on the O-ring lube I use and it should work great.  Just go out every month or so and put some in and it should be fine.  I'll look at everything each time I clean the filters to be sure it's standing up to use.  Here's a picture of the installation:
This pump was larger than the Hanna, so I had to enlarge the box (thank goodness for waterproof glue), but it should work nicely to shelter it from the hot sun and little rain that falls here.  Notice the bottom is open?  This worked well for the last several months.  If it leaks, it doesn't set in the box and corrode things and it gets plenty of ventilation to keep things dry.  There is the occasional spider though.  Here is the injection point:
Notice the check valve?  It's the gray thing that the clear vinyl tubing slips onto.  This check valve was a pleasant surprise also.  It is acid resistant and has a Hastelloy spring inside.  Hastelloy is one of the few metals that is resistant to muriatic acid and hard to find in devices that normal people use.  I chased down the manufacturer and it is available in several configurations from SMC, but they require a minimum U$100 order.  I may pursue getting some of these to keep around if this works out. I didn't use the brass fitting that was supplied with the pump; I just don't trust brass and acid in proximity to each other.  I've had too any bad things happen with that combination.  

I haven't dressed the tubing or tied it down yet.  I want to try it for a week or so first to see how things work out before making it more permanent.  Also, I need to make sure it is easy to change periodically for maintenance.  I don't have clamps all over the place because the peristaltic pump produces such gentle flow that it doesn't look like I need it.  With the heat here and various weather conditions that may cause problems, I will have to watch it over time to see and learn more.  So, right now, the installation looks like this:
I haven't removed all the old tubing and will have to dress stuff up so I don't stumble over it when I go in there, but it works.


Battery Charging - Part 3 (Harbor Freight item 42292)

$
0
0
Part 1 of this project is here, and part 2 is here.

Yes, I'm still working on a good float charger for maintaining my batteries.  See my other posts on this here and here for a recap of the project.  I finally gave up on the LM7805 circuitry that comes with these devices.  The Harbor Freight 42292 charger used to be controlled by a LM317 variable voltage regulator a long time ago.  They probably changed the regulator at some point to lower cost or overcome a supply problem.  However, it originally was a much better device; it even had a variable resistor in it to allow the end user to tweak it a bit to fit his purposes.  I got a clue on this during my searches to get ideas on what to do.  Here is the link to a schematic of the original device (link).  Notice how different it is from the current circuitry?  Just so I have a picture to talk about, here is the schematic from that site:
Back in those days, the wall wart was just a transformer so the diodes to rectify the supply were in the little black box.  IC1 is a LM317 and notice how they set up the resistor array to limit the range of available voltage and have a transistor to limit current?  Nice design that you can find all over the web.

I just duplicated part of this on a small piece of protoboard that I cut to match the size of the existing board.  It came out like this:

I still have a diode in series with the output to prevent problems with reversing the connection to the lead acid battery and used different values for all the resistors than the original had.  The reason I changed the values was purely practical; it's what I had on hand.  Notice that the parts count is a grand total of five?  So, why doesn't the manufacturer do something like this?  I don't have a clue.  So, my schematic looks more like this:

The input on the left is the wall wart's 19 VDC (apx) output; VR1 is a 1K, 25 turn potentiometer I picked up on eBay; R2 is 1.2K; and R3 is 180 ohms.  This gives the charger a range of about 9.6 to 16 or so volts.  To calibrate it, I put a 1K resistor across the output, set it for 13.4 volts and then took the resistor off.  When I hooked it to the battery, it floated the battery up to 13.37 volts over an hour or so and just held it there.

I rely on the LM317 to take care of itself.  It has over current and over temperature protection built in and regulates the voltage quite nicely.  If I discharge the lead acid battery by pulling a lot of current such that the voltage drops down to 12.4 or so, the IC will get hot, but not dangerously so.  Then over time, it charges the battery back up to the 13.4 volt level and just holds it there.

So, since I'm only using the wall wart, plastic enclosure, and heat sink of the original device, did I save any money?  Yes.  The wall wart alone is worth the price I paid for the original charger and the rest of it serves as a platform for the charger I ended up with.  

So far, I've converted three of these devices to the new design and they are chugging away keeping batteries charged.  I chose 13.4 V as the float point based on experience and a suggestion from a helpful person on the Arduino forum; this seems to be the best point to hold the battery without losing water to the charge current.  I haven't had to add any water to any of the batteries yet.  Over time, I'll know if I need to make adjustments to this, but at least now I can.  

Thinking about this a bit, it brings up an interesting point.  This wall wart can supply an amp easily and the output seems to be very good, that means I have just made a variable voltage 1 A supply that can serve various general purpose uses around the house.  The next time they have these on sale with a 20% off coupon I may pick up a bunch of them and stockpile them for later use.  Heck, since the LM317 can work as long as the difference from voltage in to voltage out isn't more than 40 V, I could use it to control the voltage from a 24 VAC transformer like I needed way back in the thermostat project.  I needed 5 VDC from a rectified 37 VDC taken from an air conditioner power supply; this would have saved me about $20 in power supply cost.

Rain - Finally

$
0
0
Late yesterday afternoon it finally rained here.  Oh, there's been slight showers and even a few minutes of real rain, but my area finally got the first real rain since last year.  It started a little after 5PM and lasted a couple of hours.  There was a period of thunder and lightning with heavy, wind driven, rain.  The next morning my rain gauge had recorded an inch and a quarter.  This was a real desert monsoon gully washer.  It was GREAT.

I know, this isn't news to anyone.  This happens reasonably often in the Southwestern desert and isn't considered any big deal - except, this time I was measuring the temperature during the storm.  Below, is a snapshot of the temperatures before and after the storm.  Notice how the temperature was over 110 F when the storm started and dropped to 75 F as the rain progressed.  That's a temperature drop of 40 F, all the way down to something reasonable and comfortable.  I don't remember that kind of fluctuation in other places I've visited.

Of course though, it got up to 105 F today, and as the moisture evaporated from the ground, the humidity shot up.  Now, I remember why I hated Louisiana in the summer...


Swimming Pool Controller

$
0
0
I have an entire page devoted to my swimming pool controller and other devices related to the pool here.  The device works pretty well, but since there are two protocols, (Goldline and my own) and they are real devices, there have been some annoying problems over the period I have been using it.  The problems all stem from the fact that there is no 'on' or 'off' command for the various functions.  They all work like a garage door, you push a button and something changes state.  Push a button, the valve opens, push it again, it closes.  This makes things like turning off the pool light a bit of a problem if you don't know if it is already on.  About a year ago a nice person gave me the command string he was using to turn his pool off, unfortunately it didn't work for my controller, but when I tried it I got an idea I should have come up with a year ago.  Simply look to see if the light is already off, and don't do anything if it is.

Obviously this was too simple an approach for me to come up with when I was developing the controller.  I was getting into loops where I would turn on the light, the delay before the various devices recorded that the light was on was erratic (real devices, remember) and I would issue the command again, thinking it got lost somewhere.  That would make the light turn on, wait a few seconds, turn off, wait a few seconds, turn on, etc.  Annoying at times.  Most of the time everything worked perfectly, but when it got into one of these loops, it might take 10 minutes or so to get out of it.  So simple code like: if (light already on) don't do anything, should fix the problem

Guess what?  It did.

I modified all my pool commands to work this way and the pool controller is very reliable now.  I got the idea when I started working on a controller for my garage doors.  I hate getting a few miles from home and suddenly starting to worry that I left the garage door open.  There is little risk of theft out here in the desert, but I hate having a squirrel move into the garage and a dozen or two cactus wrens deciding it's a nice place to live.  I had a squirrel cause some damage once and I don't want to repeat that.  So, I need to know if the door is open and close it.  I came up with a design where I'll put a magnetic switch on the door and that way I'll know when the door is open and can close it from far, far away.  This made me realize that I have the status of the various controls on the pool already, why not just use them.

There was also the problem of ambition, it worked mostly OK, why fix it?  This lethargy went away when my new, variable speed, permanent magnet, super motor died.  Yes, it died.  It developed some kind of fault and declared, "Emergency Stop in Effect."  Nice informative message.  I called Hayward and they said they'd have to send out a repairman.  The first comment out of my mouth was, "How much is that going to cost?"

"Nothing." was the reply.

Sure enough a nice guy came out, looked the problem over, and REPLACED THE ENTIRE PUMP.  Yes, I got an entirely new pump with zero hours on it as a warranty replacement.  How cool is that?  I hooked my controller up and was annoyed immediately by the toggle action.  That's how I came up with the idea and implementation.  While I was making the changes to the code, a couple of bugs turned up that I didn't encounter before and they got fixed as well; nice side benefit.

I'm waiting for parts to come in for the garage project, but thinking about it, there's a few lessons to learn here.  1. Never give up on an idea, let it percolate a while and a solution might appear.  2.  Don't be afraid to call the manufacturer for advice; you may get a really good response.  3.  some other project may suggest a better way to do something; don't ignore it.  4.  DIY projects are never really done, they just settle down for a while.

Power Washer - Frustration in Action

$
0
0
I've talked to my various neighbors and some other folks around my parts about power washers and they all agree, unless you get an expensive commercial or prosumer version, they fall apart too easily.  All but one of my neighbors have trouble with the basic consumer models for a number of reasons.  1. the stupid bayonet fittings wear out and start to leak.  2. hose connection to the washer leaks.  3. leave them out in the desert sun and the plastic lances get brittle and break.  4. the plastic nozzles wear out in a few months.  5. Hoses are stiff and hard to use.  We all like the electric models because of the small engine problems.  If you don't use a gasoline engine often, they develop problems and won't work when you need them.  Electric washers just work and give little trouble with the motor and pump.

Even with all the disadvantages, the $100 price tag (on sale) makes them too attractive to turn down if you need one, and in the desert with limited water, you need one.  For the past years I've bought one every two years because of the various problems.  Then I decided to just replace the various parts as they broke to see if it would save money.  It didn't.

The replacement lances don't fit well and fall apart faster than the factory original.  Even if you change brands, they are pure junk and work until you get about half way through a job then fall apart.  I had one turbo nozzle replacement blow apart the first time I turned the washer on.  Basically, the various manufacturers supply shoddy devices.

Notice how I keep running into this?  I know I'm not alone, but many people just put up with it or give up and hunt for some other solution to whatever device fails them.

I decided to see if I could overcome this problem.  Since most of the problems are with the lances and nozzles, suppose I got a good lance and put it on the washer?  The good lances are metal (brass and stainless), cost about the same as the factory replacement plastic, and are tough as nails.  So, after much research, I discovered that most power washers have a common fitting: an M22 female.  That means I can get a hose, pressure trigger (the gun part), extension and nozzle to replace the junk the manufacturers provide.  Since the lance and hose will last essentially forever, I should be able to move it from one washer to another as I wear the motors and pumps out.  The motors and pumps are too expensive to replace, cheaper to buy a new washer on sale and toss the old one; along with the junk plastic bayonet connected lances.  Here's the lance that blew apart the first time I tried it:
There are screw fittings on each end of the extension that you screw one of the various adapters on to match your existing pressure trigger and the turbo nozzle (big thing in the picture) screws into the other end.  In my experience, each connection leaked.  Yes, all of them.  The threads are plastic and not cast well so they leak a small amount, and the bayonet fittings almost match the device, but the small difference causes leaks.  When I put it together and attached it to my washer, the entire front of the turbo nozzle blew off across the yard.  Clearly, this device is not made to be used, just sold to unsuspecting folk like me.  And, no, it isn't because my power washer is to strong for this tool; I currently have a Powerwasher Weekender (google it) that I picked up for less than $100 at Home Depot on sale and it only gets up to around 1800 pounds on a good day.  Its one of those low pressure machines for consumer use.  Ever notice how they call us consumers?  It's like we don't contribute to society at all; we're just here to buy their somewhat inferior devices.  

A little searching on line and talking to a guy that has a huge commercial power washer, I thought I had a solution.  I'd buy a mid grade setup for everything from the connection on the washer to the nozzle on the end.  Then over time I may change the washer several times, but the hose, lance, and nozzle would work for many years.
This is the hose, pressure trigger, and extension.  Notice that the extension is stainless and has brass fittings on each end; they won't die in the sun or break if you drop them.  The pressure trigger (gun looking thing) is stainless and brass inside with a heavy plastic covering to keep hot water from burning you.  The hose has M22 fittings on both ends that mate to both the pressure trigger and the washer.  The really cool thing is that the extension has a 1/4 inch quick connect fitting on one end so nozzles can be changed easily.  That means I can get something like this:
These have various spray widths, from a stream (the red one) up to a nice wide fan.  No, I didn't have something like this before; isn't it great that now I can?  These have 1/4 quick connect fittings so they can be changed easily depending on what I want to do and can handle exceptionally heavy use.  Now, all I need is a good turbo nozzle for those hard to wash things like wheels and muddy bumpers on Jeeps.
This is the turbo nozzle I chose.  It is brass with a tough plastic covering to protect whatever you bump it into when working with it.  Notice the 1/4 inch quick connect?  Easy to change like the other nozzles.  Now, just because it would be really cool, I wanted some way to inject detergent into the high pressure spray so I could actually clean something.  It would also be good for bleach mixtures to clean off the mold from fences and maybe some other chemicals that might be useful.

This is a soap injector nozzle.  You drop one end in a soap bucket and put the other one on the end of the extension (yes, it has 1/4 inch quick connect fittings).  Using this you can wash away grease from your tractor transmission to find that stupid oil leak that's been bugging you for years.

So, everything except the turbo nozzle and the soap injector came in and I couldn't wait to try it out.  I assembled the hose, pressure trigger, and a fan nozzle and hooked it up to the little Powerwasher Weekender I have and away I went.

IT FREAKING LEAKED !!

Right where the M22 fitting entered the power washer, there was a constant stream of water that caused the washer to cycle.  This was really annoying, so I put the old hose back and it didn't leak.  Fine, what the heck is different?  It seems that the Powerwasher output fitting is .05 bigger than the specs for an M22 fitting.  This means that the thing will leak just enough to drive you nuts over time.  Since the M22 fitting has an o-ring to seal it, maybe if I changed the o-ring?  Nope, that didn't work, it was just too small, it would take a special o-ring that had a larger outside diameter while maintaining the internal size.  I could spend a month trying to find one and probably order a dozen wrong ones first or figure out something else.

I tried wrapping the male M22 fitting with teflon tape, but that was a waste of time because it just leaked around the tape.  I though about dragging out the epoxy and stuffing it full to seal it, but that would defeat the purpose I set out for.  I finally beat it a few minutes ago with a really simple trick.  The M22 fitting looks like this:
Notice the o-ring around the center?  That's the o-ring that I thought about changing to make it work, but I wanted to try something.  I took the o-ring out and wrapped teflon tape around the slot where the o-ring sets making it a little larger.  The idea is to stretch the o-ring out and  make it seal the fitting that is too large on the  Powerwasher Weekender that I have.  When I put the o-ring back on and greased it with a little o-ring lube that I keep around for the pool and acid pump, it was definitely larger.  I wiggled it a bit and made it fit into the fitting and tightened down the plastic covered nut.  It worked.  Full pressure and no leaks at all; I can drag it around the yard and bang it and it does fine.  You folks reading this, try this the next time you need a new o-ring but don't want to go to the store right now to get one; this little trick could hold you for several days until you can get a new one.  Obviously, some engineer decided that he would design a fitting that was almost to spec, but enough off to force us to buy a new washer because we couldn't make it work.  This kind of crap is what industry standards are designed to prevent.  But, we're just 'consumers' we don't count.

So, now I have a hose and lance assembly that I can change tips on easily, inject detergent, and turbo wash to my heart's content.  Even after the Powerwasher company put a non-standard fitting on their product just to mess up people that want to do what I did.

Take THAT Powerwasher.


Garage Controller - New Device at My House

$
0
0
I have a nice big garage that I use a lot, but I constantly leave the doors open. Seems about half the time I get part way down the dirt road away from home and have to try and remember if I closed the doors. This means coming back and checking so OCD doesn't set in and drive me nuts wondering if the doors are open. Be nice if I could look on my smart phone and see if the doors are open from anywhere and close them if necessary. Looks like a job for another little computer. I had an Arduino handy, a couple of Xbees and a little relay board set aside for this so the project shouldn't be too much trouble, All I need is an enclosure of some kind. I found my very most favorite enclosure for this kind of thing on Amazon:
I already had one of these installed by the phone company on the side of the house and just happened to stumble across it on Amazon.  They're 9x6x3 and weather resistant.  The one I have has been there for years and nothing inside has been damaged, so this should be fine.  
Here it is with the Arduino, one of the newer XBee shields and a four relay board mounted inside.  There's lots of room left for other devices and various wires from things around the garage.  For example, the beige box next to it is the differential temperature controller for my solar water heater.  Here in the desert, I only pay to heat water in the middle of winter on heavily overcast days.  I don't even allow power to get to the heating element for 8 months of the year.  In the future, control of that power and monitoring the temperature of the water will be handled by this new device.  The little XBee shield is a relatively new device and works really well.
I chose this particular board because it would allow me to put the XBee tx and rx pin on something other than 0 and 1 and it was relatively inexpensive; around $7 with shipping.  It also has a protoype area for mounting some screws to get inputs into the system.  I've found using the arduino serial port for an XBee leads to massive problems when I try to debug various things.  Without a serial port, you just can't find problems. So, I mounted some screw terminals on the XBee board to take inputs and hooked up some magnetic sensors on the garage doors.
Sorry, it's a little out of focus, I must have moved a bit, but you can see the terminals for the magnetic switch inputs and the relay outputs for the door switches.  I just ran wires to the regular garage door switches to control them, they were relatively close.  I use a two second pulse to open and close the doors and monitor closure for the door sensors.    

There was an unexpected side benefit of this, I can now tell the door to close.  That may not sound like much, but remember, garage doors are a toggle.  If they're closed and you push the button, they open.  You always have to go check to see if they are already closed before pushing the button because you may be opening them instead.  The idiocy of toggle buttons drives me nuts.

Currently, the Xbee simply transmits the status of the doors every few seconds and my House Controller displays the status on its LCD display.  It also provides the status on the Controller web page along with buttons to take care of closing or opening the doors.  Now, I can pull out my phone, look at the web page and close the darn doors if I left them open.  I've been wanting that for years.

One nice thing about my home automation, it gets easier over time.  I already have the XBee network set up, adding a new device is easy.  I have the code already written and available in several devices for copying to a new one.  I have code for watchdog timers, parsing inputs for commands and formatting status updates ready in several versions.  Adding a few lines to the House Controller to put it up on the web is pretty painless and the Controller has lots of memory left for this kind of thing.

Plus, the discovery of the enclosure I mentioned above.  This thing keeps the weather out, is easy to get into to debug or make changes, holds a lot of stuff, can be locked (keep kids out), and can survive the weather, especially if you paint it.  This will become the default enclosure for all my outside projects from now on since I can get it pretty easily and it works so well.  I may even get a few of them and retrofit some of the devices I already have.  I get really tired of unscrewing a lid to check an led when I could just open a door.  It's annoying that I didn't think of it before.  It would have saved me hours when I was working on the Pool Controller.  I was constantly opening that thing up and changing something as I decoded the protocol and worked out control strings.


Battery Charging - Part 4 (Harbor Freight item 42292)

$
0
0

Part 1 of this project is here, part 2 is here, and part 3 is here.

I probably will never actually finish this project to my satisfaction.  If you have been following this for the last many months, you might remember that I started off trying to get a float charger for lead acid batteries that actually worked and didn't dry the cells out in a couple of weeks ruining the batteries...without paying U$50 or more for each of them.  Rural living requires a lot of batteries for various machines that we use a few times a year and it is really annoying to have the battery fail between uses because of inattention.  Anyway, the latest charger variation (see part 3) works really well to keep the batteries charged with minimal loss of water, but checking on it is a pain in the butt.

I have to hunt down a multimeter and traipse out to the barn and check the voltage on each device.  It would be nice to have a voltage indicator on them to tell me if it is working correctly.  So, off to ebay I went and ordered a few of these:
These little guys just hook to the wires and get power from the source being measured.  Not the perfect situation since you have to power the LEDs from the supply that you are using, but it's a battery charger, not a lab instrument, so this will be fine.  To test them, I just hooked it to the charger output and stuck it on the wires leading to the battery on one of the cars.  This thing is cool.
The actual measured voltage is 13.4 on my multimeter, so it is relatively accurate and it gives me a highly visible indication of the state of charge from across the room.  Now, I have to figure out how I want it hooked into the circuitry and what form factor I'll use for mounting and using it.  The little black box I have in-line won't do the job, so I'll have to look around for something to house the display.

This brought up another idea: suppose I use one of my XBees and transmit the battery voltage over my network?  I could then check the state of charge from anywhere (yes, anywhere in the world) any time I wanted to.  I could even set up an alarm to send me email or a text message when something went wrong like a rat eating through the wiring.

I know what you're going to say, "What happened to the U$50 price goal?"  I don't have a good answer to that question; the parts and pieces so far are around 15 bucks, the little voltage display cost me a little under 3 bucks, and now I'm looking at an enclosure and an XBee.  This will push the total cost up into the 40+ range.  

I guess I'll just have to compromise my principles.....


Home Automation - Practical Application

$
0
0
It was a nice rainy morning in the desert and I decided to open the doors and air out the house.  I had all the doors open and the breeze, laden with the smell of wet earth, was circulating through the house removing all the smells of being locked up during many days of 100+ (F) temperatures.  My new puppy was trying his legs out running from doorway through the mud to another door and through the house and out again; a really fun morning.  Of course, I turned off the A/C compressors and let the recirculate fans run to air out the ducts in the house. This saved me a bunch of money on power since the entire house load was around 2KW even with the pool pump running.

This pleasant interlude started just before dawn (puppy had to go pee) and lasted until 9:30 AM when I shut the doors, put the puppy in his crate and took off for an early movie.

After I got to the show I realized that I hadn't checked the garage door and OCD set in worrying about the darn door being open.  I took out my phone and pulled up my web site to see.  Well, I had shut the door, but I forgot to restore the A/C to its summer settings and the dog was in a desert house with no cooling.  In most instances I would have just let the dog deal with it, but I had other choices now; I just touched a control and the A/C was restored to summer settings and started to cool the house down.

I have remotely checked the various statuses of my devices while away on trips, both to brag about having the ability and to actually make sure things are OK.  Also, I have daily instances of the various controllers taking care of things for me.  Things like making sure the pool pump is turned off at 10PM so it doesn't run all night, the acid pump automatically injecting chemicals into the pool to keep its levels reasonable, and my thermostats automatically handling peak usage to reduce power costs, but this is one of the rare instances where I actually wanted to remotely control my house.

That was so cool!  The puppy seemed to appreciate it too.

I love the desert, but....

$
0
0
Look at the picture below:


See the rattlesnake?  Here's a closer look:


If you look closely enough, you'll see the holes in its head from the 22 caliber snake shot rounds that killed it. This snake was hiding up against the side of my house inside the yard.  I discovered it when I went to pick up a toy my Irish Terrier puppy had left when he ran around the house.  It was dark and the snake's natural camouflage made it nearly invisible.  It didn't rattle until I actually almost stepped on it in the dark.

Yes, it did strike my dog.  The little guy was huddled up against the door into the house suffering from shock.  I grabbed the dog and headed straight for an emergency Vet's office.  

In answer to all comments about snake training, snake vaccines, watching my dog closely, keep it on a leash, etc.  The little guy is a little less than four months old.  The youngest the snake trainers will take him is 4 months and I already had an appointment for later this month.  The snake vaccine is usually given in February so it will be strongest in the spring when the snakes come out.  He was inside a fenced yard playing around my patio.  Crap like this sometimes happens no matter how many precautions you take.  And, yes, I often carry a handgun to handle situations like this, but neither I nor the puppy saw the snake in time to prevent the strike.  The handgun made short work of any possibility of this snake causing any further problems.

This is a picture of the little dog when he first came to live with me:


And here he is a couple of days ago, watching me fill his food bowl:


Fortunately, I've been overfeeding him and have gotten his weight up to almost 15 pounds so there was some body mass there to help with the snake venom.  He goes on a couple of half to three-quarter mile walks almost daily to build up some muscle and bone strength so he was very healthy.  And, he has every vaccination known to veterinary science, except snake, so opportunistic canine diseases are unlikely.

Barkley (his name) has been in the vet hospital now for over twelve hours, received lots of fluids, some narcotic pain killer, and two (and counting) vials of antivenin.  He's mostly out of shock and doing well considering the circumstances.  I'm going to go visit him in a few minutes because they are scheduled to do blood work on him soon to see how he's doing.  I want the results first hand.

So, you folks that have an aversion to handguns and people that carry them, think about this a while and what you would have done if it had been your dog.

Or child.

Update Oct 1, 2012 9:30PM:  Barkley can't come home tonight because his clotting factors are not good enough.  He'll have to stay tonight and may be able to come home tomorrow.  He's mostly alert and wants attention so I spent about a half hour in the floor with him hooked to an IV to let him know I was still around and hadn't abandoned him.  Last night when I left him, his head looked a lot like a bowling ball from the swelling; that has reduced a lot and he's eating.  I got another patient's person to take a picture of the little guy:


The red bandage is to protect his IV and the cone is because he kept trying to chew it.  They call it a 'No Cone' because they get tired of telling them 'NO' when they start chewing at the equipment.  He's eating and recognized me the minute I walked in the door.  Looks good for the little guy.

I'm going to get a flashlight now and wander around the house to see if there are any more snakes hanging around.

Update 2 October, 2012 12:25AM:  Got a call from the vet and Barkley's clotting factor improved and he said I could come get him.  The little guy is home running around chewing on a rawhide bone.  When I went to pick him up, he literally ran over to me.  This was far, far different from the little puppy in shock from a rattlesnake bite that I took to the hospital Sunday night. I may post a picture of him with the remaining swelling, but first Barkley and I are going to bed.

Don't ever say anything bad about an emergency veterinarian.

Update:  I put together a blog post about snake avoidance training <link>, do this if you have any worries at all about your dog.  If you take long walks in the wilderness or take it camping with you, it would be a really good idea.

Dogs and Rattlesnakes

$
0
0
After dealing with the second dog I've had bitten by a rattlesnake <link>, I decided people needed more information about snake avoidance.  There are a ton of sites out there that all espouse, what they say, is the right way to train a dog to avoid snakes.  There is a ton of misinformation and I just want to clear it up for people so they don't have the same problems I did.  There are a number of wrong things to do and a few right ones and I believe I have the experience now to tell the right from the wrong.  I've interviewed around twenty people who have used various trainers with varying results, and although they didn't realize they were being interviewed, they pointed out the various shortcomings.  Frankly, it's best to get the assistance of a professional snake trainer.  Very few people keep poisonous snakes around the house to be used for training dogs.  I'll start off with a few items that are very important.

When you arrive at the trainer, the cages for the snakes should already be set up.  The trainer should have done this before you got there; if they are not set up, leave and come back after they are.  The reason for this is the dog will see the cages being set up and associate any training to the cage, not the snakes inside.

The snakes MUST be alive and active.  A dead snake smells wrong and doesn't move around.  There's no point at all teaching your dog to avoid a dead snake. You want the dog to see the snake moving, hear its rattle, and realize this is another animal.

The trainer should have an empty cage for the dog to inspect.  This assures the dog that the cages are harmless.

The dog owner should be the one to walk the dog and participate in the training.  There are a couple of reasons for this.  The most important being that the owner knows how the dog will behave when it encounters a snake.  Each dog will behave a little differently from yelping and running away to just carefully skirting the snake.  You want to know the behavior in case of an encounter while on a walk through the woods.

The trainer should use a radio controlled shock collar.  Some people condemn this kind of tool as inhumane. Frankly, they are being silly.  You would MUCH rather your dog get a harmless shock than a snake bite.  Other methods, such as a water spray or loud noise just don't have the impact of a shock that isn't associated with a human in any way.  Besides, my dog loves getting sprayed with water.

So, a perfect session would consist of the trainer telling you what is going to happen and walking you through the steps first.  Then, you walk the dog over to the empty cage so it can be inspected and the dog gets familiar with the cages.  Then you walk by a cage with the snake in it.  The dog will get interested in the snake, go over, and inspect it.  When the trainer is assured that the dog has the scent, sight, and sound of the snake, the dog will get a shock.  Both you and the dog then run away from the snake to safety.  After a couple of  'good boys' you walk towards another cage with a snake or two in it.  The dogs reaction will vary a lot on the second cage.  Some dogs will want to go after the next snake, but most will shy away and not approach.  The last step is to allow the dog to wander freely (no leash) as you walk by the snake cages.  Your animal should not approach the snakes and may even warn you to stay away.

You see what is happening.  The dogs inherent curiosity will cause it to go to the snake and sniff around, the shock will tell it that this thing hurts, and running away will show the dog that it's OK to get away from harm. The empty cage will make sure the cage isn't a factor in the training; your dog will not be afraid of cages.  The live snake moves around, rattles, and probably will strike the side of the cage during the session.  You have safely exposed your pet to a dangerous situation and taught it how to respond.

The trainer should offer a second session a few weeks after the first to assure both you and the dog that the training has taken hold.  Personally, I like to take the dog back yearly to walk by the cages to be sure the little guy remembers those things are bad, and refresh my memory of the dog's behavior in this situation.

There are trainers that insist that dead snakes work just as well.  This simply isn't true.  You'll have a dog carefully trained to avoid dead snakes; not very useful.  There are other trainers that insist that they walk your dog through the course.  Their reasoning for this is the timing of the shock correction.  If it is given at the wrong time, you may not get the best results.  While this is true, it's really easy to tell the proper time for the correction.  Simply wait until the dog's entire attention is on the snake.  All of us with dogs know when that point happens; we've pulled our dog out of enough gopher holes to be quite familiar with it.  A snake trainer can easily tell while they are standing at the side watching us walk our dog up to the snake cage.  Special measures should be taken to keep the dog from associating the cage with the correction.  That's why an empty cage is a good idea at the start of the training course.

The first dog I had bitten by a snake was a loving little silky terrier.  He just wanted to play and was bitten on the side of his head.  Even though I got him to the vet within thirty minutes, he died.  I've had every dog since snake trained to protect them as much as possible from this particular danger.  The second dog that was bitten is detailed on the previous entry of this blog.  This little guy was just too young for the training and unlucky.  However, he not only survived the bite, he is totally recovered, and had his first training session just this morning.  In both cases, the vet bills were quite high; many, many times the cost of the training.

Several times now I have been with a trained dog when we encountered a rattlesnake in the wild.  In all cases, the dog alerted me to the danger before there was a possibility of a bite.  Think of snake training as a way of teaching the dog to warn you of danger when out for a walk or a run.  This means that a snake trained dog can warn children of danger when it's outside playing with them.  It certainly beats sit, roll over and beg for utility and usefulness and makes the cost of training sound worthwhile doesn't it?

This is the best training a person can give their pet if they live where such an encounter is possible.  If you live in Manhattan or the center of LA, it may not be necessary, but if you live in the suburbs skirting farm country or take your dog camping, consider doing this to protect your pet.

Alternatives to Cosm (Pachube)

$
0
0
There are a few alternatives to Cosm for handling devices that report over the web. I'm currently playing with Sen.se (open.sen.se) and it has some really cool features that I haven't seen before. See, I'm very interested in monitoring and controlling my house. I want to be able to tell if it's too hot, what the appliances are doing, is the darn garage door open, that kind of thing. I don't want to spend months learning how to create charts, pretty switches, or automatic backups for data stores. That's why services that connect devices on the web will someday be important. Someday, services like Sen.se and Cosm will be very important to the operation of devices. Anyway, Sen.se has a method of connecting to the data I'm already sending to Cosm. By adding a feed to my Cosm account I can use the Sen.se controls and displays to monitor my house. Cool, really cool. For example, here is a graph I put together in a few minutes using their tools (scroll down past it for more):
Notice that it is almost real time? The chart will change based on the items I'm charting so you can see the latest data a minute or so after it gets posted on the Cosm site.  Additionally, it's interactive.  You can put your pointer over the control and see individual values and turn off parts of the chart.  There's also a problem putting more than one control on a blog page. They seem to interact with blogger and each other such that you can't get them to work together.  At least not yet (Sen.se is a beta site).

But isn't the chart cool?

More About XBee Broadcast

$
0
0
I discuss the usefulness of XBee broadcast here <link>, but there is a problem with this I didn't foresee.  It seems that, if you get enough devices, the network gets flooded and becomes unreliable.  You see, the beauty of XBees is that they implement mesh protocol such that you can have a message forwarded from XBee to XBee until it reaches its destination many hops away.  This is a really good thing because an XBee at the far end of the house can communicate with another one at the opposite end.

I tested this several times by separating a couple of XBees to where they couldn't communicate, then completed the circuit by simply placing one in the middle to forward the data.  This means I can go from my barn to my controller with a message without worrying about how far it is, or getting a high power version of the XBee.

The problem comes when a broadcast is transmitted by a device far away and is echoed by several of them to assure it gets to its destination.  The Zigbee packet gets a little larger with each hop since it carries the routing information along with it and eventually, the channel is flooded with messages bouncing around.

Introducing the Freakduino Chibi.

I found this when I bought a new device to take a look at the network.  This little device <link>  is an IEEE 802.15.4 radio mounted with an Arduino compatible MCU.   The little device can be programmed to listen in promiscuous mode such that it hears all the packets in range, and at my house this means almost all the devices can be monitored.  There's also the possibility of hooking this into WireShark, but I couldn't get that to work reliably.  What I did was simply set up a small program that will listen to any of my devices individually to see what traffic is passing through it and just sat back and observed what was going on one device at a time.

The Acid Pump would send a broadcast that was echoed by several devices trying to forward the message to some other device effectively more than doubling the traffic for each device.  When they were all doing things, the channel was flooded with superfluous repeated messages such that collisions were constantly happening.  There just wasn't enough dead air time for any of them to transmit.  I lost messages because they overlapped each other and checksums were bad because the devices overlapped at times.

I'm still a big fan of broadcast, it definitely has its place.  For example, a new device that you want to carefully monitor for a few days to be sure you got the set up correct, or a device that is having some problems and needs to be monitored.  However, don't go nuts with it like I did. So, what you can do is set your code up to transmit in broadcast initially to get the bugs out then change it to a specific address when you're comfortable that it is working correctly.  Then get a Freakduino Chibi to check it from time to time or when you suspect something might be wrong with it

As you can see, it is a little bigger than an Arduino, but that's OK since it has an optional enclosure that houses it nicely:
This is the combination I bought.  Then, I took his example code, modified the heck out of it such that it could watch a particular device (even if the device was transmitting to a specific address) and was able to troubleshoot my network.  

Of course it isn't perfect.  The Freakduino only runs at 8MHz, so it's entirely possible for it to be unable to keep up with the traffic on a heavily loaded network like mine used to be, and there are probably a couple of problems with the library he provides to get you going, but that's the kind of thing we're best at.

So, I was able to cut the traffic down on my network by a huge amount, and I can monitor any device to see what is actually happening.  Now, I have bandwidth to add even more devices.

Monitoring My XBee Network

$
0
0
In the previous post <link> I wrote about how I discovered broadcast mode can cause problems as you increase the number of nodes.  That led to a method of monitoring each node to see what it was actually doing, and by watching each of them in turn, seeing how the traffic patterns work out.

Well, I left it kind of up-in-the-air on exactly how I did it.  Basically, I used the examples that Akiba of Freaklabs released for various functions and created a sniffer of sorts.  This is necessary because the XBee only sends out the serial port data intended for the particular radio module you're plugged into.  That's what makes broadcast mode so useful, you can see all the traffic and chase problems.  With a Freakduino Chibi board, you can monitor all the devices on your network at once, but that is way too much information to try to wade through.  By setting the Chibi board to promiscuous mode and then writing code to filter by address, you can watch any node in the network to see what is going on with that particular device.  This makes it possible to see its traffic even though you aren't using an XBee.

Here's the code I came up with:

The Arduino Sketch
/*
This sketch enables promiscuous mode on the Freakduino boards and then
filters by device address to watch a particular node.

I had to change the buffer size in the chibi library for promiscuous mode
because, being set to 1024 with another buffer for the packet to be manipulated
caused the board to run out of RAM.  Just go into the chibi library and
find the receive buffer in chb_buf.h and set it to what you want.  I used the
value 500, and it seems to work fine

Before using this sketch, also go into the chibiUsrCfg.h file and
enable promiscuous mode. To do this, change the definition:

#define CHIBI_PROMISCUOUS 0
to
#define CHIBI_PROMISCUOUS 1

When not using promiscuous mode, disable this setting by changing
it back to 0.
*/

#include <chibi.h>
#include <avr/pgmspace.h>
#include <MemoryFree.h>

/*
Addresses of devices in my network
                    Long     Short
Garage Controller 407A 38AF  A019
Power Monitor     4031 566B  CD6B
Controller        4055 B0A6  97FA
Status Display    406F B6B5  9BE8
Pool Controller   4079 B2BD  9370
Temp1             406F 7FAC  1B1E
House Clock       4055 B094  0
Acid Pump         406F B7AF  7D58
*/
char *deviceName[] = {"Garage Controller",
                       "Power Monitor",
                       "Controller",
                       "Status Display",
                       "Pool Controller",
                       "Temp1",
                       "House Clock",
                       "Acid Pump"};
uint16_t deviceAddress[] = {0xA019,
                         0xCD6B,
                         0x97FA,
                         0x9BE8,
                         0x9370,
                         0x1B1E,
                         0x0,
                         0x7D58};
uint16_t listenTo;
byte Pbuf[500];
char Dbuf[50];
int longest = 0;

void showMem(){
  strcpy_P(Dbuf,PSTR("Mem = "));
  Serial.print(Dbuf);
  Serial.println(freeMemory());
}

/**************************************************************************/
// Initialize
/**************************************************************************/
void setup()
{
  // Init the chibi stack
  Serial.begin(115200);
  chibiInit();
  strcpy_P(Dbuf,PSTR("\n\r***************I'm alive**************"));
  Serial.println(Dbuf);
  unsigned int choice = 0;
  Serial.println("Pick a device to listen to");
  for(int i = 0; i < sizeof(deviceName)/sizeof(deviceName[0]); i++){
    Serial.print((char)(i + 'A'));
    Serial.print(" - ");
    Serial.println(deviceName[i]);
  }
  Serial.print("> ");
  // this only accepts a single character for the device choice.
  // that's because the chibi board runs at 8MHz on the internal clock and
  // internal clocks aren't accurate.  This means the higher baud rates sometimes
  // have problems.  When I worked on this I couldn't get the board to accept more
  // than one character correctly at baud rates over 57K.  Works fine at 9600,
  // but I want to output the data far faster than that.
  while(1){
    if(Serial.available() != 0){
      char c = Serial.read();
      Serial.write(c);
      Serial.println();
      choice = toupper(c) - 'A';
      if (choice < sizeof(deviceName)/sizeof(deviceName[0]))
        break;
      else {
        Serial.println(" oops, try again");
        Serial.print("> ");
      }
    }
  }
  listenTo = deviceAddress[choice];
  strcpy_P(Dbuf,PSTR("Starting Radio, Result = "));
  Serial.print(Dbuf);
  Serial.println(chibiSetChannel(12),DEC);
  strcpy_P(Dbuf,PSTR("Listening to "));
  Serial.print(Dbuf);
  Serial.print(deviceName[choice]);
  strcpy_P(Dbuf,PSTR(" at address "));
  Serial.print(Dbuf);
  Serial.println(listenTo, HEX);
  showMem();
}

/**************************************************************************/
// Loop
/**************************************************************************/
void loop()
{
  // Check if any data was received from the radio. If so, then handle it.
  if (chibiDataRcvd() == true)
  {
    int len;
    uint16_t senderAddress;
 
    // send the raw data out the serial port in binary format
    len = chibiGetData(Pbuf);
    if (len > longest)
      longest = len;
    senderAddress = chibiGetSrcAddr();
    if (senderAddress == listenTo && len > 0){
      strcpy_P(Dbuf,PSTR("From: "));
      Serial.print(Dbuf);
      Serial.print(senderAddress,HEX);
      strcpy_P(Dbuf,PSTR(" Len: "));
      Serial.print(Dbuf);
      Serial.print(len);
      strcpy_P(Dbuf,PSTR(" Longest: "));
      Serial.print(Dbuf);
      Serial.println(longest);
      for (int i= 0; i < len; i++){
        uint8_t nibble = (uint8_t) (Pbuf[i] >> 4);
        if (nibble <= 9)
          Serial.write(nibble + 0x30);
        else
          Serial.write(nibble + 0x37);
     
        nibble = (uint8_t) (Pbuf[i] & 0x0F);
        if (nibble <= 9)
          Serial.write(nibble + 0x30);
        else
          Serial.write(nibble + 0x37);
        Serial.print(' ');
      }
      Serial.println();
      for (int i= 0; i < len; i++){
        uint8_t nibble = (uint8_t) (Pbuf[i] >> 4);
        Serial.write(' ');
        if (iscntrl(Pbuf[i]))
          Serial.write(' ');
        else
          Serial.write(Pbuf[i]);
        Serial.write(' ');
      }
      Serial.println();
    }
  }
}


A couple of things to keep in mind.  The Chibi board is only running at 8 Mhz, so it can't keep up with unlimited traffic flying through the air at 250Kb forever.  If you spend too much time in the code checking and decoding, you'll miss packets.  The Chibi library sets a buffer size of 1024 to handle packets being received to help with this, but you'll have to reduce this size because the MCU only has 2K of ram to begin with.  I point this out in the code.  The maximum size of a packet is 127 bytes, so make your parsing buffer longer than that.  I print the maximum packet length in the code above, and have never seen a packet larger, so it appears the library is working fine for separating the packets.  I also put a routine in the code to monitor  memory usage.  Use this to keep track so you don't run out with the various buffers and such.

Here's a sample of the output using the serial monitor from the Arduino IDE:


It doesn't wrap around, but that could be easily added.  I just use the scroll bar on the bottom to move around.  I output the hex values as well as the ascii so I can recognize the various packets as well as decode the binary portions of the data.

So, as your network grows, or you have problems right off the bat, consider this combination of things as a possible tool to help you get past it.  Of course, you're welcome to grab the code and modify it to your particular network and need for monitoring.

Using the XBee library

$
0
0
Recently Paul Stoffregen created a new software serial library for the Arduino, then he modified Andrew Rapp's XBee library to use it (as well as the older, but really great, SoftwareSerial libray).  Suddenly, the XBee library is something that could be really useful.

See, the XBee library has traditionally been hooked into the hardware serial lines on Arduino Pins 0 and 1.  That means getting debugging information out of the device combination of an Arduino and an XBee is an exercise in frustration and annoyance.  Sure, you can use blinking lights to tell you what is going on, but this is the 21st century.  I have always written my own code to handle the XBee interaction because I wanted the serial port to provide status and control when I was working on a project.  Additionally, Andrew's library is heavily c++ and all the classes, inheritance, and instances confused the heck out of me.

However, maybe with the inclusion of a modified software serial port, and the capability to use the additional ports on an Arduino Mega, now is the time to take a serious look at using it.  I mean, if you have a mega, you can now put the XBee on Serial1 and keep Serial and Serial 2 for other things; this is just the ticket for converting RS485 into XBee packets to send over the air where you don't have wires.  Heck, I can think of dozens of things.

So, here is my first voyage into the use of the library.  I haven't linked in Paul's new serial library yet, I will on a future example, but I just wanted to understand what was going on and how to, at least, receive a packet and do something with it.  I took one of Andrew's library examples and modified it substantially to include many of the things I need in using an XBee and commented the heck out of it so others stood a chance of understanding what was going on.  It's amazing how few examples are out there that actually show what you need to do to do something along these lines.


The Arduino Sketch

/**
I took Andrew Rapp's receive example and modified it to be completely
unrecognizable.

I wanted to experiment with and better understand how to use his XBee
library for an actual project.  With the inclusion of support for SoftwareSerial
so that the XBee can be put on digital pins leaving the Arduino serial port
available for debugging and status, the library's usefullness shot way up.

This is a HEAVILY commented example of how to grab a receive packet off the
air and do something with it using series 2 XBees.  Series 1 XBees are left as
and exercise for the student.
*/

#include <XBee.h>
#include <SoftwareSerial.h>

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle
ZBRxResponse rx = ZBRxResponse();

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 2 to Tx and 3 to Rx of the XBee
// I know this sounds backwards, but remember that output
// from the Arduino is input to the Xbee
#define ssRX 2
#define ssTX 3
SoftwareSerial nss(ssRX, ssTX);


void setup() {
  // start serial
  Serial.begin(9600);
  // and the software serial port
  nss.begin(9600);
  // now that they are started, hook the XBee into
  // Software Serial
  xbee.setSerial(nss);
  // I think this is the only line actually left over
  // from Andrew's original example
  Serial.println("starting up yo!");
}

void loop() {
    // doing the read without a timer makes it non-blocking, so
    // you can do other stuff in loop() as well.
    xbee.readPacket();
    // so the read above will set the available up to
    // work when you check it.
    if (xbee.getResponse().isAvailable()) {
      // got something
      Serial.println();
      Serial.print("Frame Type is ");
      // Andrew call the frame type ApiId, it's the first byte
      // of the frame specific data in the packet.
      Serial.println(xbee.getResponse().getApiId(), HEX);
   
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet, the kind this code is looking for
     
        // now that you know it's a receive packet
        // fill in the values
        xbee.getResponse().getZBRxResponse(rx);
     
        // this is how you get the 64 bit address out of
        // the incoming packet so you know which device
        // it came from
        Serial.print("Got an rx packet from: ");
        XBeeAddress64 senderLongAddress = rx.getRemoteAddress64();
        print32Bits(senderLongAddress.getMsb());
        Serial.print(" ");
        print32Bits(senderLongAddress.getLsb());
     
        // this is how to get the sender's
        // 16 bit address and show it
        uint16_t senderShortAddress = rx.getRemoteAddress16();
        Serial.print(" (");
        print16Bits(senderShortAddress);
        Serial.println(")");
     
        // The option byte is a bit field
        if (rx.getOption() & ZB_PACKET_ACKNOWLEDGED)
            // the sender got an ACK
          Serial.println("packet acknowledged");
        if (rx.getOption() & ZB_BROADCAST_PACKET)
          // This was a broadcast packet
          Serial.println("broadcast Packet");
       
        Serial.print("checksum is ");
        Serial.println(rx.getChecksum(), HEX);
     
        // this is the packet length
        Serial.print("packet length is ");
        Serial.print(rx.getPacketLength(), DEC);
     
        // this is the payload length, probably
        // what you actually want to use
        Serial.print(", data payload length is ");
        Serial.println(rx.getDataLength(),DEC);
     
        // this is the actual data you sent
        Serial.println("Received Data: ");
        for (int i = 0; i < rx.getDataLength(); i++) {
          print8Bits(rx.getData()[i]);
          Serial.print(' ');
        }
     
        // and an ascii representation for those of us
        // that send text through the XBee
        Serial.println();
        for (int i= 0; i < rx.getDataLength(); i++){
          Serial.write(' ');
          if (iscntrl(rx.getData()[i]))
            Serial.write(' ');
          else
            Serial.write(rx.getData()[i]);
          Serial.write(' ');
        }
        Serial.println();
     
        // So, for example, you could do something like this:
        handleXbeeRxMessage(rx.getData(), rx.getDataLength());
/*
        // I commented out the printing of the entire frame, but
        // left the code in place in case you want to see it for
        // debugging or something
        Serial.println("frame data:");
        for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++) {
          print8Bits(xbee.getResponse().getFrameData()[i]);
          Serial.print(' ');
        }
        Serial.println();
        for (int i= 0; i < xbee.getResponse().getFrameDataLength(); i++){
          Serial.write(' ');
          if (iscntrl(xbee.getResponse().getFrameData()[i]))
            Serial.write(' ');
          else
            Serial.write(xbee.getResponse().getFrameData()[i]);
          Serial.write(' ');
        }
        Serial.println();
*/
      }
    }
    else if (xbee.getResponse().isError()) {
      // some kind of error happened, I put the stars in so
      // it could easily be found
      Serial.print("************************************* error code:");
      Serial.println(xbee.getResponse().getErrorCode(),DEC);
    }
    else {
      // I hate else statements that don't have some kind
      // ending.  This is where you handle other things
    }
}

void handleXbeeRxMessage(uint8_t *data, uint8_t length){
  // this is just a stub to show how to get the data,
  // and is where you put your code to do something with
  // it.
  for (int i = 0; i < length; i++){
//    Serial.print(data[i]);
  }
//  Serial.println();
}

// these routines are just to print the data with
// leading zeros and allow formatting such that it
// will be easy to read.
void print32Bits(uint32_t dw){
  print16Bits(dw >> 16);
  print16Bits(dw & 0xFFFF);
}

void print16Bits(uint16_t w){
  print8Bits(w >> 8);
  print8Bits(w & 0x00FF);
}

void print8Bits(byte c){
  uint8_t nibble = (c >> 4);
  if (nibble <= 9)
    Serial.write(nibble + 0x30);
  else
    Serial.write(nibble + 0x37);
     
  nibble = (uint8_t) (c & 0x0F);
  if (nibble <= 9)
    Serial.write(nibble + 0x30);
  else
    Serial.write(nibble + 0x37);
}

I tried to get all the major items out of the packet so they could be displayed and even included a tiny routine to illustrate using the received data.  This is what it looks like running:


You have to use the scrollbar at the bottom to see all of the message, but I wanted it that way instead of worrying about wrapping around.  I also put in print routines for the hex data; I love being able to see it in both hex and ascii.

Grab it, modify it to your purpose, and have fun.

Using the XBee Library Part 2

$
0
0
Previously, I talked about using Andrew Rapp's XBee library on a project and posted an example.  This is the second example I've been working on.  The objective is to understand the library well enough to re-implement some of my devices using the library because I'm getting tired of doing my own parsing of the basic packet.  Yes, I have finer control, but I've found I don't really need finer control.  So, here is an example of using the code on an Arduino 2560 with the XBee connected to Serial3.  This leaves me two unused serial ports to play with since I'm using the main serial port as my debugging and status port.

The Arduino Sketch
/*
XBee RX test for a Arduino Mega2560 using Serial3 as the XBee serial
input for a Series 2 XBee.  I took Andrew Rapp's receive example and modified
it heavily.

I wanted to experiment with and better understand how to use his XBee
library for an actual project.  With the inclusion of support for SoftwareSerial
so that the XBee can be put on digital pins leaving the Arduino serial port
available for debugging and status, the library's usefullness shot way up.  These
changes also allow for the use of the additional serial ports on a Mega2560

This is a HEAVILY commented example of how to grab a receive packet off the
air and do something with it using series 2 XBees.  This example also supports
a remote XBee end device sending analog data.  Series 1 XBees are left as an
exercise for the student.
*/

#include <XBee.h>

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle
ZBRxResponse rx = ZBRxResponse();
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();

void setup() {
  // start serial
  Serial.begin(9600);
  // and the third serial port
  Serial3.begin(9600);
  // now that they are started, hook the XBee into
  // the third serial port
  xbee.setSerial(Serial3);
  // I think this is the only line actually left over
  // from Andrew's original example
  Serial.println("starting up yo!");
}

void loop() {
    // doing the read without a timer makes it non-blocking, so
    // you can do other stuff in loop() as well.
    xbee.readPacket();
    // so the read above will set the available up to
    // work when you check it.
    if (xbee.getResponse().isAvailable()) {
      // got something
      // I commented out the printing of the entire frame, but
      // left the code in place in case you want to see it for
      // debugging or something.  The actual code is down below.
      //showFrameData();
      Serial.print("Frame Type is ");
      // Andrew calls the frame type ApiId, it's the first byte
      // of the frame specific data in the packet.
      Serial.println(xbee.getResponse().getApiId(), HEX);
   
      if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
        // got a zb rx packet, the kind this code is looking for
     
        // now that you know it's a receive packet
        // fill in the values
        xbee.getResponse().getZBRxResponse(rx);
     
        // this is how you get the 64 bit address out of
        // the incoming packet so you know which device
        // it came from
        Serial.print("Got an rx packet from: ");
        XBeeAddress64 senderLongAddress = rx.getRemoteAddress64();
        print32Bits(senderLongAddress.getMsb());
        Serial.print(" ");
        print32Bits(senderLongAddress.getLsb());
     
        // this is how to get the sender's
        // 16 bit address and show it
        uint16_t senderShortAddress = rx.getRemoteAddress16();
        Serial.print(" (");
        print16Bits(senderShortAddress);
        Serial.println(")");
     
        // The option byte is a bit field
        if (rx.getOption() & ZB_PACKET_ACKNOWLEDGED)
            // the sender got an ACK
          Serial.println("packet acknowledged");
        if (rx.getOption() & ZB_BROADCAST_PACKET)
          // This was a broadcast packet
          Serial.println("broadcast Packet");
       
        Serial.print("checksum is ");
        Serial.println(rx.getChecksum(), HEX);
     
        // this is the packet length
        Serial.print("packet length is ");
        Serial.print(rx.getPacketLength(), DEC);
     
        // this is the payload length, probably
        // what you actually want to use
        Serial.print(", data payload length is ");
        Serial.println(rx.getDataLength(),DEC);
     
        // this is the actual data you sent
        Serial.println("Received Data: ");
        for (int i = 0; i < rx.getDataLength(); i++) {
          print8Bits(rx.getData()[i]);
          Serial.print(' ');
        }
     
        // and an ascii representation for those of us
        // that send text through the XBee
        Serial.println();
        for (int i= 0; i < rx.getDataLength(); i++){
          Serial.write(' ');
          if (iscntrl(rx.getData()[i]))
            Serial.write(' ');
          else
            Serial.write(rx.getData()[i]);
          Serial.write(' ');
        }
        Serial.println();
        // So, for example, you could do something like this:
        handleXbeeRxMessage(rx.getData(), rx.getDataLength());
        Serial.println();
      }
      else if (xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE) {
        xbee.getResponse().getZBRxIoSampleResponse(ioSample);
        Serial.print("Received I/O Sample from: ");
        // this is how you get the 64 bit address out of
        // the incoming packet so you know which device
        // it came from
        XBeeAddress64 senderLongAddress = ioSample.getRemoteAddress64();
        print32Bits(senderLongAddress.getMsb());
        Serial.print(" ");
        print32Bits(senderLongAddress.getLsb());
     
        // this is how to get the sender's
        // 16 bit address and show it
        // However, end devices that have sleep enabled
        // will change this value each time they wake up.
        uint16_t senderShortAddress = ioSample.getRemoteAddress16();
        Serial.print(" (");
        print16Bits(senderShortAddress);
        Serial.println(")");
        // Now, we have to deal with the data pins on the
        // remote XBee
        if (ioSample.containsAnalog()) {
          Serial.println("Sample contains analog data");
          // the bitmask shows which XBee pins are returning
          // analog data (see XBee documentation for description)
            uint8_t bitmask = ioSample.getAnalogMask();
            for (uint8_t x = 0; x < 8; x++){
            if ((bitmask & (1 << x)) != 0){
              Serial.print("position ");
              Serial.print(x, DEC);
              Serial.print(" value: ");
              Serial.print(ioSample.getAnalog(x));
              Serial.println();
            }
          }
        }
        // Now, we'll deal with the digital pins
        if (ioSample.containsDigital()) {
          Serial.println("Sample contains digtal data");
          // this bitmask is longer (16 bits) and you have to
          // retrieve it as Msb, Lsb and assemble it to get the
          // relevant pins.
          uint16_t bitmask = ioSample.getDigitalMaskMsb();
          bitmask <<= 8;  //shift the Msb into the proper position
          // and in the Lsb to give a 16 bit mask of pins
          // (once again see the Digi documentation for definition
          bitmask |= ioSample.getDigitalMaskLsb();
          // this loop is just like the one above, but covers all
          // 16 bits of the digital mask word.  Remember though,
          // not all the positions correspond to a pin on the XBee
          for (uint8_t x = 0; x < 16; x++){
            if ((bitmask & (1 << x)) != 0){
              Serial.print("position ");
              Serial.print(x, DEC);
              Serial.print(" value: ");
              // isDigitalOn takes values from 0-15
              // and returns an On-Off (high-low).
              Serial.print(ioSample.isDigitalOn(x), DEC);
              Serial.println();
            }
          }
        }
        Serial.println();
      }

      else {
        Serial.print("Got frame id: ");
        Serial.println(xbee.getResponse().getApiId(), HEX);
      }
    }
    else if (xbee.getResponse().isError()) {
      // some kind of error happened, I put the stars in so
      // it could easily be found
      Serial.print("************************************* error code:");
      Serial.println(xbee.getResponse().getErrorCode(),DEC);
    }
    else {
      // I hate else statements that don't have some kind
      // ending.  This is where you handle other things
    }
}

void handleXbeeRxMessage(uint8_t *data, uint8_t length){
  // this is just a stub to show how to get the data,
  // and is where you put your code to do something with
  // it.
  for (int i = 0; i < length; i++){
//    Serial.print(data[i]);
  }
//  Serial.println();
}

void showFrameData(){
  Serial.println("Incoming frame data:");
  for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++) {
    print8Bits(xbee.getResponse().getFrameData()[i]);
    Serial.print(' ');
  }
  Serial.println();
  for (int i= 0; i < xbee.getResponse().getFrameDataLength(); i++){
    Serial.write(' ');
    if (iscntrl(xbee.getResponse().getFrameData()[i]))
      Serial.write(' ');
    else
      Serial.write(xbee.getResponse().getFrameData()[i]);
    Serial.write(' ');
  }
  Serial.println();
}

// these routines are just to print the data with
// leading zeros and allow formatting such that it
// will be easy to read.
void print32Bits(uint32_t dw){
  print16Bits(dw >> 16);
  print16Bits(dw & 0xFFFF);
}

void print16Bits(uint16_t w){
  print8Bits(w >> 8);
  print8Bits(w & 0x00FF);
}

void print8Bits(byte c){
  uint8_t nibble = (c >> 4);
  if (nibble <= 9)
    Serial.write(nibble + 0x30);
  else
    Serial.write(nibble + 0x37);
     
  nibble = (uint8_t) (c & 0x0F);
  if (nibble <= 9)
    Serial.write(nibble + 0x30);
  else
    Serial.write(nibble + 0x37);
}

It was actually pretty easy to convert my previous example to the 2560; I just changed the port in setSerial() to Serial3 instead of newsoftserial and it worked.  This left me a little time to play with capturing an I/O packet and taking it apart.  The code to handle an I/O packet is in this example.

I wanted the I/O packet because I have an XBee outside on a pole measuring the temperature that sends I/O packets periodically and I want to set up a battery monitor for my lead acid batteries to keep track of their state of charge.  You don't need an Arduino hooked to an XBee for these purposes, but you do need to be able to receive and decode the packets.

Once again, feel free to grab the code and modify it for your purposes.

Tiny Power Supplies for Micro Controller Projects

$
0
0
When you build micro controller projects, eventually you want to do something real that will have to work long term.  For this you need a power supply that is small, maybe small enough to put in a light switch, ceiling fan, or dryer control panel.  These things are hard to find.  I've spent hours on Google trying to find really small 5V supplies with some success, but never fitting my needs.  Nice little supplies that you have to buy in 100+ quantities, nice little supplies that cost US $50, etc are out there, but who wants to invest that kind of money in a technology that changes almost daily?

In a few project postings I describe how I cut the guts out of a wall wart like this:
These little devices work great as microcontroller power supplies.  The one above will put out up to 2A and doesn't seem to get hot doing it.  I've had several in service, out in the weather for two years.  At a cost less than US $5 each (usually with free shipping) they are a fine solution.  I've taken the supply out of the plastic case and installed it into devices like this <link>:
The little board in the upper left is the guts of the wall wart.  I've even used the entire wall wart as a mounting platform for another device:
This device <link> has an XBee mounted on the side of the wall wart transmitting temperature every minute or so.  All-in-all, a pretty useful device repurposed from the iPad craze.  However, technology moves on and I want to try a couple of ideas that would work better if I had an even smaller power supply.  I asked on a couple of forums and was pointed to one of these:
I already had two of them charging mobile devices in the house so I decided to gut one of them and see what was inside:
This little supply is TINY. Yes, I had to cut the case off with a Dremel to get to the guts; the top was seriously glued to the bottom and refused to come off. The two board with connecting cable configuration could create a problem mounting, but nothing I can't overcome, and the wires to the AC pins might give me a problem, but it couldn't be too hard to solve; I like this.  So, looking around the web to see what kind of deal I could get on them I found them for US $1 on Amazon.  Yes, you read that right, a single dollar, with free shipping.  So:
Here's my pile of stock devices.  

Since supply and demand act on everything, the price at Amazon has gone up to US $1.45 as of this writing and could go either up or down based on activity, but they are still a bargain.  

Even with this solution available, I'm still searching for possibilities.  The rough requirements for the supply are: minuscule size, 5V at a least an amp (relays, you know), easy to mount, things like that.  

To you suppliers out there, there's a market here that you aren't exploiting.  SparkFun, Lady Ada, Itead, etc. are you listening?  You folks in China, what are you waiting for?
Viewing all 218 articles
Browse latest View live