I’ve previously documented the protocol of the La Crosse TX20 Anemometer, but mine recently failed.
The La Crosse TX23U Anemometer is almost half the price of the TX20, so I decided to buy one and see if I could decode the protocol.
The big difference between the TX20 and the TX23U is that the TX20 will send a datagram every two seconds (when the DTR line is pulled low), while the TX23U won’t send anything until triggered by briefly pulling the Data line low.
Here’s everything you’ll ever want to know about the pin out and the communications protocol of the La Crosse TX23.
I’m unsure of what Voltage the TX23U is normally driven with (when connected to a La Crosse Weather Station), but it seems happy running from 3.3 Volts.
TxD should be pulled high to Vcc with a 10k (or similar) pull up resistor.
If you connect the GND and TxD to a oscilloscope (with the pullup resistor from TxD to Vcc) and trigger it by pulling TxD to GND briefly, you’ll see a waveform similar to the following.
The datagram starts high due to the pull up resistor. The TX23U then pulls the data line low for approximately 20 mSec while it (I assume) performs internal calculations. It then sends a 41 bit datagram. Each Bit is approximately 1200uSec long, resulting in a bit rate of around 833 bits per second.
It’s best to calculate the bit rate based on the pin state changes of the start frame as the bit rate seems very dependent on temperature.
Note that all of the values are LSB (Least Significant Bit) First, so you will need to reverse them for standard (MSB First) Integer arithmetic.
|A||N/A||N/A||N/A||Host pulls TxD low||Signals TX23U to sent measurement|
|B||N/A||N/A||N/A||TxD released||TxD is pulled high due to Pull up Resistor|
|C||N/A||N/A||N/A||TX23U pulls TxD low||Calculation in progress (assumed)|
|D||5||No||LSB first||Start Frame||Always 11011|
|E||4||No||LSB first||Wind Direction||0-15, see table below|
|F||12||No||LSB first||Wind Speed||0-511|
|G||4||No||LSB first||Checksum||See below|
|H||4||Yes||LSB first||Wind Direction||0-15, see table below|
|I||12||Yes||LSB first||Wind Speed||0-511|
A – Host pulls TxD low
You need to pull TxD low (To GND) to signal to the TX23U that you want a measurement. Holding it low for 500mSec seems to give reliable results.
B – TxD released
When the Host releases TxD, it will go high briefly (about 1.2mSec) due to the Pull up resistor.
C – TX23U pulls TxD low
The TX23U then takes control of the TxD line and pulls it low. This lasts for about 20mSec while (I assume) the TX23U is taking measurements and calculating values.
D – Start Frame and Triggering / Detecting start of data
The start frame is always 11011, and due to section C pulling the line low, you can use a rising edge trigger / interrupt to detect the Start Frame.
E – Wind Direction
The wind direction is supplied as a 4 bit value. It requires it’s endianness to be reversed. Once this is done it’s a value of 16th’s of a revolution from North. Thus it can be multiplied by 22.5 to get a direction in Degrees, or a 16 value array can be used to return the direction.
In the example image above, the Wind direction is read as 1101, and then it’s endianness is reversed to 1011, which is decimal 11, WSW or 247.5 degrees.
Table of the directions is below.
F – Wind Speed
The wind speed is a 12 bit value. It requires it’s endianness to be reversed.
I’m unsure of the exact units, but it appears to be a factory calibrated value in units of 0.1 metre/sec. The 3 MSB’s are always 000, so only 9 bits are used. With a max value of 511, this relates to 51.1 metres per second, or 183.96 km/h (114.31 miles per hour).
From the example image above, the wind speed is read as 101010100000, then endianness reversed to 000001010101, which is decimal 85, or 8.5 metres per second.
G – Checksum
The checksum is a 4 bit value. It requires it’s endianness to be reversed.
This is a 4 bit value of the four least significant bits of the SUM of the wind direction and the three nibbles of the 12 bit windspeed.
The checksum in the datagram above is read as 1010, then endianness swapped to 0101.
For the datagram image above, the checksum would be calculated by:
|Wind Direction||1 – 4||1011|
|Wind Speed||1 – 4||0000|
|Wind Speed||5 – 8||0101|
|Wind Speed||9 – 12||0101|
As the Checksum received matches the calculated Checksum, the received data is likely to be correct.
H – Wind Direction (Inverted)
The wind direction (Inverted) is supplied as a 4 bit value. It requires inverting and it’s endianness to be reversed. It can then be interpreted like section “E” above.
In the example image above, the Wind direction is read as 0010, Inverted to 1101 and it’s endianness is reversed to 1011, which is decimal 11, WSW or 247.5 degrees.
I – Wind Speed (Inverted)
The wind speed (Inverted) is a 12 bit value. It requires inverting and it’s endianness to be reversed. It can then be interpreted like section “F” above.
From the example image above, the wind speed is read as 010101011111, Inverted to 101010100000 and it’s endianness is reversed to 000001010101, which is decimal 85, or 8.5 metres per second.
The checksum calculation is very simple and could easily be prone to errors where noise in the line results in invalid data which still matches the checksum.
As both the wind direction and the wind speed are sent twice, I suggest the following checks before a result is considered to be read correctly:
- Check that the start frame is 11011 (0x1B)
- Check received checksum matches calculated checksum
- Check that Wind Direction matches Wind Direction (Inverted)
- Check that Wind Speed matches Wind Speed (Inverted)