Friday, April 19, 2013

Pool Controller 2 for Goldline P4

No, I didn't take a month off; I've been off on other projects that aren't technical or related to power.  Stuff like fixing a chip in my motorcycle paint, equipping toy hauler to tow it, and spring pruning.  But, I started having some trouble with the transmissions from my pool controller.  I have a whole section on my swimming pool page <link> where I describe how I decoded the Goldline protocol and built a controller for my swimming pool.  Yes, there are remote controllers out there that allow you to change settings and such from the house, but mine hooks into the House Controller and allows me to change things from the internet.  Yes, I can turn my pool motor on from anywhere.

However, as I described, there are some problems.  First, it's based on an Arduino Uno which only has one serial port.  I need at least two, one for the XBee to transmit status and the other for the RS485 link to the Goldline pool controller.  It would be nice to have another one for debugging and testing commands as well.   I used SoftwareSerial code to handle the extra port needs, but there's the occasional over run and I'm really running the little Arduino on the edge with two high speed ports cranking away all the time.  Guess what, I have a Mega2560 that isn't doing anything.

So, I pulled the device off the fence and rebuilt it essentially from scratch.  I put the XBee on Serial3, the pool controller on Serial2, and use the regular Serial as my command and debugging port.  This is all possible because the watchdog timer and boot loader problems have been fixed as I detailed in several posts, and I discovered a new enclosure that I have already used on my Garage Controller <link> that gives me plenty of room and easy access.

Since it was going on a Mega2560, there would have to be software changes.  I decided to take the time to incorporate all that I've learned over the last couple of years and update the XBee and timer handling.  The device now uses the Arduino XBee library and is in API mode so the packets are handled well.  It knows what time it is by catching the House Clock <link> transmission, so it's possible to build in specific time of day alarms or do special things on the weekends.  There's room in memory and in the enclosure to incorporate the Acid Pump timer as well, freeing up a device.  I will also be able to hook in the float I installed in my septic tank so it can alarm when the tank filter gets clogged <link>.  Of course, it will be more than a Pool controller then, but what's in a name?  Besides, a septic tank is sort of a pool ... isn't it?

Here's a picture of the device after I mounted the boards into the enclosure:


And here it is on the fence working:

Here's the devices on that side of the house:

No, I didn't mount it crooked, the fence goes down hill at that point.

Naturally, I'll post the code on the Swimming Pool page, but I'll get to that in a day or two because I have to change a lot of stuff to illustrate it the way I want to.

Why aren't more people doing this kind of thing around their house?

Monday, March 4, 2013

Water Heater and Solid State Relays Part 2


Part 1 of this is here <link>

I wandered out into the garage to admire my new SSR controlled water heater and noticed that the indicator led was on.  It was during the period when the water heater should have been turned off and that can't be allowed to happen.  I drug out the ladder, voltmeter, and screwdriver and dug into it.  There was no power getting to the SSR control circuit, so it shouldn't have been on, but the indicator led showed there was voltage on the output.  Sure enough, there was a little over 100V on the output.  Could this brand new SSR have failed already?  Fortunately, everything was fine.  I just didn't read enough about the devices.  They have transient suppression on them that is built right into the module.  This transient suppression will allow a little voltage to be seen on an open circuit.  So, the water heater had shut off by opening the switch that operates the heating element.  The SSR was off, but the suppression circuitry was allowing a little voltage through.  Nothing to worry about, but how to test it to be sure?

See, strange readings and unexpected results often happen when you're dealing with 240VAC circuits that use power at 15 - 25 amps.  Leakage of a few milliamps is expected and allowed for in this kind of circuitry for various suppression techniques.  The relay that used to do this job was a real mechanical open circuit, not a semiconductor.

Testing turned out to be simple; just drain enough hot water out of the tank to kick the mechanical heater switch, and then measure the voltage while the SSR was off.  Sure enough, when the element switch closed, the voltage on the output dropped to virtually nothing.  Everything was actually fine.  The little led indicator just doesn't draw enough current to suck it down to zero and will continue to glow.  I also noticed that the led was dim when the SSR was off and bright when the SSR allowed current through.  It's hard to tell the difference between the two levels, and I may look into the indicator at some point and see about correcting this.  It may just need a resistor in line or something.

No, I didn't waste the hot water.  I needed a bath anyway.

Saturday, March 2, 2013

Water Heater and Solid State Relays

A few times I mentioned the solar water heater I have.  It works great and keep me in free hot water most of the time.  Yes, it's the desert and during the summer the coldest the water gets is lukewarm, but I get 140F water out of the heater for zero continuing expense except for the few days where it is overcast.

Those overcast days present a problem.  A couple of times I turned the power on to the water heater and used the helper coil to heat the water because the sun just didn't come out.  Once, it pushed my power bill up because an X10 controller didn't react to the turn off command.  This prompted me to hook the water heater power to the garage controller I have.  This worked fine.  I'm able to send an XBee signal and turn on the water heater.  I also have code in the garage controller that shuts the heater down during peak periods. It's working really great except...

The contactor I have started to buzz.  It works fine, but there is a constant 60Hz buzz coming from it any time it's on.  The first time I heard it, I had to hunt for a while to figure out what it was.  Then, as the days went by, it got more and more annoying.  For those of you that have no idea what a contactor is, here's a picture of the one I have.


They're really nothing much more than a really big relay.  They have specially built contacts to survive high current switching and lots of places to hook wires.  They are probably all over your house and you don't know it.  Appliances have them, some fireplaces, environmental heating, etc.  Most of them run on a 24V coil and last a really long time.  In my particular case, I used a 110V coil because I was originally switching it with an X10 appliance module.  Unfortunately, the 110V units tend to make noise as they age.  They're not wearing out, they just start to rattle at 60Hz and drive you nuts.  There is a solution, use a solid state relay instead.

So, I got online and started looking for an SSR that could handle 25A at 240VAC.  There's a lot of them out there, but I need two of them, one for each leg of the power.  That made converting expensive, but I kept looking and found a SSR for 240 VAC three phase.  This gives me three of them in a package and I only have to use two of them.  I don't know if I'll ever need the spare, but it's there if I need it.  Here's the device I bought:


Notice that is has inputs for three circuits and one control for all of them.  This is exactly what I wanted.  So, when it came in, I took the entire control assembly off the wall and rebuilt it essentially from scratch.  Here's what it looks like on the wall:



Simple isn't it?  Just one device with the control signal coming in the top and hooking up on the left side.  It only takes a little over 4VDC to turn it on and it doesn't make any noise at all.  Since there are no contacts, it should last forever just sitting there working it's little heart out.  

I probably should have used one of these to begin with, but I didn't have a clue XBees even existed when I started out on these projects.  I was convinced by the advertising and various articles on the web that X10 would do the job.  

It's sad that I was that naive.

Wednesday, February 20, 2013

Battery Charging - Part 6


My float charger that is based on ideas I stole from the Harbor City 42292 device has gone through another iteration.  I decided to actually have a circuit board made that would hold the components and allow me to mount the board properly.  Using Eagle, I drew up a board which included the charger parts and everything necessary to support the XBee.  It was fun and came back looking like this:


It was so cool getting my first printed circuit board design back in the mail, so I rushed right in and assembled it.  Naturally, there were a lot of problems.  I hooked the voltage divider for the analog measurement to the wrong pin on the XBee and had trouble telling it was transmitting because I didn't include  troubleshooting lights to look at.  I got Eagle back up and changed the design, and ordered another board.


On this one I also increased the size of some of the traces and moved the voltage regulators around so I could use the heatsink I kept from the original charger.  So, I populated the board and hooked it to the lid of the box.  The entire device looks like this:


I happened to catch the leds on in the picture, but they are disconnected in a running device because they draw unnecessary power when it is actually in use.  It works real nice, and keeps the battery voltage at a constant 13.4 volts.  I've had several hand wired ones in place for months now and they are doing the job.

I'm still not done though.  I discovered a way to sense current being put out by the device.  I can put a hall sensor over a trace on the board that carries current and it will change output relative to the current flowing through the trace.  I doubt that I can tell the exact amount of current passing through the trace, but I can certainly tell if it is actually charging the battery.  This idea will take some development though and I don't know what components will be necessary for the final result, so I'll just assemble the rest of them and put them to work. I hope to get back to the hall effect device idea in a couple of months and work out the details.  The previous post on these devices is here <link>

I learned a lot creating the board, and I think I can develop boards for other ideas I have.  Things like a timer that will catch the time broadcast on my XBee network to operate lights and other devices would be great. It gets to be a real pain tediously connecting wires on a protoboard, especially when you want several identical devices.  Having an XBee network and something like this means I can finally get rid of the X10 devices that are so unreliable.  It would be so cool to completely switch over to XBee throughout the house.

Thursday, February 14, 2013

Still Wrapping up the Mega2560 Bootloader

More on the continuing drama of the 2560 bootloader.  Most recent post on this is here.

I just moved a lot of my code up to IDE 1.0.3 and decided to check and see if they had updated the bootloader in this.  Well, they haven't.  I just used it to program a 2560 and the bootloader supplied with the release failed on both the '!!!' and the watchdog timer problems.

But, I went searching to see if there was some schedule and ran across another bootloader that works.  This one is smaller because the author removed the code that samples for the '!!!' to jump into a rom monitor.  So, there is no problem with '!!!' because it doesn't look for it, and the watchdog timer works.  Plus, we get a little code space back (not that it matters on a 2560).  I tested it with several things and successfully loaded code that exceeds 60K (biggest I currently have) to the board.  The hex file is in text form here <link>.  If you want to get it and try it, just copy and paste it into notepad and save it as a .hex file.  I used an AVRISP mk 2 to replace the bootloader, I haven't tried any other device for programming the chip.


Here is the code I used to test the two problems notice the '!!!' in the Serial.print:


Code:
#include <avr/wdt.h>

void setup(){

  wdt_reset();   // First thing, turn it off
  wdt_disable();
  Serial.begin(57600);
  Serial.println("Hello, in setup!!!");
}

int firstTime = true;

void loop() {
      if (firstTime){
        firstTime = false;
        Serial.println("In loop waiting for Watchdog");
        wdt_enable(WDTO_8S);    // eight seconds from now the device will reboot
      }
      // now just do nothing
}

It's annoying that they haven't updated the IDE with a version that works.  But, there are a couple of solutions that work now.

Saturday, February 9, 2013

Using the XBee Library Part 3

Part 1 <link>, Part 2 <link>.

As part of my porting of my devices to the latest version of the Arduino IDE, I decided to move the devices to using the XBee library.  Back in part 1 I described why I suddenly took an interest to it, and since I was going into the code, I might as well start using it for real at the same time.  The changes to make my XBees receive packets using the library went without a hitch.  It just worked fine and reduced the code I had to write by a lot.  However, when I looked at transmitting data, I was appalled.  All the examples show something like:

XBee Tx Example

void loop() {
  // break down 10-bit reading into two bytes and place in payload
  pin5 = analogRead(5);
  payload[0] = pin5 >> 8 & 0xff;
  payload[1] = pin5 & 0xff;

  xbee.send(zbTx);

  // flash TX indicator
  flashLed(statusLed, 1, 100);


I mean REALLY??  Setting the bytes into an array one at a time?  Well, I went searching the web to see what else could be done and found dozens of examples of this kind of thing.  Here's one from the New SoftSerial example:

Another Example

void loop() {

  payload[0] = 'H';
  payload[1] = 0x7E;
  payload[2] = 0x11;
  payload[3] = 0x13;
  payload[4] = 0x7D;

  xbee.send(zbTx);


I even saw examples that had many bytes filled in one at a time to compose the data that needed to be sent.  Clearly, the examples need to be updated.  That's not something that is easy to do, but I can put an example here to show how a simple string, "Hello World" can be transmitted to another XBee without all the hassle. Here is an extremely easy way to do it:
My Tx Example
/*
XBee RX test for a Arduino Mega2560 using Serial3 as the XBee serial
input for a Series 2 XBee.  This is NOT based on the examples that come with
the Arduino XBee library.

See, the examples there and most other places on the web SUCK.  Andrew's
library is much easier to use than the illustrations would lead you to believe.

This is a HEAVILY commented example of how send a text packet using series 2
XBees.  Series 1 XBees are left as an exercise for the student.
*/

#include <XBee.h>

XBee xbee = XBee();
// This is the XBee broadcast address.  You can use the address
// of any device you have also.
XBeeAddress64 Broadcast = XBeeAddress64(0x00000000, 0x0000ffff);

char Hello[] = "Hello World\r";
char Buffer[128];  // this needs to be longer than your longest packet.

void setup() {
  // start serial
  Serial.begin(9600);
  // and the software serial port
  Serial3.begin(9600);
  // now that they are started, hook the XBee into
  // Software Serial
  xbee.setSerial(Serial3);
  Serial.println("Initialization all done!");
}

void loop() {
  ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)Hello, strlen(Hello));
  xbee.send(zbtx);
  delay(30000);
  strcpy(Buffer,"I saw what you did last night.\r");
  zbtx = ZBTxRequest(Broadcast, (uint8_t *)Buffer, strlen(Buffer));
  xbee.send(zbtx);
  delay(30000);
}



Yes, that's all there is to it; this example will compile and run using IDE 1.0.3 on a Mega2560.  Andrew made the library quite capable, but most people don't seem to want to look deeply enough into it to use it to advantage.  Notice that you fill in the Tx request with an address and then send the string pointer and its length to the XBee.  It's just that simple.  You can use a buffer and format it to be exactly what you want, then hand it off to the xbee.send() for transmission.  Really, really nice.

Remember though this example is for a mega2560 with four serial ports.  To do exactly the same thing on a UNO, just use SoftwareSerial as I described in part 1.  It will work equally well and you still have the Serial to output status and debugging information so you can see what is going on.

Suppose you want to send the packet to a specific XBee on your network, avoiding the problems that can happen with broadcast <link> it's actually really easy.  Just create another address like the one for Broadcast in the example above and use it instead.

Using this technique, I reduced a fifty or so line transmit routine down to:

How Simple It Can Be
XBeeAddress64 Broadcast = XBeeAddress64(0x00000000, 0x0000ffff);

void sendXbee(const char* command){
  ZBTxRequest zbtx = ZBTxRequest(Broadcast, (uint8_t *)command, strlen(command));
  xbee.send(zbtx);
}

Yes, I can compose the commands for my various devices and then just call sendXbee() with the string.  Simple, easy to read, and it works.

I like my little XBees more and more each day.

Thursday, February 7, 2013

Ethernet, Running Out of Connections

When I added thingspeak <link>as a repository for my data online, I started to notice that my House Controller <link> was freezing up and rebooting pretty often.  This isn't as bad a problem as one would think since the arduino only takes a few seconds to reboot and will continue right where it left off with only a minute or so worth of data lost.  However, it drove me nuts after a day or so of watching it randomly reboot for no apparent reason.

I moved the controller over to my breakfast table and plugged it into a laptop to monitor what was happening.  When the problem happened, it seemed to be at 10 minute intervals, but sometimes it would be at a minute interval.  What the heck?  I finally noticed that it was happening when the controller was doing a lot of internet interaction.  This made sense because I had recently added updates to thingspeak, so maybe I had screwed that up somehow.

Well, I finally had a brainstorm and realized that I was running out of connections on the ethernet card.  I use a 5100 based ethernet card for the arduino.  I use one of the older arduino ethernet cards, and I have heavily modified it so I can tell if the ethernet actually connects OK, and these devices only support four simultaneous connections..  See my page on the Thermostat <link> for details on the modifications I did. I connect to these devices using ethernet:  North home thermostat, South home thermostat, Dyndns to publish IP address, Dyndns to get my current IP address, Cosm, emoncms, thingspeak, and a connection for the web server that runs on the arduino itself. That's a possibility of eight connections, and somehow I must be using them all up.

I was.  I use timers for connecting to devices, and over time, I had too many of them trying to connect, or already connected at the same time.  The web server running on the little machine is always connected; the thermostats are connected every thirty seconds as clients; Cosm, emoncms, and thingspeak, connect every minute; Dyndns is connected every ten minutes and again a few seconds later if my external IP address changes due to my ISP.  Obviously, these were happening at the same time occasionally (often) and the board was running out of connections and pausing which caused the watchdog timer to fire.

I can't emphasize enough how useful timers are.  These little machines don't have an operating system that can handle scheduling tasks or switching between actions that some projects require.  You have to handle all this stuff yourself.  If you want something to happen at noon, you can either wait until your clock hits noon, or set a timer to check it for you.  If you are waiting, you can't do anything else.  Using timers to schedule things allows the little devices to behave like a machine many times its capabilities.  If you're into automating things, you should examine timers extensively.

What should I do?  There are lots of solutions, things like a table of connections that I can check to see if one is available, add a call to the ethernet library to tell me if I have a connection left to use, try and connect then check the return value for the right error, etc.  I decide not to do any of those.  Instead, I staggered the timers such that they split the minute up into intervals where each device could have a clear shot at getting a connection.  This should be fine since the various interactions only take a couple of seconds max and the odds of inserting a new bug using any of the other techniques was extremely high.  My original code to set up the various server interactions was:

Original Timer Setup

void initTimers(){
  
  Alarm.timerRepeat(30, updateThermostats); 
  Alarm.timerRepeat(60, updatePachube);     
  Alarm.timerRepeat(60, updateEmoncms);
  Alarm.timerRepeat(60, updateThingspeak);
  Alarm.timerRepeat(10*60,checkPublicIp);   
  
 /* other timers to control devices follow this */

So, you can see that every minute, I try to update at least 4 devices and every ten minutes, I add a couple more.  The odds of running out of connections (maximum 4) are high; it's a wonder the board stayed up for more than a couple of minutes.

There isn't any good solution to doing this differently using the same technique.  If I stagger the times, it will just be rebooting less often because they will eventually fall in the same couple of seconds; I know, I tried that first.  So, I redid the way the timers are set up:


Modified Timer Setup

void initTimers(){
  // I want the various timers to work on the minute boundary
  while(second() != 0){
    delay(500);
    doggieTickle(); // so the watchdog doesn't time out on me
  }
  // I have to stagger the timers for the ethernet
  Alarm.timerOnce(5, updateThermostats);                           
  Alarm.timerOnce(10, updatePachube);
  Alarm.timerOnce(15, updateEmoncms);
  Alarm.timerOnce(20, updateThingspeak);
  Alarm.timerRepeat(10*60,checkPublicIp);


First, I wait until the time hits a minute boundary by waiting until seconds == zero.  I have to keep the watchdog timer reset during this period to make sure I don't reboot the board.  Then I set timers for the offset from the minute boundary that I want for the various devices.  When these timers expire, I set timers for the next time the device is supposed to run.  For example, the thermostats are handled like this:

The Arduino Sketch

void updateThermostats(){  
// this will interogate the thermostats to make sure data is current

  Alarm.timerOnce(30, updateThermostats);  // check again in 30 seconds.

  getThermostat(0, "status", true);
  getThermostat(1, "status", true);
}


And, then when it cycles around again, a new timer will be set to do the same thing.  Basically, when I initialize the timers, I'm just kick starting an action that carries itself on after that.  This way the devices fire off at certain times within a minute so they don't conflict with each other as much, which should leave me with a free connection or two at all times.

Most people that do this kind of thing use a home computer to collect and forward data; that isn't a solution for me.  I don't want to tie up a large machine doing this kind of service since they can be useful for other things (surfing and games).  That's why I built the house controller in the first place.  Also, laptops and desktops take a long time to reboot and that doesn't go well with experimental software.  Mainly though, what the heck kind of pleasure is there in using a great big ol' machine to do something like this?

For my next project, I'm going to move this device up to the latest version of the arduino IDE.  I've been using IDE 21 for a long time now and the latest is 1.0.3 or something.  They changed a lot of stuff and redid most of the libraries, and I have changed some of the libraries to support my work, so this may be a challenge.