Linux support for TFA Klima-Logger
Update 2012-03-01:
I just ordered 2 outdoor sensors and the plan is to connect the Klima-Logger to a Raspberry Pi Board to make the data available via browser on my home network. Here are some resources I found
- https://oss.inqnet.at/trac/klimalogger/
- http://members.home.nl/xbasic/01c2249c770e62101/index.html
- http://www.atmel.com/dyn/resources/prod_documents/doc0670.pdf
- http://www.wetterstationsforum.de/phpBB/viewtopic.php?t=7605&postdays=0&postorder=asc&start=0&sid=472299c23b04447cc15aa92492c4a76f
- http://web.student.tuwien.ac.at/~e9725348/Projects/klimalogger/
Outdated:
I recently bought a hygrometer from TFA-Dostmann, called Klima-Logger. It is the cheapest thermometer and hygrometer with PC connectivity I could find on the market. Unfortunately only a Windows software is provided to get the recorded values for temperature and humidity. I thought a Linux driver would be cool and started searching for resources on the net. Usually the Linux community is very fast in supporting new gadgets of any kind, but nothing could be found.
That was driving me to think about writing support on my own. The first thing I did was to install the demo version of IDA Pro 4.8, a commercial disassembler for Windows, to look at any valuable information inside the executable. Some symbols I found were very narrative, for example CI2CDriver::setScl
or CI2CDriver::setSda
which indicated that some kind of I2C communication was used for accessing the device. The Windows API calls to GetCommModemStatus
and EscapeCommFunction
gave a hint that only serial flag lines were used for the I2C communication. At least for writing, informational and error messages from the data segement were indicating exactly which serial flag lines are used:
(newState == SdaHigh) ? CLRRTS : SETRTS
and
(newState == SclHigh) ? CLRDTR : SETDTR
That means RTS (Request To Send) is used for SDA (Serial Data) and DTR (Data Terminal Ready) is used for SCL (Serial Clock) write functionality. The EscapeCommFunction
from the Win32 API is utilized to set or clear the RTS and DTR serial flag lines.
Reading is done by utilyzing the GetCommModemStatus
Win32 API function. Unfortunately I haven’t found any strings from the data segment that reveal the assignment of the read flags directly. Assumptions are that DSR (Data Set Ready) and CTS (Clear To Send) lines are used for reading SCL and SDA lines. The problem is to find out whether SCL == DSR and SDA == CTS or whether SCL == CTS and SDA == DSR. The signals might additionally be inverted SCL == CLRCTS or SCL == SETCTS.
By looking at the board inside the hygrometer I found an Atmel 24C256 which is an EEPROM with an I2C interface and a capacity of 256KB (0x00000-0x39999).
The next step was trying to decipher the I2C protocol over the serial port status lines. I searched for a topic on how to install hooks for Win32 API system calls and found a solution from Microsoft Research on system call interception, called Detours (See article ‘Intercepting Win32 API system calls’ on how to use this tool).
My Detour dynamic link library with trampoline functions for all serial port Win32 API calls delivered a file with the recorded serial line status changes, but I forgot associating the SCL and SDA signals on a time basis. That made the data delivered by the Detours library unusable for analyzing the protocol. Further thinking about this solution led to the conclusion that it might be an uncomparably high effort to write this extension as it would require multiple threads being synchronized by timer interrupts in order to get this synchronization on a time basis.
Further looking through the data segment of the Windows application revealed that on top of the EEPROM some kind of Ringbuffer has been implemented.
The Ringbuffer seems to store the temperature and the humidity of each transmitter that is wirelessly connected to the device. The Windows software shows a list of 5 possible sensor pairs, but only the column for one pair is filled with values coming from the built in temperature- and humidity-sensor pair on the device. The conclusion for this observation is that 4 wireless transmitters can be connected and that the ring-buffer always seems to reserve space for all possible sensor pairs. Here as well, the structure of some data items haven’t been identified so far, for example start markers and end markers of data sets.
Without a claim of correctness, this might be the structure of the EEPROM:
00000 RING_BUFFER_CONFIG
00000 NrOfTransmitters
00004 Start
00008 End
0000c ByteSize
00010 DatasetSize
00014 DatasetCount
00018 RING_BUFFER_START (earliest start)
Dataset #1
00018 TIMESTAMP (usually a long aka 8 Bytes)
00020 TEMPERATURE of Built In sensor (1 Byte)
00021 HUMIDITY of Built In sensor (1 Byte)
00022 TEMPERATURE of transmitter sensor #1 (1 Byte)
00023 HUMIDITY of transmitter sensor #1 (1 Byte)
00024 TEMPERATURE of transmitter sensor #2 (1 Byte)
00025 HUMIDITY of transmitter sensor #2 (1 Byte)
00026 TEMPERATURE of transmitter sensor #3 (1 Byte)
00027 HUMIDITY of transmitter sensor #3 (1 Byte)
00028 TEMPERATURE of transmitter sensor #4 (1 Byte)
00029 HUMIDITY of transmitter sensor #4 (1 Byte)
Dataset #2
0002a TIMESTAMP (usually a long aka 8 Bytes)
39999 RING_BUFFER_END
What I found out so far:
- Serial Port Interface (Writing: SDA High == CLRRTS, SDA Low == SETRTS, Reading: DSR, CTS)
- EEPROM Atmel 24C256 with Ringbuffer for data sets and means to identify not yet read data sets.
- Linux I2C layer might provide basis for a possible solution as it implements all the infrastructure with pluggable device support.
The next steps are to get familiar with the Linux I2C layer and to learn how to write external Linux kernel modules for the Linux 2.6 kernel, especially for Ubuntu Linux which I have installed on my notebook.