Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:16 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Decoding La Crosse TX20 Wind Sensor

Author Message
MikeO
Senior Member

Joined: 11/09/2011
Location: Australia
Posts: 275
Posted: 10:27am 22 Apr 2018
Copy link to clipboard 
Print this post

Following on from the recent posts from Grogster, Disco4now and the original software code from Tassie Jim, I thought it would be fantastic if I could put the La Crosse Anemometer (TX20) I had to good use. The base station had failed quite a while ago so it was just sat in the shed. Actually its quite a good unit with optical wind direction sensing and Hall effect wind speed so it was worth trying to get going and replace the all reed switch model I have. So armed with the Digoo remote temp sensor post as my guide I set about coding. Running on a MX170 here is the resultant code which seems to work very well so thanks to everyone

'http://www.codenquilts.com.au
'Michael Ogden April 2018
'Credits
'Protocol John.Geek.nz
'Software original coding ideas - Tassie Jim
'La Crosse TX20 Anenometer communications
'
'mx170 version
DIM code$
dim integer isWind,wSpeed
dim float wDir


SETPIN 16, INTH, Wind ' triggers on a high

do
if isWind=1 then
print "Wind degrees:";wDir
Print "Wind Speed m/Sec:";wSpeed
print
end if
pause 3000
loop

SUB Wind
local integer s
code$=""
'timer=0
for s=1 to 5 'check for start frame , exit with fail if not correct
pause 0.42
IF PIN(16) = 1 THEN ' we went from low to high
code$ = code$ + "0"
ELSE ' we went from high to low
code$ = code$ + "1"
ENDIF
pause 0.42
next s
if code$<>"00100" then
isWind=0:wDir=0:wSpeed=0
exit sub
end if
for s=6 to 41
pause .42
IF PIN(16) = 1 THEN ' we went from low to high
code$ = code$ + "0"
ELSE ' we went from high to low
code$ = code$ + "1"
ENDIF
pause .42
next s
'print timer
'print code$
'print "start:";left$(code$,5)
isWind=1
wDir=val("&B"+endian$(mid$(code$,6,4),4))*22.5
wSpeed=val("&B"+endian$(mid$(code$,10,12),12))
' print "CheckSum:";endian$(mid$(code$,22,4),4)
' print "IwindDir:";endian$(mid$(code$,26,4),4)
' print "IwindSpeed:";endian$(mid$(code$,30,12),12)
END SUB

function endian$(en$,l%)
do
endian$=endian$+mid$(en$,l%,1)
l%=l%-1
loop until l%=0
end function

Codenquilts
 
pcaffalldavis

Senior Member

Joined: 17/10/2011
Location: United States
Posts: 187
Posted: 01:57pm 22 Apr 2018
Copy link to clipboard 
Print this post

I'm trying to learn to understand code used for a variety of different purposes I'm not familiar with. This project seems a good opportunity. I too have an old anemometer, albeit not a Le Cross. Rotating wind cups use magnets to send pulses to a bicycle computer. But, it displays only speeds, current or present speed, max and min, not direction. It is a wired anemometer from the wind cup unit to the bicycle computer located indoors.

Might it be possible for someone to peel off the code portion from the example given that deals with the wind direction indicator and leave only the code that deals with wind speed? I would like to try using the speed only code (without wind direction) with my anemometer using a GSMMStick1 running version 4.5.

Does anyone think that might be possible? If this could be done I'd like to have the Maximite store the peak, and average wind speeds every day or maybe every hour when there is a lot of wind activity.

I could code the accumulating, averaging and data dumping parts, and I can probably write the code to calibrate it too, but I could use a bit of help learning how to configure the MM and get it to interpret the pulses being sent by the wind cups.

I'd probably hook the MM up to a switched VGA monitor too so I would also design a display showing present wind speed, daily peak, and daily average, maybe monthly data too, but the display would be more of an optional afterthought and not get much use or viewing. I'm more interested in using this as a data-logger to help determine seasonal potential for wind power generation here.

Any thoughts? Am I maybe out of my depth?
We're all here 'cause we're not all there.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:15pm 22 Apr 2018
Copy link to clipboard 
Print this post

  pcaffalldavis said   I would like to try using the speed only code (without wind direction) with my anemometer using a GSMMStick1 running version 4.5.

Does anyone think that might be possible?

I did it for a number of years until the big lightning strike....
The pulses are fed into one of the counting pins of the Maximite. You can read the count every 3, 10 etc seconds and get the average over that time interval.

I will dig out thw code when my time in the sun comes to an end.
Jim

I will also have to see if I can decode my 'fine offset' weather station.

VK7JH
MMedit
 
MikeO
Senior Member

Joined: 11/09/2011
Location: Australia
Posts: 275
Posted: 01:15am 23 Apr 2018
Copy link to clipboard 
Print this post

  pcaffalldavis said  
Might it be possible for someone to peel off the code portion from the example given that deals with the wind direction indicator and leave only the code that deals with wind speed? I would like to try using the speed only code (without wind direction) with my anemometer using a GSMMStick1 running version 4.5.

Does anyone think that might be possible?


Here is the portion of code from my current weather station which uses a "Reed" switch type device. This routine uses an interrupt that measures the time for one revolution (in this case , some anemometers have more than a single reed switch).
The whole weather station code is on my server at the link below in the menu under hardware.


'Wind speed sensor interrupt
Sub anemometerClick
local thistime
thistime=Timer-anem_last 'thistime measures the time between pulses
thistimeW=thistime
anem_last=Timer
If thistime>5 Then 'only process if > 5mSec, for switch debounce
anem_count=anem_count+1 'Adds up pulses single pulse per/rotation
If thistime<anem_min Then 'If the time is less than 1 second
anem_min=thistime 'gust 'then thistime = gust
End If
'Print "Wind click" 'Prints this EVERY time the reed switch closes=**TEST USE ONLY - DELETE WHEN happy its working properly
'use this to check how many switch closures per revolution when turning by hand
end if
'print "Incr Anem counts:";anem_count;" This Pulse interval:";thistime;" Min Pulse interval:";anem_min
End Sub

Edited by MikeO 2018-04-24
Codenquilts
 
pcaffalldavis

Senior Member

Joined: 17/10/2011
Location: United States
Posts: 187
Posted: 01:23am 23 Apr 2018
Copy link to clipboard 
Print this post

Thank you Tassy Jim and MikeO. I'll Try to find another of my old reed switch wind cups and play with this on the bench next weekend.

Thank you,

Peter in Hyder
We're all here 'cause we're not all there.
 
MikeO
Senior Member

Joined: 11/09/2011
Location: Australia
Posts: 275
Posted: 03:04am 26 Oct 2018
Copy link to clipboard 
Print this post

Update Version of La Crosse TX20 Anenometer . Code in the first version wasn't totally reliable but this version is proving to be rock solid so far. Data is sent via UDP network transmission approximately every 1-2 sec.

Plan now is to rebuild my weather station using a RPI Model 3B running a combination of Picromite and Python and one of these PCBs to connect the hardware. There is a very nice tutorial on the python bits used with this board for this project also on the site.

I will also monitor my Water Tank level and water flow with the RPI running Picromite
code replacing the current MX170 stand alone system.


'http://www.codenquilts.com.au
'Michael Ogden April 2018
'Credits
'Protocol John.Geek.nz
'Software original coding ideas - Tassie Jim
'La Crosse TX20 Anenometer communications
'
'mx170 version
'ver 1.03 (Oct 2018)

option autorun on
if mm.watchdog then Print "Reset error"
cpu 48
sub MM.STARTUP
'set Nowifi=1 if no ESP8266
'Nowifi=1
end sub
'Constants
const node$="ESP_Wind"
const serv$="ESP_Svr"
DIM code$,a$,c$
dim integer isWind,Wstop,xwdir,xwspeed
dim integer t,s
dim float wDir,wSpeed
'tv1 and tv2 delays, tv1 plus tv2 sets bit bang timing in this case ~ 1.2msec/bit
'tv1 sets the delay after "wind" interupt on pin 16 so sampling occurs ~ 350-400uSec
'after start of bit. tv2 sets the balance of 1.2mSec. In the case of MX170 @ default
'40MHz, tv1 can be set to zero and tv2=0.37. Timings shown below are for MX170 @
'48MHz. Other faster Micromites will require different settings for tv1 and tv2
dim float tv1=0.15
dim float tv2=0.46
'
SETPIN 16, INTh,Wind' triggers on a High or Low
setpin 10, dout
setpin 14, dout
pin(10)=0 'DTR
pin(14)=0
do
'***** mxWiFi Hook **** Network only
if userprocessflag=1 then
'StartTime = Timer
UserProcess
UserProcessFlag=0
xbsend "udp.send:|"+from$+"|"+chr$(4)+"|"
'Print "Processing elapsed time"; Timer-StartTime
watchdog 60000
continue do 'skip to a new loop immediately , there may be more external processing to do
endif
'***** End mxWiFi Hook ****
watchdog 60000
if isWind=1 then
print "Wind degrees/direction:";wDir;"/";winddir(wdir)
Print "Wind Speed m/Sec/km/h:";wSpeed;"/";wspeed*3.6
print
a$=str$(wdir) + "," + winddir(wdir)+ "," + str$(wspeed) +"," + str$(wspeed*3.6,3,1)
'UDP Network only transmission,data may be sent by other means
xbsend "udp.cast:|"+serv$+":|"+node$+"|Log|4|"+a$
WaitforReady 'reset flag
isWind=0
end if
pause 1000
loop

function WindDir(w as float)as string
select case w
case 0
WindDir="N"
case 22.5
Winddir="NNE"
case 45
Winddir="NE"
case 67.5
Winddir="ENE"
case 90
Winddir="E"
case 112.5
Winddir="ESE"
case 135
Winddir="SE"
case 157.5
Winddir="SSE"
case 180
Winddir="S"
case 202.5
Winddir="SSW"
case 225
Winddir="SW"
case 247.5
Winddir="WSW"
case 270
Winddir="W"
case 292.5
Winddir="WNW"
case 315
Winddir="NW"
case 337.5
Winddir="NNW"
case else
Winddir="-"
end select
end function


SUB Wind
for s=1 to 41 'sample frame
pause tv1
IF PIN(16) = 1 THEN ' we went from low to high
pin(14)=1:pause .1:pin(14)=0 'debug OSC calibration
code$ = code$ + "0"
ELSE ' we went from high to low
pin(14)=1:pause .1:pin(14)=0 'debug OSC calibration
code$ = code$ + "1"
ENDIF
pause tv2
next s
print code$
if left$(code$,5)="00100" then sig=1
xwdir= val("&B"+endian$(mid$(code$,6,4),4)) xor val("&B"+endian$(mid$(code$,26,4),4))
xwspeed= val("&B"+endian$(mid$(code$,10,12),12)) xor val("&B"+endian$(mid$(code$,30,12),12))
print sig;xwdir;xwspeed 'debug
if sig=1 and xwdir=15 and xwspeed=4095 then 'data verification
isWind=1
wDir=val("&B"+endian$(mid$(code$,6,4),4))*22.5
wSpeed=val("&B"+endian$(mid$(code$,10,12),12))/10
code$=""
else
isWind=0:wDir=0:wSpeed=0:code$=""
xwdir=0:xwspeed=0:sig=0:csum=0
end if
END SUB

function endian$(en$,l%)
do
endian$=endian$+mid$(en$,l%,1)
l%=l%-1
loop until l%=0
end function

'External command processing sub Routine if required, network only
sub extCmd
'print "External Commands:";from$;" ";cmd$;" ";cfg$;" ",strin$
end Sub

Codenquilts
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025