int main( int argc, char **argv ) { int i; for (i = 1; i < argc; i++) { char *val = argv[i]; struct tst *timer = nfmalloc( sizeof(*timer) ); init_wakeup( &timer->timer, timed_out, timer ); init_wakeup( &timer->morph_timer, morph_timed_out, timer ); timer->id = ++nextid; timer->first = strtol( val, &val, 0 ); if (*val == '@') { timer->other = timer->first; timer->first = strtol( ++val, &val, 0 ); } else { timer->other = -1; } if (*val == ':') { timer->morph_to = strtol( ++val, &val, 0 ); if (*val != '@') goto fail; timer->morph_at = strtol( ++val, &val, 0 ); } else { timer->morph_at = -1; } if (*val) { fail: fprintf( stderr, "Fatal: syntax error in %s, use <timeout>[@<delay>][:<newtimeout>@<delay>]\n", argv[i] ); return 1; } timer_start( timer, timer->first ); if (timer->morph_at >= 0) { printf( "timer %d, should morph after %d\n", timer->id, timer->morph_at ); conf_wakeup( &timer->morph_timer, timer->morph_at ); } } main_loop(); return 0; }
int main(void) { uint8_t i; uint16_t wakeup_sec; bool send; // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); util_init(); check_eeprom_compatibility(DEVICETYPE_SOILMOISTUREMETER); // configure power pin for 74HC14D as output sbi(TRIGGERPWR_DDR, TRIGGERPWR_PIN); // read packetcounter, increase by cycle and write back packetcounter = e2p_generic_get_packetcounter() + PACKET_COUNTER_WRITE_CYCLE; e2p_generic_set_packetcounter(packetcounter); // read device id device_id = e2p_generic_get_deviceid(); dry_thr = e2p_soilmoisturemeter_get_drythreshold(); if (dry_thr == 0) // set default value if never initialized { dry_thr = 40000; } counter_min = e2p_soilmoisturemeter_get_minval(); if (counter_min == 0) // set default value if never initialized { counter_min = 30000; } avgIntInit = e2p_soilmoisturemeter_get_averagingintervalinit(); avgInt = e2p_soilmoisturemeter_get_averaginginterval(); smoothing_percentage = e2p_soilmoisturemeter_get_smoothingpercentage(); osccal_init(); uart_init(); UART_PUTS ("\r\n"); UART_PUTF4("smarthomatic Soil Moisture Meter v%u.%u.%u (%08lx)\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_HASH); UART_PUTS("(c) 2014..2015 Uwe Freese, www.smarthomatic.org\r\n"); osccal_info(); UART_PUTF ("DeviceID: %u\r\n", device_id); UART_PUTF ("PacketCounter: %lu\r\n", packetcounter); UART_PUTF ("AveragingInterval for initialization: %u\r\n", avgIntInit); UART_PUTF ("AveragingInterval for normal operation: %u\r\n", avgInt); UART_PUTF ("Dry threshold: %u\r\n", dry_thr); UART_PUTF ("Min value: %u\r\n", counter_min); UART_PUTF ("Smoothing percentage: %u\r\n", smoothing_percentage); adc_init(); // init AES key e2p_generic_get_aeskey(aes_key); // set pull-up for BUTTON_DDR sbi(BUTTON_PORT, BUTTON_PIN); _delay_ms(10); // set DIDR for all ADC channels and AINs, switch off digital input buffers to reduce ADC noise and to save power DIDR0 = 63; DIDR1 = 3; // If button pressed at start up, go to sleep for idle power consumption test. // Don't communicate with RFM12, which may not have been connected yet. if (BUTTON) { led_blink(50, 50, 20); power_down(true); } led_blink(500, 500, 3); rfm12_init(); wakeup_sec = init_wakeup(); // init interrupt for button (falling edge) sbi(EICRA, ISC11); sbi(EIMSK, INT1); sei(); for (i = 0; i < SEND_STATUS_TIMES_AT_STARTUP; i++) { prepare_deviceinfo_status(); send_prepared_message(); _delay_ms(800); prepare_battery_status(); send_prepared_message(); _delay_ms(800); } while (42) { if (BUTTON) { led_blink(100, 0, 1); UART_PUTS("Button pressed!\r\n"); uint8_t cnt = 0; while (BUTTON && (cnt < 250)) { _delay_ms(10); cnt++; } if (cnt == 250) { UART_PUTS("Long press -> initiate measure mode!\r\n"); while (BUTTON) { led_blink(100, 100, 1); } init_mode = true; wupCnt = 0; counter_meas = 0; init_wakeup(); // to usually shorter value UART_PUTS("Button released!\r\n"); _delay_ms(10); } } else { send = true; //UART_PUTF("version_status_cycle = %u\r\n", version_status_cycle); if (!measure_humidity()) { if (battery_status_cycle > 0) battery_status_cycle--; if (version_status_cycle > 0) version_status_cycle--; if (version_status_cycle == 0) { version_status_cycle = SEND_VERSION_STATUS_CYCLE; prepare_deviceinfo_status(); } else if (battery_status_cycle == 0) { battery_status_cycle = SEND_BATTERY_STATUS_CYCLE; prepare_battery_status(); } else { send = false; } } if (send) { send_prepared_message(); } } power_down(true); } // never called // aes256_done(&aes_ctx); }
// Measure humidity, calculate relative value in permill and return it. // Return true, if humidity was sent. bool measure_humidity(void) { bool res = false; uint16_t cnt; switch_schmitt_trigger(true); _delay_ms(10); // make PD5 an input and disable pull-ups DDRD &= ~(1 << 5); PORTD &= ~(1 << 5); // clear counter TCNT1 = 0x00; // configure counter and use external clock source, rising edge TCCR1A = 0x00; TCCR1B |= (1 << CS12) | (1 << CS11) | (1 << CS10); _delay_ms(100); //cnt = (TCNT1H << 8) | TCNT1L; cnt = TCNT1; TCCR1B = 0x00; // turn counter off switch_schmitt_trigger(false); counter_meas += cnt; wupCnt++; UART_PUTF4("Init mode %u, Measurement %u/%u, Counter %u\r\n", init_mode, wupCnt, init_mode ? avgIntInit : avgInt , cnt); if ((init_mode && (wupCnt == avgIntInit)) || (!init_mode && (wupCnt == avgInt))) { uint32_t avg = init_mode ? counter_meas / avgIntInit : counter_meas / avgInt; if (init_mode) { UART_PUTF("Init: Save avg %u as dry threshold.\r\n", avg); dry_thr = avg; counter_min = dry_thr - 1; init_mode = false; init_wakeup(); // to normal value e2p_soilmoisturemeter_set_drythreshold(dry_thr); } else { int32_t result; if (avg < counter_min) { counter_min = avg; UART_PUTF("New min: %lu, ", counter_min); } if (avg > dry_thr) { result = 0; } else { result = (dry_thr - avg) * 1000 / (dry_thr - counter_min); } UART_PUTF("Avg: %u, ", avg); UART_PUTF("Result: %lu permill\r\n", result); // Don't change reported value if it changes within a window of // some percent. if (reported_result == 0) { reported_result = result; } else { if (direction_up) { if (result > reported_result) { reported_result = result; } else if (result < reported_result - smoothing_percentage * 10) { reported_result = result; direction_up = false; } } else // direction down { if (result < reported_result) { reported_result = result; } else if (result > reported_result + smoothing_percentage * 10) { reported_result = result; direction_up = true; } } } prepare_humidity_status((uint16_t)reported_result); //prepare_humidity_status_RAW_DBG((uint16_t)reported_result, (int16_t) MIN((int32_t)avg, 30000)); // for debugging only res = true; } wupCnt = 0; counter_meas = 0; } _delay_ms(10); return res; }