#include // Register defions #include #include // Timer library functions #include // Time delay functions #include // CCP library functions #include #include #include #include #include #pragma config OSC = XT #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = ON #pragma config BOREN = NOSLP #pragma config BORV = 2 #pragma config WDT = ON //#pragma config WDT = OFF #pragma config WDTPS = 512 //#pragma config WDTPS = 32768 #pragma config MCLRE = ON #pragma config PBADEN = OFF #pragma config LVP = OFF #pragma config XINST = OFF #pragma config DEBUG = OFF #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CP2 = OFF #pragma config CP3 = OFF #pragma config CPB = OFF #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRT2 = OFF #pragma config WRT3 = OFF #pragma config WRTB = OFF #pragma config WRTC = OFF #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTR2 = OFF #pragma config EBTR3 = OFF #pragma config EBTRB = OFF #define WIRELESS_RX PORTCbits.RC2 #define LED1 LATCbits.LATC0 #define LED2 LATCbits.LATC1 #define LED3 LATCbits.LATC3 #define word unsigned int #define byte unsigned char // function prototypes void timer_isr(void); void SendTemp(void); void ReadWirelessTemp(void); void phex16(word data); void SendMoisture(void); int Global_Temp, Global_Temp_Raw, Global_Moisture_Raw; byte Global_Power_On = 1; byte Carrier_Detect; byte Signal_Level; word GPoint; byte rx_data[16]; #pragma code isrcode=0x0008 void isrhandler(void) // This function directs execution to the { // actual interrupt code _asm goto timer_isr _endasm } #pragma code #pragma interrupt timer_isr save=W //--------------------------------------------------------------------- // timer_isr() // Performs the capture interupt //--------------------------------------------------------------------- void timer_isr(void) { static word this_point, this_abs, last_abs; static word Carrier_lost_timer=0; static word Carrier_found_timer=0; /* #define low_min 0x64 #define low_max 0x6e #define high_min 0x55 #define high_max 0x5f */ #define low_min 0x90 #define low_max 0x9f #define high_min 0x80 #define high_max 0x86 // CCP interupt (RX Demodulator) if ((PIR1bits.CCP1IF==1)&&(PIE1bits.CCP1IE==1)) { this_abs=CCPR1; // get the capture value this_point= this_abs - last_abs; // compute the delta last_abs=this_abs; // save current absolute reading for next pass GPoint = this_point; //LATCbits.LATC3 = 0; if((this_point <= low_max) && (this_point >= low_min)) { Signal_Level = 0; //LED2 = 0; if((Carrier_Detect==0)&&(Carrier_found_timer==0))Carrier_found_timer = 20; if(Carrier_Detect==1)Carrier_lost_timer = 20; } else if((this_point <= high_max) && (this_point >= high_min)) { Signal_Level = 1; //LED2 = 1; if((Carrier_Detect==0)&&(Carrier_found_timer==0))Carrier_found_timer = 20; if(Carrier_Detect==1)Carrier_lost_timer = 20; } else if(Carrier_Detect==0) { Carrier_found_timer = 0; } PIR1bits.CCP1IF=0; // reset interupt } // Timer interupt - used for carrier detect timeout if ((INTCONbits.TMR0IE==1)&&(INTCONbits.TMR0IF==1)) { LATBbits.LATB4=!LATBbits.LATB4; INTCONbits.TMR0IF=0; // reset interupt if((Carrier_Detect==1)&&(Carrier_lost_timer>0)) if(--Carrier_lost_timer==0) Carrier_Detect=0; // carrier is lost; if((Carrier_Detect==0)&&(Carrier_found_timer>0)) if(--Carrier_found_timer==0) Carrier_Detect=1; // carrier is found; if(Carrier_Detect == 1)LED3 = 0; else LED3 = 1; if(Carrier_Detect == 1)LED2 = 0; } } void main (void) { int loc_x, loc_y, TRISA = 0x20; TRISB = 0x0; TRISC = 0x84; OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & BAUD_16_BIT_RATE, 2976 ); BAUDCON=0x08; loc_x=2976; SPBRG = (loc_x&0xff); SPBRGH = (loc_x >> 8); OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_16); // OpenTimer3(TIMER_INT_OFF & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_OSC1EN_OFF & T3_SYNC_EXT_OFF & T3_SOURCE_CCP); // OpenTimer3(0xf9); T3CON=0xf9; CCP1CON=0x00; // reset ccp module CCP1CON=0x04; // set for every 4th edge, 0x06 = every 4th edge - 0x04 = every edge PIR1bits.CCP1IF=0; // Reset the interupt PIE1bits.CCP1IE=1; INTCONbits.PEIE=1; INTCONbits.GIE=1; Carrier_Detect = 0; Signal_Level = 1; loc_x = 0x30; Global_Temp = 0x5533; LED1 = 1; LED2 = 1; LED3 = 1; while(1) { LATBbits.LATB7=!LATBbits.LATB7; if(Carrier_Detect == 1)ReadWirelessTemp(); if(DataRdyUSART()) { loc_x=getcUSART(); if(loc_x == '?') SendTemp(); if(loc_x == 'M') SendMoisture(); // phex16(GPoint); } if((RCSTAbits.OERR == 1)||(RCSTAbits.FERR == 1)) { loc_x = RCREG; RCSTAbits.CREN = 0; Nop(); RCSTAbits.CREN = 1; } ClrWdt(); } } void SendTemp(void) { while(BusyUSART())ClrWdt(); WriteUSART(Global_Temp_Raw >> 8); while(BusyUSART())ClrWdt(); WriteUSART(Global_Temp_Raw & 0xff); LED1 = 1; LED2 = 1; } void SendMoisture(void) { while(BusyUSART())ClrWdt(); WriteUSART(Global_Moisture_Raw >> 8); while(BusyUSART())ClrWdt(); WriteUSART(Global_Moisture_Raw & 0xff); while(BusyUSART())ClrWdt(); WriteUSART((Global_Power_On & 0xff)+0x30); LED1 = 1; LED2 = 1; } void ReadWirelessTemp(void) { // do a bit banged serial rx // first byte can be anything // second byte is 0x55 // third byte is 0xaa // fourth byte is 'T' // fifth and sixth bytes are temp // seventh byte is checksum word shift_reg; //byte rx_data[16]; byte rx_ptr, bit_ctr; word bit_timer; int temp_val; long templ; #define half_cell 350 #define full_cell 615 for(rx_ptr=0; rx_ptr<15; rx_ptr++)rx_data[rx_ptr]=0xff; // for(rx_ptr=0; rx_ptr<7; rx_ptr++) for(rx_ptr=0; rx_ptr<10; rx_ptr++) // changed for moisture - changed again for power fail { while((Carrier_Detect == 1) && (Signal_Level == 1)) ClrWdt(); // wait for start bit if(Carrier_Detect == 0) return; // lost carrier waiting for start bit for(bit_timer = 0; bit_timer < half_cell; bit_timer++)ClrWdt(); if(Signal_Level == 1)return; // if false start then exit shift_reg = 0; for(bit_ctr=0; bit_ctr<9; bit_ctr++) { shift_reg >>= 1; if(Signal_Level & 1)shift_reg |= 0x80; for(bit_timer = 0; bit_timer < full_cell; bit_timer++)ClrWdt(); } if((Carrier_Detect == 0) || (Signal_Level == 0))return; // if carrier lost or overrun exit rx_data[rx_ptr]=shift_reg; } if(rx_data[1] != 0xaa) return; // bad sync byte 1 if(rx_data[2] != 0x55) return; // bad sync byte 2 if(rx_data[3] != 'T') return; // bad ID byte // if(rx_data[6] != (rx_data[4]+rx_data[5])) return; // bad checksum if(rx_data[9] != (rx_data[4]+rx_data[5]+rx_data[6]+rx_data[7]+rx_data[8])) return; // bad checksum with moisture LED1 = 0; temp_val = rx_data[4]; temp_val <<= 8; temp_val |= rx_data[5]; // temp val is signed .0625 degree c units Global_Temp_Raw = temp_val; templ = temp_val; // convert the .0625 degree units to degrees templ *= 625; templ /= 10000; // Convert C to F using (C*1.8)+32 = F templ *= 18L; templ /= 10L; templ += 32; // convert C to F Global_Temp = templ; // and save the new temp temp_val = rx_data[6]; temp_val <<= 8; temp_val |= rx_data[7]; // Save the raw 0-1023 valur for moisture Global_Moisture_Raw = temp_val; Global_Power_On = rx_data[8]; } void phex16(word data) { word tempw; tempw = data; tempw >>= 12; tempw &= 0x0f; if(tempw > 9)tempw+=7; tempw+=0x30; while(BusyUSART())ClrWdt(); WriteUSART(tempw); tempw = data; tempw >>= 8; tempw &= 0x0f; if(tempw > 9)tempw+=7; tempw+=0x30; while(BusyUSART())ClrWdt(); WriteUSART(tempw); tempw = data; tempw >>= 4; tempw &= 0x0f; if(tempw > 9)tempw+=7; tempw+=0x30; while(BusyUSART())ClrWdt(); WriteUSART(tempw); tempw = data; tempw &= 0x0f; if(tempw > 9)tempw+=7; tempw+=0x30; while(BusyUSART())ClrWdt(); WriteUSART(tempw); while(BusyUSART())ClrWdt(); WriteUSART(' '); }