picprogrammer
 
 
  Joined: 10 Sep 2003 Posts: 35
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| La Crosse TX20 anemometer | 
			 
			
				 Posted: Sun Sep 20, 2015 11:34 am     | 
				     | 
			 
			
				
  | 
			 
			
				Here my code by easy made because John Geek made a nice description. I did not implemented the checksum
 
 
 	  | Code: | 	 		  
 
////////////////////////////////////////////////////////////////////////////////
 
// La Crosse TX20
 
// The datagram is 41 bits long and contains six data sections. Each bit is almost exactly 1.2msec
 
//
 
// Source:
 
// https://www.john.geek.nz/2011/07/la-crosse-tx20-anemometer-communication-protocol/
 
//
 
////////////////////////////////////////////////////////////////////////////////
 
 
 
#include <18F2680.h>
 
#device adc=16
 
 
 
#FUSES WDT512                   //Watch Dog Timer
 
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
 
#FUSES PUT                      //Power Up Timer
 
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
 
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
 
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
 
#FUSES BBSIZ1K                  //1K words Boot Block size
 
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
 
#FUSES STVREN                   //Stack overflow will rest
 
#use delay(int=8000000)
 
#use rs232(baud=38400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)
 
 
#define  tx20   pin_B7
 
 
 
int1 TX20_bit[50], 
 
     tx20_low,
 
     read_tx20;
 
 
int8 tx20_bitcounter;
 
 
/****************************************************************************
 
 *   0.5uS*8 = 4uS increase overflow *FFFF-300 = 1.2ms
 
 */
 
#int_TIMER3
 
void TIMER3_isr()
 
{
 
static int1 a;
 
  if (tx20_bitcounter < 43)
 
  {
 
    read_tx20 = true;
 
    if (a =!a)output_high(pin_B6);
 
    else output_low(pin_B6);
 
  }
 
  set_timer3(0xFFFF-297);
 
 }
 
 
 
/****************************************************************************
 
 *  Description : TX20 decoder
 
 */
 
int8 bittcopy(int8 start,int8 aantal,int8 invert) //from, aantal, inverted
 
 
{
 
signed int8 k;
 
int8 a=0,answer=0;
 
  
 
  for (k=start;k<=start+aantal-1;++k)
 
  {
 
    if (invert)
 
    {
 
      if (!TX20_bit[k]) bit_set(answer,a);
 
    }
 
    else 
 
      if (TX20_bit[k]) bit_set(answer,a);
 
    a++;
 
  }
 
  return(answer);
 
}
 
 
 
 
/*******************************************************************************
 
 *  Main
 
 */
 
void main()
 
{
 
int8 k,rc;
 
   rc = RESTART_CAUSE();
 
   if (rc == WDT_TIMEOUT) printf("WDT\n\r");
 
     else printf("rc=%u\n\r",rc);
 
  setup_wdt(WDT_ON);
 
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //32.7 ms overflow
 
  setup_timer_2(T2_DIV_BY_16,0xFF,8);         // routine elke 0.2uS *div16 *255*16= = 16.32mS mS
 
  setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);     // 0.5uS*8 = 4uS increase overfow *FFFF = 262ms
 
  
 
  disable_interrupts(INT_TIMER1);
 
  disable_interrupts(INT_TIMER2);
 
  enable_interrupts(INT_TIMER3);
 
  disable_interrupts(INT_EXT);
 
  disable_interrupts(INT_RDA);
 
  enable_interrupts(GLOBAL);
 
  setup_oscillator(OSC_8MHZ|OSC_TIMER1|OSC_31250|OSC_PLL_OFF);
 
  
 
  printf(__DATE__);
 
  printf("\n\r" );
 
  printf(__TIME__);
 
 
  printf("La Crosse TX20 1.0\n\r");
 
  
 
  while(1)
 
  {
 
    restart_wdt();
 
    
 
    if (read_tx20)
 
    { 
 
      read_tx20 = false;
 
      TX20_bit[tx20_bitcounter] = input(tx20);  
 
      tx20_bitcounter++;  
 
    }
 
 
    if (input(tx20) && tx20_low)
 
    {
 
      tx20_low = false;
 
      if (tx20_bitcounter > 41)
 
      {
 
        tx20_bitcounter=0;
 
        set_timer3(0xFFFF-150);
 
      }
 
    }
 
    
 
    if (!input(tx20) ) 
 
      tx20_low = true;
 
    
 
    if (tx20_bitcounter == 42)
 
    {
 
      tx20_bitcounter++;
 
      int8 wind1,wind2,dir1,dir2;
 
      k= bittcopy(0,5,1); //from, aantal, inverted      
 
      dir1 = bittcopy(5,4,1); //from, aantal, inverted      
 
      wind1 = bittcopy(9,12,1); //from, aantal, inverted
 
      dir2 = bittcopy(25,4,0); //from, aantal, inverted      
 
      wind2 = bittcopy(29,12,0); //from, aantal, inverted
 
 
      if( dir1 == dir2 && wind1 == wind2 && k==4)
 
      {
 
        printf("Direction= %u  \n\r",dir1);
 
        printf("speed    = %u  \n\r",wind1);
 
      }
 
    }
 
  }
 
}
 
 | 	 
  | 
			 
		  |