Author Topic: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions  (Read 63625 times)

0 Members and 1 Guest are viewing this topic.

Offline EA1EF

  • Senior Member
  • **
  • Posts: 98
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #100 on: November 16, 2014, 12:18:04 PM »
a good antenna for all type of test and mods are PCB 3 element from http://www.wa5vjb.com/  have 868Mhz for europe models and 900mhz for USA ISM Band

http://www.wa5vjb.com/pcb-pdfs/Yagi900.pdf

(also sold in europe by http://g4ddk.com/ )

I test this antenna radomized hide in rain sensor with good results)

Offline AnOldFella

  • Member
  • *
  • Posts: 16
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #101 on: November 19, 2014, 12:00:57 PM »
I'm adding a DHT22 to my project, but I'm confused about how to wire it correctly.  On DeKay's summary blog, it shows
"DHT22 Pin 1 -> Moteino 3.3V Out
DHT22 Pin 2 -> Moteino D4 with 10K Pullup resistor to Moteino 3.3V Out
DHT22 Pin 3 -> Not connected
DHT22 Pin 4 -> Moteino GND".

My confusion comes from the differences between DeKay's set up and the Data Sheets on Adafruit and SparkFun.  The circuit diagram on the Data Sheet at SparkFun shows a 1K resistor between Power and DHT22 Data, but the written portion of the Data Sheets from both Adafruit and SparkFun state "One capacitor valued 100nF can be added between VDD and GND for wave filtering."  The DHT22 came with a 10K resistor, but no instructions.  Any help understanding all this would be greatly appreciated.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #102 on: November 19, 2014, 12:17:21 PM »
The exact value of pullup doesn't matter. 1k or 10k should be good. It only prevents the input from "floating" by pulling it near Vcc. Or you could leave out the pull-up entirely.
« Last Edit: November 19, 2014, 12:19:51 PM by kobuki »

Offline DeKay

  • Forecaster
  • *****
  • Posts: 399
    • Mad Scientist Labs
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #103 on: November 19, 2014, 07:50:51 PM »
The exact value of pullup doesn't matter. 1k or 10k should be good. It only prevents the input from "floating" by pulling it near Vcc. Or you could leave out the pull-up entirely.

I'd hesitate to leave the pullup out altogether.  To say it "only" prevents the input floating is actually quite important.  The DHT22 is known for being a bit of a fickle beast.

AnOldFella: The 10K value has given me dependable operation so you should be fine with that.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #104 on: November 19, 2014, 08:01:03 PM »
It might depend on the actual sample, but 2 different pieces worked without problems for me. I'm aware of the importance of pull-ups, and using one doesn't hurt. But we're getting a little off-topic here.

Offline BCJKiwi

  • Forecaster
  • *****
  • Posts: 302
    • Silver Acorn Weather - N.Z.
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #105 on: November 19, 2014, 08:18:09 PM »
The I2C specification requires a Pullup resistor.
The ideal value depends on;
Supply voltage, Clock frequency and Bus capacitance (type and length of cable).

You may well get away without adding one to the Bus if the Master (typically the microcontroller or I2C I/O device) has pull-ups built into the port but you would need to know this is the case and that it is a suitable value else the circuit may be unstable.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #106 on: November 19, 2014, 08:24:39 PM »
Yeah, though the DHT22 is not I2C. It uses some proprietary serial protocol. And we're talking about very short wires on a breadboard. But yes, always use a pull-up according to specs.

Offline ct

  • Contributor
  • ***
  • Posts: 101
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #107 on: November 20, 2014, 03:09:29 AM »
I have built a DIY weather station using an Arduino and some Davis sensors, such as the rain bucket and anemometer, but it has no console. 

With the work that Dekay has done, it is possible to send weather data to a Davis console?

I like Davis hardware, but prefer using my own microcontroller for increased flexibility.  Davis communiction accessories are also very expensive.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #108 on: November 20, 2014, 05:28:35 AM »
So you have a console but not an ISS/SIM? Yes, it's possible to send data from the individual sensors. I've made an anemometer transmitter (using a Moteino). It could be used as a basis for other sensors, source is available, if that's what you have in mind. I want to make it more power-friendly because the current implementation expects the CPU to be alive all the time. I'd suggest opening a new thread for this kind of stuff.

Offline ct

  • Contributor
  • ***
  • Posts: 101
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #109 on: November 20, 2014, 08:46:26 PM »
So you have a console but not an ISS/SIM?

A already have a VP1, but have built a DIY station for another location.  I was wanting to use some kind of console, preferably a Davis console which I would buy if it is possible to send data to it.

Offline DeKay

  • Forecaster
  • *****
  • Posts: 399
    • Mad Scientist Labs
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #110 on: November 20, 2014, 10:48:07 PM »
So you have a console but not an ISS/SIM?

A already have a VP1, but have built a DIY station for another location.  I was wanting to use some kind of console, preferably a Davis console which I would buy if it is possible to send data to it.

There is probably enough data on my blog to figure out how to do it, but nobody to my knowledge has actually done it yet.  I gave it a shot once and didn't get it to work, but I didn't spend much time playing with it either.  One reason might be that Davis does some funky stuff after the data in the packet has been transmitted that I haven't dug into yet.

Lots of things to do.  Not a lot of time.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #111 on: November 21, 2014, 04:42:47 AM »
A already have a VP1, but have built a DIY station for another location.  I was wanting to use some kind of console, preferably a Davis console which I would buy if it is possible to send data to it.
If you're willing to buy a VP2 or a Vue console, yes, it's possible as I've already mentioned in my previous post. I have working SAT (Standalone Anemometer Transmitter) code you could use as a base if you're interested. It would be wise to test it first though on a test console you can borrow or something, athough it should work without problems. The transmitter code is a modified version of DeKay's receiver, btw. Of course, I'm willig to help and interested in your progress, should you ever start on this project.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #112 on: November 21, 2014, 05:05:43 AM »
There is probably enough data on my blog to figure out how to do it, but nobody to my knowledge has actually done it yet.
Well, I did (for the VP2, not the VP1, of course). I exchanged some PMs with you on the subject this spring and have mentioned it in several forum threads too. Never mind.

Offline ct

  • Contributor
  • ***
  • Posts: 101
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #113 on: November 21, 2014, 05:08:35 AM »
. I have working SAT (Standalone Anemometer Transmitter) code you could use as a base if you're interested.

Yes, I'm very interested in what you have done.  Is the code available somewhere?

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #114 on: November 21, 2014, 05:16:06 AM »
Yes, I'm very interested in what you have done.  Is the code available somewhere?
Sure, it's in a branch here. It's a branch of DeKay's stuff, but I'll prolly make it a standalone repo sometime soon, since now I have a different approach in mind than a console emulator. The current transmitter code needs to be a little more power-friendly. I have a plan for that in mind but no time to code.
« Last Edit: February 27, 2015, 12:30:57 PM by kobuki »

Offline DeKay

  • Forecaster
  • *****
  • Posts: 399
    • Mad Scientist Labs
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #115 on: November 21, 2014, 05:59:40 PM »
There is probably enough data on my blog to figure out how to do it, but nobody to my knowledge has actually done it yet.
Well, I did (for the VP2, not the VP1, of course). I exchanged some PMs with you on the subject this spring and have mentioned it in several forum threads too. Never mind.

Proof once again that my memory is absolutely horrible.  :-)

Offline Bushman

  • Forecaster
  • *****
  • Posts: 7549
    • Eagle Bay Weather
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #116 on: November 21, 2014, 06:24:21 PM »
 "A Waste Is A Terrible Thing To Mind" :)
Need low cost IP monitoring?  http://wirelesstag.net/wta.aspx?link=NisJxz6FhUa4V67/cwCRWA or PM me for 50% off Wirelesstags!!

Offline cmatteri

  • Member
  • *
  • Posts: 11
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #117 on: February 22, 2015, 07:54:56 PM »
I would first like to thank everyone who has helped discover and document the wireless protocol used by Davis.  One of the main reasons I chose Davis products for my project was that I could inexpensively access the data computationally.

I needed to receive data from multiple weather and soil moisture/temperature stations, so I initially modified Dekay's DavisRFM69 library to keep track of up to 8 transmitters.  The range on the Moteino with the included antenna was inadequate for my project, so I rewrote the receiver code to work with a CC1101-CC1190 evaluation module from TI (http://www.ti.com/tool/cc1101cc1190emk915).

I figured out how the Davis Leaf and Soil Moisture/Temperature Stations encode their data.  I'll add that information to the wiki.

My project's code is posted at https://github.com/cmatteri/CC1101-Weather-Receiver/.  Instead of processing the packets on the microcontroller, I send them to a linux host and process them in weewx drivers.  The code is still alpha.

For anyone interested in using the CC1101-CC1190 EM, they are $50 a piece, but only come in pairs.  The connection to the module is a 1.27 mm header, so I used a PCB to connect it to an Arduino.

I didn't know about rdsman's CC1101 code until several days ago.  I based all of the radio settings off of Dekay's work.  Interestingly, several of the radio parameters differ between Dekay's and rdsman's work.  The DEVIATN register setting on the Vue console is 0x24.  Assuming the crystal frequency is 26 MHz, the deviation is 26e6 / 2^17 * (8 + 4) * 2^2 = 9.5 kHz.  In the IM-ME and DavisRFM69 libraries, the deviations are 4.5 kHz and 4.8 kHz, respectively.  Dekay, could you have miscalculated the deviation on the CC1021?  If not maybe Davis got it wrong on one of them, or I'm missing something. 

The MDMCFG4 register on the Vue is set to 0xC9, giving a channel filter bandwidth (ChBW) of 26e6 / (8 * (4 + 0) * 2^3) = 101.6 kHz.  The setting on the IM-ME is the same (though the crystal frequency on the IM-ME is 27 Mhz so they're not exactly the same, but they're as close).  The ChBW in the DavisRFM69 lib is 25 kHz (it is the one sided bandwidth.  I believe ChBW for the TI chips is double sided).  Section 12.2 of the CC1021 datasheet describes how to estimate the minimum ChBW.  The minimum ChBW with a 10 ppm crystal would be 19.2 kHz + 2 * 9.5 kHz + 4 * 10 ppm * 915 MHz = 74.8 kHz.  I believe the ChBW for the RFM69 should be increased.

The frequencies sniffed by Dekay from the VP2 console and by rdsman from the Vue console are off by about 30 kHz.  Observing the value of FREQEST on my receiver with both Dekay's and rdsman's frequencies shows an error of about 15 kHz for both frequencies, but in opposite directions.  Frequency compensation must be performed by the microcontroller for the CC1012 (section 12.13 of the datasheet), so it is possible that the sniffed frequencies included an offset calculated to compensate for error/drift in the crystals of the consoles and weather stations used by Dekay and rdsman (though there is a dedicated offset register on the CC1101, so that wouldn't be necessary, but perhaps they are reusing code, or perhaps rdsman read the nominal frequencies and the error I'm showing is due to my crystals being off).  Probably the only way we're going to find the nominal frequencies is to have more people report the error they're observing.  With the large channel filter bandwidth and automatic frequency offset compensation, either set of frequencies seems to work.  I plan to implement permanent frequency compensation based on FREQEST readings, which would negate offset errors in the frequency table, but it would still be nice to know the nominal frequencies.

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #118 on: February 22, 2015, 08:19:22 PM »
Cmatteri, great work. I've also spent a lot of time coding/testing Davis competible receivers, using Moteinos. My code is based on Dekay's original work, and I've also written code for configuring and receiving up to the max. 8 stations. You can see an older version of my code on Github. I'll commit newer, updated code soon.

I'm very surprised you found the reception abilities of the Moteino's RFM69 inadequate. There is no antenna included in the package, just a piece of wire you can solder on or you can attach a factory-made antenna in some way. I've done both, with somewhat better and more stable RSSI using rubber duck dipoles. My Moteino receiver is far better in reception quality and dropped packets ratio than the original Davis Envoy I have. A product called Meteostick is also using this receiver module.

You observed a few interesting things about radio paramteres. I've been strugling with a Moteino-based Davis compatible transmitter recently, and I'll try to employ some of your findings - I wonder if I can finally create a stable Moteino transmitter.

Keep up the good work, and please update us if you make any progress.

Offline cmatteri

  • Member
  • *
  • Posts: 11
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #119 on: February 22, 2015, 11:17:07 PM »
I only used the Moteino with wire monopole it came with.  It wasn't working with a station that was about 700 ft away, with the receiver inside a window, and we're adding new stations that will be even further.  I could try using different antennas, but those would also improve the module I'm using right now, and the CC1190 gives an additional range boost.

I should have posted earlier.  It's amazing how much of other peoples' work I missed while searching for what had been done with Davis receivers.  I'll try to stay more in the loop going forward.  Hopefully the wiki will make it easier for new people to find what's been done.  It will be fun to compare our implementations for tracking multiple stations.
« Last Edit: February 22, 2015, 11:20:41 PM by cmatteri »

Offline cmatteri

  • Member
  • *
  • Posts: 11
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #120 on: February 23, 2015, 02:49:11 PM »
I believe I have made an additional discovery about message_9.  The upper nibble of byte 5 (byte5[7:4]) appears to indicate the interval between message_9 transmissions to which the max wind speed in byte3 corresponds.  E.g. if byte5[7:4] is 0, then the max wind speed occurred in the time since the previous message_9, if it is 1, it occurred between the previous message_9 and the message 9 before that.

When byte3 increases, byte5[7:4] always goes to 0.  Sometimes byte5[7:4] goes to 0, but byte3 remains unchanged.  This would indicate that the wind rose to the speed in byte3 again in the previous interval.  byte3 only ever decreases after byte5[7:4] is 9.  This makes sense if byte3 is the max wind speed in the last 10 message_9 intervals.  When byte3 does decrease, byte5[7:4] is often set to a nonzero value less than 10.  This makes sense too because the new max wind speed could have occurred in any of the last 10 intervals.

It doesn't look like the ISS gives us the direction of the max wind speed.  If we keep track of the direction of the wind between message_9 intervals, we can at least know the wind direction during the interval (the length of which depends on the transmitter ID) that the max wind was from.  If the max wind was ever in byte1 of any packet, then we know exactly what the direction was.

Here are a bunch of message_9s for anyone who wants to confirm this:
https://drive.google.com/file/d/0B-dARPEa08c9bnZQejdVZjB6Z0U/view?usp=sharing
« Last Edit: February 23, 2015, 03:07:07 PM by cmatteri »

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #121 on: February 23, 2015, 04:36:22 PM »
Without analysing your data thoroughly, but assuming that the upper nibble of byte 5 is always between 0..9, are you suggesting that it is a backreference to the current wind gust speed out of the last 10 ones? I guess it would make sense. I have a simple graph of the 3 wind data values superimposed, and it might explain why the wind gust values come in in an odd manner. I'm attaching the graph for the last 6 hours so you can see what I'm talking about.

Offline cmatteri

  • Member
  • *
  • Posts: 11
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #122 on: February 24, 2015, 01:42:45 AM »
I'm not sure what you mean by backreference to the current wind gust speed, so I'm not sure if we're on the same page.  I'll elaborate on my thoughts.

Peak wind speed is an important reading.  Everyone wants to know the maximum wind that was detected on their station.  If the protocol relied on the wind speed transmission in each packet, the peak wind could occur between packets.  So a separate packet is used to transmit the max wind speed (message_9).  But if message_9 only transmitted the max wind speed since the last message_9, then a single packet being missed could mean a potentially very interesting max wind reading is lost.  By transmitting the max wind speed over the last 10 message_9 intervals, you get 10 chances to get an interesting reading to the receiver.  That gives you a fairly good system, but it it's hard to tell exactly when the gust occurred.  That's what the index in byte5[7:4] tells us--which of the last 10 message_9 intervals the max wind reading occurred in.

I'm not sure why the gust speed is zero when the wind speed is not in your plot.  Shouldn't the gust speed be at least as high as the average wind speed?

Offline kobuki

  • Forecaster
  • *****
  • Posts: 838
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #123 on: February 24, 2015, 05:30:41 AM »
OK, you described exactly the same observation with slightly different words. First, AFAIK, packet type 9 contains wind gust values. We can assume I have a good understanding of what you want to say. When you refer to a previous value in one packet in the previously received stream of packets of a certain type, it can be called a backreference - a reference to a value that has already been measured and stored or buffered for later retrieval; it is not a current value, but a value from the past. It can still be interpreted as a maximum value for a certain period of time. That is basically the definition of wind gust.

I'd like to understand it fully so I can potentially add this bit to my own code. So if you think I still haven't grasped the gist of what you want to say, please elaborate more, or try to draw an explanation if your time allows. It might be beneficial for others following this thread, too.

OTOH, wind gust values in packet type 9 packets are transmitted for every 20th packet, so their interval is (depending on station ID) somewhere between 51 secs and 1 minute. Yes, they can be lost. My assumption up till now was the same for this type of packet as for all others: values can be lost by missing a reception and the last known valid value (potentially including your proposed algoritm) can be repeated or dropped. In the case of a wind gust value, I think it should be just dropped, since it's among the 3 rarest packet types.

About my plot: yes, that's a good question :) In the interpretations I've seen so far the wind gust value is assumed to be equal to the last sensed wind speed value (contained in every packet) if it's correctly received and is zero (I can't recall if the gust calculation interval is considered for this case, though). Your proposed algorithm with that certain nibble might shed some light on it, but I'm not sure.

My post has become rather long, but finally let me ask a question: are you sure that barring factory interpretation of the values without original Davis equipment will be sufficient for your needs? You mentioned simple temperature measurements but we've been posting about wind gust interpretations for some posts now... There exist of the shelf, cost-efficient third party solutions for receiving up to 8 stations simultaneously.
« Last Edit: February 24, 2015, 05:48:32 AM by kobuki »

Offline DeKay

  • Forecaster
  • *****
  • Posts: 399
    • Mad Scientist Labs
Re: A Walk on the Wireless Side: Deciphering ISS to Console Transmissions
« Reply #124 on: February 24, 2015, 09:35:07 PM »
I figured out how the Davis Leaf and Soil Moisture/Temperature Stations encode their data.  I'll add that information to the wiki.

<snip>

My project's code is posted at https://github.com/cmatteri/CC1101-Weather-Receiver/.  Instead of processing the packets on the microcontroller, I send them to a linux host and process them in weewx drivers.  The code is still alpha.

Thanks for figuring this stuff out and for sharing!  It would be great if you'd update the wiki with what you've learned.  I get pretty psyched when I see other people dig into this stuff and contribute improvements.

I based all of the radio settings off of Dekay's work.  Interestingly, several of the radio parameters differ between Dekay's and rdsman's work.  The DEVIATN register setting on the Vue console is 0x24.  Assuming the crystal frequency is 26 MHz, the deviation is 26e6 / 2^17 * (8 + 4) * 2^2 = 9.5 kHz.  In the IM-ME and DavisRFM69 libraries, the deviations are 4.5 kHz and 4.8 kHz, respectively.  Dekay, could you have miscalculated the deviation on the CC1021?  If not maybe Davis got it wrong on one of them, or I'm missing something. 

Feel free to check my math.  From the spreadsheet in the linked post, you'll see how all the other numbers check out when a crystal frequency of 14.7456 MHz is used in the VP2 console.  It is very possible that I missed out on the one sided vs. two sided bandwidth bit you mention below.

As it sounds like you are aware, there are also two versions of IM-ME out there, BTW.  I think one of my blog posts stated which mine was but it was different from most of the rest.  I think it might have to do with the fact that I ordered mine out of the UK vs. North America.

The MDMCFG4 register on the Vue is set to 0xC9, giving a channel filter bandwidth (ChBW) of 26e6 / (8 * (4 + 0) * 2^3) = 101.6 kHz.  The setting on the IM-ME is the same (though the crystal frequency on the IM-ME is 27 Mhz so they're not exactly the same, but they're as close).  The ChBW in the DavisRFM69 lib is 25 kHz (it is the one sided bandwidth.  I believe ChBW for the TI chips is double sided).  Section 12.2 of the CC1021 datasheet describes how to estimate the minimum ChBW.  The minimum ChBW with a 10 ppm crystal would be 19.2 kHz + 2 * 9.5 kHz + 4 * 10 ppm * 915 MHz = 74.8 kHz.  I believe the ChBW for the RFM69 should be increased.

If my bandwidth is too narrow, this might explain why some people report problems with the odd channel not working right.  If one frequency is out a bit from the rest, maybe it gets chopped off vs the others.

The frequencies sniffed by Dekay from the VP2 console and by rdsman from the Vue console are off by about 30 kHz.  Observing the value of FREQEST on my receiver with both Dekay's and rdsman's frequencies shows an error of about 15 kHz for both frequencies, but in opposite directions.  Frequency compensation must be performed by the microcontroller for the CC1012 (section 12.13 of the datasheet), so it is possible that the sniffed frequencies included an offset calculated to compensate for error/drift in the crystals of the consoles and weather stations used by Dekay and rdsman (though there is a dedicated offset register on the CC1101, so that wouldn't be necessary, but perhaps they are reusing code, or perhaps rdsman read the nominal frequencies and the error I'm showing is due to my crystals being off). 

I'm about 99% certain that this is the case.  One of my blog posts tries to figure out a pattern in the frequency hops, but I never got it as close as I'd have expected.  I'm pretty sure the console just writes raw frequency registers to the CC1021 without using any kind of offset correction programmed in.

Probably the only way we're going to find the nominal frequencies is to have more people report the error they're observing.  With the large channel filter bandwidth and automatic frequency offset compensation, either set of frequencies seems to work.

There are a few other ways I can think of
-  set the console to factory defaults and sniff the SPI bus as the console started hopping after that.  The console does store the error for each frequency.  After a reset, the offsets it uses should all be zero and the commanded frequencies would be nominal. 
- figure out how in the code the console calculates the frequency in the first place. C5250 had some of that code disassembled but it got a little hairy.
- sniff the radio chip in the ISS !

I plan to implement permanent frequency compensation based on FREQEST readings, which would negate offset errors in the frequency table, but it would still be nice to know the nominal frequencies.

I wanted to do this on the Moteino but had trouble getting it working.  Just another item on my long list of things to do that I never seem to get to, unfortunately.

And great work, BTW   =D&gt;