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

Friday, February 1, 2013

Outdoor Temperature Part 3

Part 1 is here <link>, part 2 is here <link>

I've been asked several times now how I mounted the temperature sensor to the XBee, and I didn't explain very well because I was too lazy to take a picture.  See, once I put it in a Stevenson Screen and mounted it on a fence post, it isn't as easy to get to as a lazy person like me would like.

Well, I got asked again and decided to bite the bullet and go open it up for a picture:

Simple huh?  One end of the sensor is hooked to 5V from the wall wart, the other end is to ground and the sensor output is connected to two 10K resistors in series to ground.  I take the center of the the two resistors to an XBee analog pin for transmission to my House Controller.  Notice the sophisticated nylon tie to mount the XBee?  Remember, this is all inside an open air enclosure that is screened on the inside to keep the darn birds from building nests inside.  It also keeps out rodents and bats (yes, I know bats are rodents).

The board is an XBee breakout board that has a 3.3V regulator on it to power the XBee, so I have access to both 5V and 3V to power whatever I need.  I've mentioned the wall wart several times on this blog, so look around a bit if you're curious.

There, now I can just point to a picture when people ask how I did it.