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);
}
}
}
}
|
|
|