#include #include #include uint32_t read_capacitance(dio_t *dio) { uint32_t i; dio_set_direction(dio, LINE_OUT); dio_set(dio, 1); i = 0; dio_set_direction(dio, LINE_IN); while (dio_read(dio) > 0) i++; return i; } uint32_t calibrate(dio_t *dio) { uint32_t max = 0; for (uint8_t i = 0; i < 100; i++) { uint8_t cap = read_capacitance(dio); max = cap > max ? cap : max; _delay_ms(10); } return max; } int main(void) { dio_t sensor = (dio_t){ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 0 }; display_t display = { .reg = { .output = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 4 }, .shift_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 3 }, .latch_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 2 }, }, }; display_init(&display); display_enable(&display); display_clear(&display); // calibration // // 100 times: // Output 1 // Switch to Input // measure in a loop until the input is 0 // save the measurement // // normal function // Output 1 // Switch to input // measure in a loop until the input is 0 // check against the saved measurement // enable pin if significantly higher than the saved measurement // update the average MCUCR |= _BV(PUD); uint8_t calibration_countdown = 0; uint32_t calibration = 0; bool touch = false; while (1) { if (calibration_countdown == 0 && !touch) { calibration = calibrate(&sensor); calibration_countdown = 100; char msg[20]; snprintf(msg, 20, "calib: %6ld", calibration); display_set_location(&display, 0, 0); display_write_message(&display, msg); } uint32_t cap = read_capacitance(&sensor); if (cap > calibration) { display_set_location(&display, 1, 0); display_write_message(&display, "touch!"); touch = true; } else if (touch) { display_set_location(&display, 1, 0); display_write_message(&display, " "); touch = false; } if (calibration_countdown > 0) { calibration_countdown--; } _delay_ms(100); } }