Sunday, March 11, 2012

First You Get The Sugar...

The pursuit of an alternative Davis Weather Station console is, and always has been, a three step process.  Homer Simpson breaks it down from that famed episode where he comes upon a big pile of sugar that he believes will make him a fortune.
Watch This, Or Nothing From Here On Will Make Sense

The intricacies of wireless RF transmission put a slightly different spin on any Scarface reference you might want to make, so let's look at it this way.

First you get the signal: I unlocked this achievement a little while ago when I used my Pretty Pink Pager to successfully receive a signal from the Davis Outdoor Integrated Sensor Suite (ISS) out in my yard.  A good start, but there was still a long way to go.

Then you get the data: This turned out to be rather tricky, and is the subject of today's post.

Quite some time ago, I looked at how the radio chip in the Davis console is configured for each frequency hop it makes.  That was all well and good, but as I dug deeper in actually trying to grab the data over the air, I realized that there were a few more things I'd need to figure out.

The CC1021 datasheet (for the RF chip in the Davis console) treats this subject pretty lightly, but once you delve into the CC1110 datasheet (the compatible RF chip in the Pretty Pink Pager), you hit David Rumsfeld's known unknowns.  That datasheet makes it clear that there is a lot more going on than just the data coming in over the air.  I figured out how to see the data a long time ago by using STRMON and a terminal program, but there is more to it than that. There are actually three parts to the transmission from the ISS that need to be sorted out.
  • Preamble.  From the CC1021 datasheet: "The recommended preamble is a ‘010101...’ bit pattern... This is necessary for the bit synchronizer to synchronize to the coding correctly."  This doesn't show up in the STRMON output.  How long is this bit pattern?  Where is it in relation to the data?
  • Sync Words. Again from the CC1021 datasheet: "The recommended sync words for CC1021 are 2 bytes (D391), 3 bytes (D391DA) or 4 bytes (D391DA26) and are selected as the best compromise of the above criteria."  Does the Davis system really use these recommended sync words?  If so, how many bytes do they use?  Where are they in relation to the data?
  • Data: I know what this is at any given time.  STRMON tells us that this is seven bytes of information plus an eighth byte for a checksum.  As we'll see in a bit, knowing what the data in the transmission is was critical in figuring out the other stuff.
All this unknown stuff is important if we want to build a compatible receiver.  Unlike the CC1021, the CC1110 lets you define a packet format to help you do the heavy lifting in decoding the incoming data stream.  We need to answer the questions above so the registers in the CC1110 can be programmed properly.  Unfortunately, the 1's and 0's don't appear on the SPI bus used by console's ATMEGA processor to configure the CC1021's registers.  That would be too easy.  The 1's and 0's show up on a separate pin called DIO (Data Input / Output), and are synchronized to a DCLK (Data Clock) pin.  If I was going to figure out the bitstream from the RF chip to the ATMEGA, I'd have to sniff this data.

My first attempt to do this did not go well.  I soldered a few wires directly to the console's processor in an attempt to break these lines out.  Something broke all right, and that was my console.  I had hoped it was just a blown LCD and ordered one of those up from Ryan at Archer Trading Post.  That didn't work, so I actually had to order up a whole new console.  Those are the breaks.  The new console arrived on Wednesday.  By Saturday, it looked like this.
Much To The Chagrin of My Lovely Wife,
This Is Our Kitchen Table
Note ancient ATI mousepad on the middle-right and the old school Micronta / Radio Shack analog multimeter top left.  I wish that meter would break so I could justify getting something that isn't older than some of the people reading this.  But it still works perfectly, and the manual I still have for it is in perfect condition.  I even still have the receipt: this baby set me back $29.95 back on August 20th, 1981.  But I digress.

I was a little more careful on my second attempt.  If you are going to try this (don't try this), here is the pinout you need to know.
CC1021 DCLK Pin 7 connects to ATMEGA (SCL/INT0) PD0 Pin 25
CC1021 LOCK Pin 9 connects to ATMEGA (SDA/INT1) PD1 Pin 26
CC1021 DIO Pin 8 connects to ATMEGA (ICP1) PD4 Pin 29
It was time to break out my $50 logic analyzer and try, try again.  I figured I didn't need to worry about LOCK.  But I did worry about something else: shorting some spins and frying another console.  The spacing between pins on the processor's TQFP package is a mere 0.8 mm, and I now know that new consoles don't come cheap.

With one hand I held a probe to the DCLK line, with my other hand I held a probe to the DIO line, and with my third hand I triggered the analyzer.  That third hand was actually that of My Lovely Wife, without whom I would have been well and truly screwed once again.  It worked, and this was what I got.
Sniffing CC1021 DIO / DCLK Data, Very Carefully.  Click To Embiggen.
Let's take a little closer look at that first bit around the trigger point.  Things are looking pretty good so far.
I Got A Clock.  I Got Some Data.
I was running STRMON and capturing its data at the same time.  The last stuff that scrolled across the screen when the capture taken above was done looked like this.  But...
What In Here Am I Looking For?
I had a bunch of questions to sort out before I could decode all of this.  First, I wasn't exactly sure what chunk of the capture log corresponded to the data I had collected.  Second, I didn't know how to sync up in the bitstream above to know where to start calculating the corresponding bytes.  Third, I wasn't sure of the bit order of the datastream, whether there were any parity or stop bits, etc.  This was going to be harder than I thought.  I had to turn my brain into a fuzzy pattern matching machine.

Since I had the STRMON data, I would start looking for the eight data bytes and then look for the Sync and Preamble bytes after that.  What helped was finding a spot in the bitstream where there were eight or nine 1's followed a short while later by eight or nine 0's.  There was some data in the capture log that had an 0xff byte, followed by something else, followed by a 0x00 byte.  It took a while and I went down several blind alleys, but I finally sorted it out.


corresponds to this...

Here are the key points to know:
  • The eight data bytes (six plus two byte CRC) appear in the bitstream as numbered in the STRMON output
  • Each byte is Least Significant Bit (LSB) first.
  • The data is taken on the rising edge of DCLK
So decoding the datastream above, we have to think it through like this.
LSB Order   Byte    MSB Order   Time After Trigger
00000110    0x60    01100000    8.125 ms
11000000    0x03    00000011    8.540 ms
01010101    0xaa    10101010    8.960 ms
11111111    0xff    11111111    9.375 ms
10000011    0xc1    11000001    9.795 ms
00000000    0x00    00000000    10.210 ms
10011011    0xd9    11011001    10.625 ms
10001000    0x11    00010001    11.045 ms
Here is a closeup of the first data byte to help you see what I'm talking about.
First Byte of Data
Looking from marker T2 and going by the rising edge of the clock, you get:
0 0 0 0 0 1 1 0
That is LSB order. So we reverse the bit order to get the more conventional MSB order.
0 1 1 0 0 0 0 0
That is 0x60, our first byte in the table above.  Going from there to the right, each byte works out exactly.  There is no Start Bit, Parity, or Stop Bit.  Booya.

Next thing we need to sort out is the Sync bytes.  Remember from above that what we are looking for is probably something that looks like D391DA26 or less.  It turns out the Sync bytes look like this.
Sync Bytes
What this capture tells us is this:
  • The Davis system uses only two Sync bytes
  • The Sync bytes are 0xD3 followed by 0x91
  • The two Sync bytes immediately precede the data bytes.  There is no gap between them.
Looks like we are on a roll.  We should dive into the Preamble bytes while our luck holds.  Remember that "The recommended preamble is a ‘010101...’ bit pattern".  But how many bytes?  This many.
Preamble Bytes
What this capture tells us is this:
  • The Davis system uses four Preamble Bytes
  • The Preamble is more correctly a '101010...' pattern if we don't do a LSB to MSB conversion (and we shouldn't in this case)
  • The four Preamble bytes immediately precede the Sync bytes.  There is no gap between them.
The reason I mentioned above that we shouldn't convert from LSB to MSB in the Preamble is because this isn't really data.  But more importantly, take a look at this from the CC1110 datasheet.
CC1110 Packet Format
You'll want to click on that bad boy to enlarge it, but you'll note that the CC1110 expects a Preamble to have a pattern that starts with '1010...', not '0101...'.  The pattern also has some integer number of bytes and is expected to butt right up against the Sync word.  In other words, it looks like the Davis system is compatible with the CC1110 packet format.  This is great news.  The CC1021 had no such mechanism to enforce policy like this.  It was up to the Davis firmware programmers to manage each and every bit that spewed forth from the CC1021.  Life should be a lot easier getting the CC1110 to do it in our alternative receiver.

The sharp eyed amongst you will notice that there is some stuff going on on either side of the Preamble, Sync, and Data bitstream in those first couple screen captures.  I haven't dug into this yet, but my suspicion is that this is there for a couple reasons:
  • allow the CC1021 to detect and lock on to the carrier when it first starts being transmitted from the ISS
  • allow the console to determine the frequency error on the signal transmitted from the ISS so it can precisely tune to the signal and minimize bit errors
I still have to dig into this part of it, but I've got a plane to catch this afternoon and I haven't started packing yet.  The next step in using this information to pull data into the Pretty Pink Pager will have to wait for another day.  In the meantime, let's reflect on the wisdom of Homer Simpson on the third step of this process.

Then you get the women: That is pretty much automatic when you do cool stuff like this all weekend.  Have a good one.


  1. You da man , i have been searching for this data. I have often wondered if the folks at Davis would have done better to consider open architecture and letting the community use their products as they wish. Now the cat is out the bag. Thanks.

  2. @DeKay, Great stuff! Thanks for your hacking. I have two consoles, but no ISS. My 6152 console is wireless but the PCB clearly shows where the RJ11 connection would be with the cabled version. I'm collecting WU data from a neighbor. Do you think it would be possible to feed that data on the RJ11 connections at the 19K boud you have identified elsewhere? I would like to bypass the radio tx/rx.

    1. I found your protocol.txt file on Github. BIG help! Next I'll probe the RJ11 port for connections to SDA & SCK on the Atmel chip. Then ... what the hell, I'll just try throwing some faux-data (I2C) at the console and see what comes up on the screen. I found the RJ11 GND easily and there appears to be no vcc connection so I presume the "cabled" console depends on the ISS to be indepently powered. Any ideas or help are welcome!