Weather station memory map

Cautionary note: this is not official information from any manufacturer. It has been compiled from various sources, including careful “reverse engineering” of data from a small number of users’ weather stations. Use at your own risk.

An essential precursor to writing software for the Fine offset weather stations (WH1080, WH1081, W-8681, WH3080, WH3081 etc.) was to decode the data read from them. This was discussed in Michael Pendec’s weather station forum a few years ago. Michael had decoded the current and stored data, and Dave Wells contributed an almost complete map of the remaining data. That forum message has since been deleted (Michael had a spam problem, and wiping everything was his only option) so I’ve reproduced the info here, with a few additions of my own. Credit is also due to Steve from Sandaysoft for decoding the strange wind speed layout and to Chris Naunton for decoding the extra data stored by the ‘3080’ family of stations.

Note that there are gaps and overlaps in the memory layout, with different models using the same locations for different data. Writing software that works with all the different models (and different generations of firmware) can be tricky!

Data is read from the weather station, via USB, in 32-byte chunks. Each chunk has an address, in the range 0 to 65504, so it is convenient to describe the data as a memory map with an address range of 0 to 65535.

The first 256 bytes of the memory map is a “fixed” block, containing data such as maximum and minimum temperature records and alarm settings. The remaining data is an array of 4080 16-byte records (or 3264 20-byte records), which store the weather history.

Note that there are some pecularities about the data formats. Signed numbers use the most significant bit to indicate sign, so -1 would be represented in binary as 1000 0001 (signed byte) or 1000 0000 0000 0001 (signed short). Date-time values are stored as year (last two digits), month, day, hour and minute in binary coded decimal, two digits per byte.

Weather record layout

The weather station’s history is stored in 4080 16-byte records (3264 20-byte records in the 3080), each of which has the following layout.

AddressBytesItemFormatComments
01delayunsigned byteMinutes since last stored reading.
11indoor humidityunsigned byte
22indoor temperaturesigned shortMultiply by 0.1 to get °C.
41outdoor humidityunsigned byte
52outdoor temperaturesigned shortMultiply by 0.1 to get °C.
72absolute pressureunsigned shortMultiply by 0.1 to get hPa.
91average wind speed, low bitsunsigned byteMultiply by 0.1 to get m/s.
101gust wind speed, low bitsunsigned byteMultiply by 0.1 to get m/s.
111wind speed, high bitsunsigned byteLower 4 bits are the average wind speed high bits, upper 4 bits are the gust wind speed high bits.
121wind directionunsigned byteMultiply by 22.5 to get ° from north.
132total rainunsigned shortMultiply by 0.3 to get mm.
151statusbitsbit 6: 1 = loss of contact with sensors
bit 7: 1 = rain counter overflow
163(3080 only) illuminanceunsigned 3-byte integerMultiply by 0.1 to get lux.
191(3080 only) UVunsigned byte

Fixed block layout

Other weather station data is stored in a 256 byte “fixed block”, which has the following layout.

AddressBytesItemFormatAccessComments
02EEPROM initialised flagrawR/WShould be 0x55AA.
22(2080 only) modelunsigned shortR/WExpected to be 0x8010 (i.e. big-endian 1080)
22(3080 only) rain factor (?)unsigned shortRDivide by 8192
41(2080 only) versionunsigned byteR/WExpected to be 0x20
42(3080 only) wind factor (?)unsigned shortRDivide by 8192
52(2080 only) IDunsigned shortR/W?
65(3080 only) maximum, UV, whendate-timeR/W
72(2080 only) rain factor (?)unsigned shortR/WDivide by 8192
92(2080 only) wind factor (?)unsigned shortR/WDivide by 8192
112(2080 only) inverted rain factor (?)unsigned shortR/WRain factor ^ 0xffff
115(3080 only) maximum, illuminance, whendate-timeR/W
132(2080 only) inverted wind factor (?)unsigned shortR/WWind factor ^ 0xffff
161read periodunsigned byteR/WMinutes between each stored reading
171unit settings 1bitsR/Wbit 0: indoor temperature: 0 = °C, 1 = °F
bit 1: outdoor temperature: 0 = °C, 1 = °F
bit 2: rain: 0 = mm, 1 = inch
bit 5: pressure: 1 = hPa
bit 6: pressure: 1 = inHg
bit 7: pressure: 1 = mmHg
181unit settings 2bitsR/Wbit 0: wind speed: 1 = m/s
bit 1: wind speed: 1 = km/h
bit 2: wind speed: 1 = knot
bit 3: wind speed: 1 = m/h
bit 4: wind speed: 1 = bft
191display options 1bitsR/Wbit 0: pressure: 0 = absolute, 1 = relative
bit 1: wind speed: 0 = average, 1 = gust
bit 2: time: 0 = 24 hour, 1 = 12 hour
bit 3: date: 0 = day-month-year, 1 = month-day-year
bit 4: time scale(?): 0 = 12 hour, 1 = 24 hour
bit 5: date: 1 = show year year
bit 6: date: 1 = show day name
bit 7: date: 1 = alarm time
201display options 2bitsR/Wbit 0: outdoor temperature: 1 = temperature
bit 1: outdoor temperature: 1 = wind chill
bit 2: outdoor temperature: 1 = dew point
bit 3: rain: 1 = hour
bit 4: rain: 1 = day
bit 5: rain: 1 = week
bit 6: rain: 1 = month
bit 7: rain: 1 = total
211alarm enable 1bitsR/Wbit 1: time
bit 2: wind direction
bit 4: indoor humidity low
bit 5: indoor humidity high
bit 6: outdoor humidity low
bit 7: outdoor humidity high
221alarm enable 2bitsR/Wbit 0: wind average
bit 1: wind gust
bit 2: rain hourly
bit 3: rain daily
bit 4: absolute pressure low
bit 5: absolute pressure high
bit 6: relative pressure low
bit 7: relative pressure high
231alarm enable 3bitsR/Wbit 0: indoor temperature low
bit 1: indoor temperature high
bit 2: outdoor temperature low
bit 3: outdoor temperature high
bit 4: wind chill low
bit 5: wind chill high
bit 6: dew point low
bit 7: dew point high
241time zonesigned byteR/WHours offset from Central European Time, so in the UK this should be set to -1. In stations without a radio controlled clock this is always zero.
25
261data refreshedrawR/WComputer writes 0xAA to indicate a change of settings. Weather station clears value to acknowledge.
272data countunsigned shortR/WNumber of stored readings. Starts at one, rises to 4080 (3264 in the 3080).
291(3080 only) display options 3bitsR/Wbit 0: illuminance: 0 = lux, 1 = foot-candle
bit 1: illuminance high alarm
bit 2: UV high alarm
bit 5: illuminance: 1 = W/m2
302current positionunsigned shortR/WAddress of the stored reading currently being created. Starts at 256, rises to 65520 in steps of 16 (or 65516 in steps of 20 in the 3080), then loops back to 256. The data at this address is updated every 48 seconds or so, until the read period is reached. Then the address is incremented and the next record becomes current.
322relative pressureunsigned shortRCurrent relative (sea level) atmospheric pressure, multiply by 0.1 to get hPa.
342absolute pressureunsigned shortRCurrent absolute atmospheric pressure, multiply by 0.1 to get hPa.
362(3080 only) Lux to W/m2 coefficientunsigned shortR/WDivide by 10.
382(2080 only?) wind correction factorunsigned shortR/WPercent in range 75..125
402(2080 only?) outdoor temperature offsetsigned shortR/WMultiply by 0.1 to get °C?
422(2080 only?) indoor temperature offsetsigned shortR/WMultiply by 0.1 to get °C?
435(1080 only?) current date & timedate-timeR
442(2080 only?) outdoor humidity offsetsigned shortR/WUnknown units
462(2080 only?) indoor humidity offsetsigned shortR/WUnknown units
481alarm, indoor humidity, highunsigned byteR/W
491alarm, indoor humidity, lowunsigned byteR/W
502alarm, indoor temperature, highsigned shortR/WMultiply by 0.1 to get °C.
522alarm, indoor temperature, lowsigned shortR/WMultiply by 0.1 to get °C.
541alarm, outdoor humidity, highunsigned byteR/W
551alarm, outdoor humidity, lowunsigned byteR/W
562alarm, outdoor temperature, highsigned shortR/WMultiply by 0.1 to get °C.
582alarm, outdoor temperature, lowsigned shortR/WMultiply by 0.1 to get °C.
602alarm, wind chill, highsigned shortR/WMultiply by 0.1 to get °C.
622alarm, wind chill, lowsigned shortR/WMultiply by 0.1 to get °C.
642alarm, dew point, highsigned shortR/WMultiply by 0.1 to get °C.
662alarm, dew point, lowsigned shortR/WMultiply by 0.1 to get °C.
682alarm, absolute pressure, highunsigned shortR/WMultiply by 0.1 to get hPa.
702alarm, absolute pressure, lowunsigned shortR/WMultiply by 0.1 to get hPa.
722alarm, relative pressure, highunsigned shortR/WMultiply by 0.1 to get hPa.
742alarm, relative pressure, lowunsigned shortR/WMultiply by 0.1 to get hPa.
761alarm, average wind speed, Beaufortunsigned byteR/W
772alarm, average wind speed, m/sunsigned shortR/WMultiply by 0.1 to get m/s.
791alarm, gust wind speed, Beaufortunsigned byteR/W
802alarm, gust wind speed, m/sunsigned shortR/WMultiply by 0.1 to get m/s.
821alarm, wind directionunsigned byteR/WMultiply by 22.5 to get ° from north.
832alarm, rain, hourlyunsigned shortR/WMultiply by 0.1 to get mm.
852alarm, rain, dailyunsigned shortR/WMultiply by 0.1 to get mm.
872alarm, timeBCDR/WHour & minute.
893(3080 only) alarm, illuminanceunsigned 3-byte integerR/WMultiply by 0.1 to get lux or fc, according to setting at address 29 bit 0.
921(3080 only) alarm, UVunsigned byteR/W
931(3080 only) maximum, UV, valueunsigned byteR/W
943(3080 only) maximum, illuminance, valueunsigned 3-byte integerR/WMultiply by 0.1 to get lux.
97
981maximum, indoor humidity, valueunsigned byteR/W
991minimum, indoor humidity, valueunsigned byteR/W
1001maximum, outdoor humidity, valueunsigned byteR/W
1011minimum, outdoor humidity, valueunsigned byteR/W
1022maximum, indoor temperature, valuesigned shortR/WMultiply by 0.1 to get °C.
1042minimum, indoor temperature, valuesigned shortR/WMultiply by 0.1 to get °C.
1062maximum, outdoor temperature, valuesigned shortR/WMultiply by 0.1 to get °C.
1082minimum, outdoor temperature, valuesigned shortR/WMultiply by 0.1 to get °C.
1102maximum, wind chill, valuesigned shortR/WMultiply by 0.1 to get °C.
1122minimum, wind chill, valuesigned shortR/WMultiply by 0.1 to get °C.
1142maximum, dew point, valuesigned shortR/WMultiply by 0.1 to get °C.
1162minimum, dew point, valuesigned shortR/WMultiply by 0.1 to get °C.
1182maximum, absolute pressure, valueunsigned shortR/WMultiply by 0.1 to get hPa.
1202minimum, absolute pressure, valueunsigned shortR/WMultiply by 0.1 to get hPa.
1222maximum, relative pressure, valueunsigned shortR/WMultiply by 0.1 to get hPa.
1242minimum, relative pressure, valueunsigned shortR/WMultiply by 0.1 to get hPa.
1262maximum, average wind speed, valueunsigned shortR/WMultiply by 0.1 to get m/s.
1282maximum, gust wind speed, valueunsigned shortR/WMultiply by 0.1 to get m/s.
1302maximum, rain hourly, valueunsigned shortR/WMultiply by 0.1 to get mm.
1322maximum, rain daily, valueunsigned shortR/WMultiply by 0.1 to get mm.
1342maximum, rain weekly, valueunsigned shortR/WMultiply by 0.1 to get mm.
1362maximum, rain monthly, valueunsigned shortR/WMultiply by 0.1 to get mm.
1382maximum, rain total, valueunsigned shortR/WMultiply by 0.1 to get mm.
1401high nibble for month and total rainfallR/Whigh nibble – month rainfall, low nibble – total rainfall
1415maximum, indoor humidity, whendate-timeR/W
1465minimum, indoor humidity, whendate-timeR/W
1515maximum, outdoor humidity, whendate-timeR/W
1565minimum, outdoor humidity, whendate-timeR/W
1615maximum, indoor temperature, whendate-timeR/W
1665minimum, indoor temperature, whendate-timeR/W
1715maximum, outdoor temperature, whendate-timeR/W
1765minimum, outdoor temperature, whendate-timeR/W
1815maximum, wind chill, whendate-timeR/W
1865minimum, wind chill, whendate-timeR/W
1915maximum, dew point, whendate-timeR/W
1965minimum, dew point, whendate-timeR/W
2015maximum, absolute pressure, whendate-timeR/W
2065minimum, absolute pressure, whendate-timeR/W
2115maximum, relative pressure, whendate-timeR/W
2165minimum, relative pressure, whendate-timeR/W
2215maximum, average wind speed, whendate-timeR/W
2265maximum, gust wind speed, whendate-timeR/W
2315maximum, rain hourly, whendate-timeR/W
2365maximum, rain daily, whendate-timeR/W
2415maximum, rain weekly, whendate-timeR/W
2465maximum, rain monthly, whendate-timeR/W
2515maximum, rain total, whendate-timeR/W