![]() |
Forum Index : Microcontroller and PC projects : Decoding La Crosse TX20 Wind Sensor
Author | Message | ||||
MikeO Senior Member ![]() Joined: 11/09/2011 Location: AustraliaPosts: 275 |
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 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 StatesPosts: 187 |
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: AustraliaPosts: 6283 |
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: AustraliaPosts: 275 |
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 Codenquilts |
||||
pcaffalldavis![]() Senior Member ![]() Joined: 17/10/2011 Location: United StatesPosts: 187 |
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: AustraliaPosts: 275 |
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 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 |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |