// solar powered remote temperature/humidity/illumination sensor // using xbee xb24 radio. // epv 2/2011 #include #include #include #include #include #include #include #include #include #include "serial.h" #include "sht15.h" #define MYREF _BV(REFS0) #define BLINK() { PORTB |= _BV(0); _delay_ms(50); PORTB &= ~_BV(0); } #define VDIV_ON() { PORTC |= _BV(3); } #define VDIV_OFF() { PORTC &= ~_BV(3); } #define WAKE_MODEM() { PORTD &= ~_BV(2); } #define SLEEP_MODEM() { PORTD |= _BV(2); } #define WAIT() { _delay_ms(100); getchar(); getchar(); getchar(); } #define VDIV_CONST 155.00 // ratio of ADC value to voltage before divider #define NUMSLEEPS 3 // 3 = about 25 seconds with "8" sec WDT ISR(WDT_vect) { } ISR(ADC_vect) { } void go_to_sleep(void); uint16_t read_adc(uint8_t chan) { ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE); set_sleep_mode(SLEEP_MODE_ADC); ADMUX = chan | MYREF; ADCSRA |= _BV(ADSC); sleep_mode(); return(ADCW); } int main(void) { uint16_t batt, light, sum, count=0; uint8_t i; double temp, rh; // data from SHT15 char logline[58]; FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); init_usart(); _delay_ms(100); stdout = stdin = &uart_str; // IO pins setup DDRB |= _BV(0); // blue LED DDRD |= _BV(2); // wake line to XBee DDRD &= ~_BV(3); // CTS line from XBee DDRC |= _BV(3); // switch for battery voltage divider PORTC &= ~_BV(3); // leave it off DDRC |= (1<<5); // C5 = SHT15 clock line BLINK(); sht_reset(); WAKE_MODEM(); _delay_ms(1020); printf("+++"); _delay_ms(1020); printf("ATCE0\r\n"); WAIT(); printf("ATID3332\r\n"); WAIT(); // pan id printf("ATMY01\r\n"); WAIT(); // my address printf("ATDL02\r\n"); WAIT(); // dest address printf("ATSM1\r\n"); WAIT(); // cycl sleep mode, let pin wake it too printf("ATCN\r\n"); WAIT(); // back to cmd mode. BLINK(); printf("I'm alive!\r\n"); sei(); _delay_ms(50); while(1) { BLINK(); // take data before powering up radio to save power. VDIV_ON(); _delay_ms(15); // SHT15 needs 11ms before talking to it batt=read_adc(2); light=read_adc(1); temp=sht_temp(); rh=sht_humidity_comp(temp); VDIV_OFF(); WAKE_MODEM(); // now we're drawing lots of current while((PIND & _BV(3)) != 0); // wait for CTS _delay_ms(20); memset(logline, 0, sizeof(logline)); sprintf_P(logline,PSTR("unit2 %u %.2fv %.1f%% illum %.2f degF %.2f%% rh"), count++, batt / VDIV_CONST, light/10.24, (temp*9/5)+32, rh); sum=CalcCRC(0xFFFFFFFF, logline, sizeof(logline)); printf("%s %04x\r\n", logline, sum); _delay_ms(90); SLEEP_MODEM(); for(i=0; i