#include #include #include #include #include #include #include #include #include #include #include #include "debug.h" #include "analog.h" //#include "dht11.h" #include "rf24.h" #include "lib/Hamming.h" #include "crc8.h" #include "onewire.h" #define EE_Num 0 uint8_t ADDR[5]={0xE7,0xE7,0xE7,0xE7,0xE7}; //{0xE7,0xE7,0xE7,0xE7,0xE7}; // #define PKTLEN 24 #define CMD_DATA 0x20 #define CMD_BIN 0x30 #ifdef DEBUG char debugbuf[32]; uint16_t totaltime; #endif char buffer[18]; char* text = buffer +4; uint8_t sendbuffer[24]; uint8_t id; uint8_t pid=0; volatile bool wdt_flag=false; volatile bool pcint_flag=false; ISR(WATCHDOG_vect){ wdt_flag=true; } ISR(PCINT0_vect){ pcint_flag = true; } // Put in sleep mode until next ISR void sleep(){ #ifdef DEBUG uint16_t time = TCNT1; totaltime +=time; //debughex(&time,2); #endif set_sleep_mode(SLEEP_MODE_PWR_DOWN); cli(); sleep_enable(); //sleep_bod_disable(); sei(); sleep_cpu(); sleep_disable(); #ifdef DEBUG TCCR1A =0; TCCR1C =0; TCNT1 = 0; TCCR1B = 2; #endif } // Sleep for c*8s + 0-6s void wait_for_next(int c){ int cnt=c; #ifdef DEBUG cnt=2; #endif while (cnt--){ wdt_enable(WDTO_8S); WDTCSR |= _BV(WDIE); sleep(); } cnt = rand()%6; while (cnt--){ wdt_enable(WDTO_1S); WDTCSR |= _BV(WDIE); sleep(); } #ifdef DEBUG debughex((char *)(&totaltime),2); totaltime=0; debug("\r"); #endif } // Energy saving mode void power_down(){ stopADC(); power_all_disable(); } // Wait until radio tx done & poweroff void wait_for_radio(){ wdt_enable(WDTO_120MS); wdt_flag=false; pcint_flag = false; cli(); // Sleep until radio ready or wdt 60ms while (bit_is_set(PINA,PA7) || (!wdt_flag) ){ WDTCSR |= _BV(WDIE); sleep(); cli(); // disable interrupts before testing wdt_flag } // disable radio -> low power until next tx rf24_powerDown(); if(!wdt_flag) // radio ok... wait until 60ms { WDTCSR |= _BV(WDIE); // reenable wdt interrupt sleep(); } return; } // Load nRF lib setup in Ram void setupRadio(){ rf24_CONFIG = 0; rf24_RF_CH = 90; rf24_RF_SETUP = 0x26; rf24_FEATURE = 0;//_BV(EN_DPL)|_BV(EN_ACK_PAY)|_BV(EN_DYN_ACK); rf24_DYNPD = 0x00; rf24_RX_PW[0]=PKTLEN; rf24_RX_PW[1]=PKTLEN; rf24_SETUP_RETR = 0x00; rf24_EN_AA = 0x00; } // Restart USI & Reinit nRF24 void initRadio(){ power_usi_enable(); rf24_init(); rf24_writeRegister(RX_ADDR_P0,(uint8_t*)ADDR,5); rf24_writeRegister(TX_ADDR,(uint8_t*)ADDR,5); } // **** // Transmit data buffer void txData(){ uint8_t crc,cpt,a,b,len; uint8_t *in, *out; // Pkt ID buffer[1] = id; buffer[2] = pid++; len = buffer[0] & 0x0F; #ifdef DEBUG debughex(buffer,len); debug("\r"); #endif // CRC Calc buffer[3] = 0; // CRC =0 in crc calc; crc=0; cpt= len; in=(uint8_t*)buffer; while(cpt--) crc = _crc8_ccitt_update(crc,*(in++)); buffer[3] = crc; // Hamming compute cpt= len ; if(cpt & 1) buffer[cpt++]=0; // odd number => add one 0 cpt/=2; in=(uint8_t*)buffer; out = sendbuffer; while(cpt--){ a = *(out++)= *(in++); b = *(out++)= *(in++); *(out++) = HammingCalculateParity2416(a,b); } cpt=4; while (cpt--){ rf24_send(sendbuffer,PKTLEN); wait_for_radio(); } } int main(void) { #ifdef DEBUG DDRB |= _BV(PB0); debug("Sonde Start \r"); #endif uint8_t rvcc=0,rtx=0,delay=6; uint16_t t_i, lt_i=100; int vcc; // Setup power_down(); setupRadio(); id = eeprom_read_byte((const uint8_t*)EE_Num); // random seed initADC(); srand((int)readVcc() * id ); DDRB |= _BV(PB1) ; PORTB &= ~_BV(PB1); while(1){ // each 10 runs => read VCC if(!(rvcc--)){ initADC(); vcc = readVcc(); stopADC(); rvcc=9; } // PowerUp DS18B20 w1_start(); // Wait 15ms (for DS18B20 to start) wdt_enable(WDTO_15MS); WDTCSR |= _BV(WDIE); sleep(); // Start DS18B20 Temp conversion start_meas(); // Wait for 1s wdt_enable(WDTO_1S); WDTCSR |= _BV(WDIE); sleep(); // Read temp & stop DS18B20 t_i = read_meas();//=temp*100; w1_stop(); // If temp change more than 1 since last tx if(t_i > lt_i+1 || t_i < lt_i -1){ // Force Tx rtx=0; } else { delay=6; } // If temp change more than 2 => reduced delay if(t_i > lt_i+2 || t_i < lt_i -2){ // Force Tx delay=2; } if(!(rtx--)){ // Send data initRadio(); buffer[0] = 0x0A | CMD_BIN; // 10 octets : *(uint16_t*)(buffer+4) = 0x0002; // BIN v2 = vcc+tempDS *(uint16_t*)(buffer+6) = vcc; // 2 o *(uint16_t*)(buffer+8) = t_i; // 2 o txData(buffer); // keep tx temp lt_i = t_i; rtx=5; //radio off rf24_powerDown(); } power_down(); wait_for_next(delay); } }