La Crosse TX23U Anemometer Communication Protocol

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.

Wiring Pinout:

Pin Color Description
1 Brown TxD
2 Red Vcc
3 Green Not Connected
4 Yellow GND

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 from a La Crosse TX23U Anemometer

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.

Section Length (bits) Inverted? Endianness Description Notes
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.

Binary Hex Decimal Direction
0000 0 0 N
0001 1 1 NNE
0010 2 2 NE
0011 3 3 ENE
0100 4 4 E
0101 5 5 ESE
0110 6 6 SE
0111 7 7 SSE
1000 8 8 S
1001 9 9 SSW
1010 A 10 SW
1011 B 11 WSW
1100 C 12 W
1101 D 13 WNW
1110 E 14 NW
1111 F 15 NNW

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:

Name Bits Example
Wind Direction 1 – 4 1011
Wind Speed 1 – 4 0000
Wind Speed 5 – 8 0101
Wind Speed 9 – 12 0101
SUM 4 LSBs 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.

Suggestions
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)

You May Also Like

About the Author: John

18 Comments

  1. Hello,
    I have found your Code reading the TX23 there:
    https://github.com/ToninoTarsi/swpi/tree/master/TX23

    I get it working but it seems to be that the value of the wind speed is an integer value only (0,1,2,3,7, 11,..).
    Whats the measure for this? and can I get meter per second?

    I have a small fan next to the wind-sensor, leet’s say there are 90 RPM.
    So i get the following values:
    http://pastebin.com/dU1aXNeN
    Can you please explain to interpret the debug output?

    An other Post I have starten there http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=39243

  2. Hi John,

    I downloaded a sketch that I found of yours from the Arduino blog on how to read the data on a TX23.
    I modified your sketch removing the PWM portion just to view the wind direction on a 16X2 LCD display.
    What I don’t see is the raw data bits changing for the wind speed sent out to the serial port.

    //WIND SPEED
    for (int i =17 ; i> 8 ; i–){
    Serial.print( ((data[i] == 48)? 0 : 1) );

    Any help would be Great….

  3. Never mind found the info on adding a 2 second delay for the internal micro to calculate wind speed!
    Wind speed now working!

  4. Ok being new to Arduino coding, How do I format this…
    To display wind speed on a LCD display?

    Also can’t find reference to ? 0 : 1 what are you doing? formatting?

    //WIND SPEED
    for (int i =17 ; i> 8 ; i–){
    Serial.print( ((data[i] == 48)? 0 : 1) );

  5. Hello,

    Is someone able to connect the TX-23 to Raspberry pi and the sensor is working correctly. If so, I would be grateful for making the SD card image of the system and instructions for what pins to connect the sensor.

  6. Has anyone gotten the wind speed to work correctly? I get data but it appears the be cumulative not a new reading.

  7. Has anyone been able to make sense out of the wind speed data. I get a return but the binary does not appear to be wind speed dependent, it just increments up with a constant wind speed. When stopped the numbers returns to zero after about a minute. Ideas???

  8. I used the excellent information on your page to get a TX23 communicating with an Arduino Uno. I would not have been able to do it without your page. Thanks for posting this.

  9. Hello,

    I was looking at purchasing this anemometer, but haven’t found much to verify that people have been able to figure out the wind speed and direction signalling. Has anyone written a library for Arduino, or do I need to try and create the raw signal code?

    I’ve programmed Parallax micro controllers but am completely new to ATMel, would someone mind sharing or pointing me to some sort of sample code how I would do some sort of bitbang thing to read the pin change timing?

    Thanks,

    Kevin

  10. I followed your protocol and I got most of the stuff right. I put an oscilloscope to see the data line output and I found that sometimes before the TX-23U send the start frame it pulls the data high for about 20ms then low for about 100ms before sending the start frame. Sometimes it works exactly like your protocol, why is that and how can I eliminate or avoid that?

  11. Thank you for this awesome information. I have a question, when I send a start signal, sometimes I see a very long pull high then pull down interval before the start frame is send. But sometimes it works exactly like your tutorial. Do you know the cause of this problem and how I can avoid it? I am sending the start signal via a PIC16F1825 controller and monitoring the output with an oscilloscope and the PIC.

  12. Hello,
    I build my own weather station based on your protocol information with TX23 purchesed on fly market. Everything work well but for various period of time. Sometimes it work 1 hour sometimes 1,5 day. I wrote code in BASCOM and I sew that it stuck in TX23 reset sequence (never exit bitwait in reset sequence). Now, I don’t know is the sensor bad (I already change quarc 32Khz) or I made mistake in code. I scope wave form with logic analizer and the timings are OK. Do you have similar situation like this?

  13. hi John,
    thank you very much for working out the communications protocol for the TX23.
    i have been trying to write some c / python code for 2 weeks to try to get data from the sensor but, no success.
    i am not a programmer.

    did find some code from “swip” but it is a large program and could not get the contents of
    TX23 folder to give me output from the sensor.

    do you know of a group / forum where i could find some code specific to the TX23 or
    a location were i can post questions ???

    i am using a schematic from Derick Molloy site but, the circuit diagram i’m using with Raspberry – Buster is not specified for the TX23.

    pin 1 3.3V —————————————————————>Red
    |
    [ 1 k ohm ]
    |
    |
    pin 15 (gpio 22)—————————|—————————>Brown

    pin 9 (ground)———————————————————>Yellow

  14. I’m seeing two of these datagrams at each host request. The first one appears to be a smoothed average wind speed. The second one responds much more quickly to changes in speed and is likely the “gust” value. There is a ~20ms low period between the datagrams then the 5 bit preamble followed by the data.

Leave a Reply to Velja Cancel reply

Your email address will not be published. Required fields are marked *