Skip to content
dekay edited this page Jan 24, 2015 · 13 revisions

Introduction

What is DavisRFM69?

DavisRFM69 is the result of efforts to reverse engineer the wireless transmissions by Davis Instruments in their weather stations, specifically their Integrated Sensor Suite (ISS) and the Vantage Pro2 (VP2_ Weather Station console. A newer product, the Davis Vantage Vue, is a more integrated product with a few new messages added in, but is otherwise compatible.

RF Transmission

The system uses frequency-hopped spread spectrum for its transmission. That might sound scary, but it isn't. In a nutshell, here is how it works

  • the ISS transmits a packet at one frequency, goes into a low power mode, and then wakes up and transmits its next packet a short time later.
  • the ISS is set to one of eight different channels. All this does is change the timing between the packets.
  • The sequence of frequencies is always the same for a given setup, but the number of frequencies varies according to the region in which the console was sold. For example, North American consoles use a set of 51 frequencies in the 915 MHz band, whereas consoles sold in Europe use only four frequencies in the 868 MHz band.

The VP2 ISS uses a CC1020 chip to transmit the data in Gaussian Frequency Shift Keying (G-FSK) format. That also is not as scary as it sounds. Basically, the carrier is modulated by one of two tones representing a 0 bit or a 1 bit. The CC1020 is transmit-only, whereas the CC1021 in the VP2 Console can either transmit or receive. Davis did this to allow the console to act as a repeater that can relay data from one console to another.

The Vantage Vue uses a newer variant of this chip that offloads a lot of the packet processing from the console's processor while maintaining compatibility between the older system and the newer one. This allows a VP2 console to receive transmissions from a Vantage Vue.

Packets are sent from the ISS every 2.5 seconds for an ISS set to a transmit ID of zero. The rate gets slower as the transmit ID increases by 1/16 of a second for every station ID number e.g. ID 1 transmits at an interval of 2.5625 seconds (ref: Davis Serial Protocol document). The data rate is 19.2 kbps and is transmitted from the ISS with the least significant bit first. More here.

Protocol

This section describes the protocol used by the Davis Weather wiressless Integrated Sensor Suite (ISS) to communicate its readings back to the console.

The starting point for reverse engineering the protocol is the output from the STRMON command when connected to the console with an LVTTL serial connection. This connection is discussed in detail in: http://madscientistlabs.blogspot.ca/2011/01/davis-weatherlink-software-not-required.html. Let's use the following STRMON snippet as an example.

0 = 60
1 = 6
2 = d3
3 = ff
4 = c0
5 = 0
6 = 78
7 = 75

The eight bytes come from the ISS in this order. However, each byte comes in from the ISS with least significant bit first. The bit order has to be flipped before we can work with it. All values in the example above are in hex.

Byte 0: This is a header. The upper nibble is the sensor the data is from, as follows. Some of these messages are Vantage Vue specific.

2 = Supercap voltage (Vue only)
3 = ?
4 = UV Index
5 = Rain rate
6 = Solar radiation
7 = Solar Cell output (Vue only)
8 = Temperature
9 = Wind gust
a = Humidity
e = Rain

The lowest three bits in the low order nibble is the transmitter ID, set via dipswitches inside the unit.

Bit 3 in the low order nibble of byte 0 indicates if the transmitter battery is low. The bit is set to zero if the battery is OK, but is apparently only set if the transmitter needs to run off the battery and not the solar-charged supercap.

Byte 1: Wind speed in mph. Wind speed is updated every transmission. Simple.

Byte 2: Wind direction from 1 to 360 degrees. Wind direction is updated every transmission. The wind reading is contained in a single byte that limits the maximum value to 255. Davis says that 0 indicates it can't get a reading, so you'd never see wind straight out of the North unless your wind vane is broken.

Wind direction is treated differently between the VP2 and the Vue because of the different types of sensors used between the two units. The VP2 uses a potentiometer with a significant dead zone around North. No values are reported between 8 and 352 degrees inclusive. These values correspond to received byte values of 1 and 255 respectively. So for a VP2...

if (byte2 == 0)
  windDirection = 360;
else
  windDirection = 9 + byte2 * 342.0 / 255.0;

The Vue uses a Hall Effect sensor and this dead zone is significantly reduced. [This is the code](http://www.wxforum.net/index.php?topic=21967.msg213307#msg213307 WXForum) for calculating the wind speed for the Vue.

if (byte2 == 0)
  windDirection = 360;
else
  windDirection = (byte2 * 1.40625) + .3;

Byte 6: High byte of the 16 bit CRC (0x78 in our example above)

Byte 7: Low byte of the 16 bit CRC (0x75 in our example above)

The CRC is the same as that on the serial interface and is documented in the Davis "VantageSerialProtocolDocs_v230.pdf" document. The first six bytes can be run through the calcuation and checked against the seventh and eight bytes. Alternatively, all eight bytes can be run through the calculation and the result will be zero if the CRC is valid. My code uses this CRC algorithm.

Bytes 3 - 5: Depend on the sensor being read at the time. Need to work through these. This is what is known now.

Message 2: Supercap voltage (Vue only)

Bytes 3 and 4 are for reporting the Supercap voltage. The Supercap is a "super" capacitor that stores excess energy from the ISS solar cell during the day, which is then used to help power the console at night. This design is very effective in extending the life of the non-rechargeable lithium CR2032 battery in the outdoor unit. Both the VP2 ISS and the Vue have a Supercap, but only the Vue reports its status. [Dario has determined](http://www.carluccio.de/davis-vue-hacking-part-2/ Dario's Blog) that the value is reported over a range of 3V to 8V and is calculated as follows:

voltage = ((Byte3 * 4) + ((Byte4 && 0xC0) / 64)) / 100

Message 4: UV Index

Bytes 3 and 4 are for UV Index. The first byte is MSB and the second LSB. The lower nibble of the 4th byte is always 5, so they only use the first three nibbles. A value of FF in the third byte indicates that no sensor is present.

The UV index is calcuated as follows as discussed [here](http://www.wxforum.net/index.php?topic=18489.msg178506#msg178506 WXForum) and [here](http://www.wxforum.net/index.php?topic=18489.msg190548#msg190548 WXForum).

UVIndex = (byte3 << 8 + byte4) >> 6) / 50.0

Message 5: Rain Rate

Bytes 3 and 4 contain the rain rate information. The rate is actually the time in seconds between rain bucket tips in the ISS. The rain rate is calculated from the bucket tip rate and the size of the bucket (0.01" of rain for units sold in North America). More information [here](http://www.wxforum.net/index.php?topic=23652.msg230631#msg230631 WXForum) and [here]( Dhttp://www.carluccio.de/davis-vue-hacking-part-2/ario's Blog).

TBD: Is the rain bucket size different in different parts of the world, or is it the same and just calculated differently? TODO: write this up in actual code and (preferably) convert to the console's native units of inches per hour

no rain     if Byte3 == 0xFF

rain intensity:

light rain  if (Byte4 && 0x40) == 0 
strong rain if (Byte4 && 0x40) == 0x40 

light rain:

time between clicks[s] = ((Byte4 && 0x30) / 16 * 250) + Byte3
rainrate [mm/h] = 720 / (((Byte4 && 0x30) / 16 * 250) + Byte3)

strong rain:

time between clicks[s] = (((Byte4 && 0x30) / 16 * 250) + Byte3) / 16
rainrate [mm/h] = 11520 / (((Byte4 && 0x30) / 16 * 250) + Byte3)

Message 6: Solar Radiation

Bytes 3 and 4 are solar radiation. The first byte is MSB and the second LSB. The lower nibble of the 4th byte is again always 5, so they only use the first three nibbles. A value of FF in the third byte indicates that no sensor is present. See [here](http://www.wxforum.net/index.php?topic=18489.msg178506#msg178506 WXForum) and [here](http://www.wxforum.net/index.php?topic=18489.msg190548#msg190548 WXForum) for further discussion.

Solar radiation = (byte3 << 8 + byte4) >> 6) * 1.757936

Message 8: Temperature

Byte 3 and 4 are temperature. The first byte is MSB and the second LSB. The value is signed with 0x0000 representing 0F. This reading in the old version of the ISS was taked from an analog sensor and measured by an A/D. The newer ISS uses a digital sensor but still represents the data in the same way. 160 counts (0xa0) represents 1 degree F. A message of 80 04 70 0f 99 00 91 11 represents temperature as 0x0f99, or 3993 decimal. Divide 3993 by 160 to get the console reading of 25.0F

Message a:

Humidity is represented as two bytes in Byte 3 and Byte 4 as a ten bit value. Bits 5 and 4 in Byte 4 are the two most significant bits. Byte 3 is the low order byte. The ten bit value is then 10x the humidity value displayed on the console. The function of the four low order bits in Byte 3 that cause the apparent jitter are not known.

Here is an example using an actual message from my console.

a0 06 52 83 38 00 5a c8

The corresponding humidity is calculated as

((0x38 >> 4) << 8) + 0x83 = 131 + 768 = 899 = 89.9% Relative Humidity

The displayed humidity at the time was 90%. The console rounds the value. More here.

Message e:

Rain is in Byte 3. It is a running total of bucket tips that wraps back around to 0 eventually from the ISS. It is up to the console to keep track of changes in this byte.

The example below is bound to confuse: the leading value is the elapsed time since data collection started (in seconds), all bytes have been converted to decimal, and the last two CRC bytes have been stripped off. A tip of the rain bucket causes the value the ISS is sendingfrom a steady value of 40 to a new value of 41.

2426.3,224,16,33,40,1,0
2436.6,224,11,36,40,1,0
2446.8,224,9,29,41,2,0
2457.1,224,10,29,41,3,0

Protocol Summary

To summarize:

  • Byte 0 is a header.
  • Byte 1 always represents wind speed
  • Byte 2 always represents the wind direction
  • Bytes 3-5 will carry other data according to the header in Byte 0
  • Bytes 6 and 7 always represents the checksum with high byte first

Miscellaneous Notes

From my notes to help work the rest of this out:

Signed values from the weather station console are two's complement, least significant byte first. Note that pressure is measured by the console and not the ISS, so don't expect it to appear in the STRMON output.

Update rates below are from Davis' specs and manuals. Data sizes and signing are as per the loop command and are what one might expect out of STRMON but not always. I noted above that wind direction via STRMON is actually one byte unsigned. There may be other exceptions.

  • Outside temp: 10 seconds in 10th of a degree F, two bytes signed (message e in STRMON, bytes 3 and 4).
  • Winds speed: 2.5 seconds, one byte unsigned (Byte 1 in STRMON, always)
  • Wind direction: 2.5 seconds, two bytes unsigned from 1 to 360 (one byte via STRMON, Byte 2 always)
  • Outside humidity: 50 seconds in percent, one byte unsigned (message a in STRMON, bytes 3 and 4)
  • Rain: 10 seconds. This is in counts of 0.01 inches.
  • Pressure: in Hg/1000, two bytes unsigned (Rate????)
  • Leaf Wetness: 40 seconds
  • Soil Moisture: 40 seconds
  • Solar radiation: 50 seconds
  • UV: 50 seconds
  • Soil Moisture: 62.5 seconds
  • Vue Supercap Voltage: 50 seconds
  • Rain Rate: 10 seconds

I think all other outdoor related values are calculated in the console. The only headers (ie Byte 0) I see from my wireless VP2 with no additional sensors connected are:

40 50 60 80 90 a0 e0

The rates they show up at are:

  • 40 shows either every 47.5 or 50 seconds
  • 50 shows every 10 seconds
  • 60 shows every 50 seconds
  • 80 shows every 10 seconds
  • 90 shows either 45, 47.5, or 50 seconds
  • a0 shows alternately every 40 seconds and 10 seconds (interesting!)
  • e0 shows every 10 seconds

These rates along with the rates given in the Davis manual should make correlating the data a lot easier.

Clone this wiki locally