А так ли важно определить именно момент клика? Частота ардуино довольно большая и мне кажется, что определения того, что кнопка сейчас нажата вполне достаточно. Если будет известно, что в предыдущей итерации кнопка была не нажата, а в текущей итерации нажата, то погрешности там будут миллисекунды (если конечно код не очень большой с кучей delay()). Писал я как-то код для модуля джойстика с кнопкой
/* Код предназначен для джойстика и кнопки. Выпоняет следующий алгоритм: при нажатии кнопки и удержании ее в течении 2 секунд, открывается прим данных с джойстика.
* Если перемещение джойстика прекращается и не начинается в течении 5 секунд, то прием данных закрывается и программа ожидает следующего нажатия на кнопку.
*/
int axis_X = A0; // Ось Х
int axis_Y = A1; // Ось Y
int button = 2; // Кнопка
int vaule_X = 0; //Текущее значение оси Х
int vaule_Y = 0; //Текущее значение оси Y
int vaule_XP; //Предыдущее значение оси Х
int vaule_YP; //Предыдущее значение оси Y
unsigned long timeout = 10000000; // таймаут функции 10 сек
unsigned long TIME = 0;
unsigned long n_time = 2000000; // условное время начала према данных (мкс)
int k_time = 5000; // условное время закрытия приема (мс)
int nT = 0; // Переменные для отсчитывания времени бездействия
int kT = 0;
int condition_1 = 0; //условие начала приема данных
int condition_2 = 0; //условие, определяющее бездействие
void setup() {
Serial.begin(9600); //настройка КОМ - порта
pinMode(axis_X, INPUT); // оси и кнопка это входы
pinMode(axis_Y, INPUT);
pinMode(button, INPUT);
Serial.println("Hello"); //Здрасьте
}
void loop() {
if ((digitalRead(button) == LOW) && (condition_1 == 0)) // если кнопка нажата и прием данных закрыт
{
TIME = pulseIn(button, LOW, timeout); // время, которое кнопка была нажата
if (TIME >= n_time) // если время нажатия больше или равно двум секундам
{
condition_1 = 1; // тогда условию 1 присваиваем единичку
TIME = 0; //обнуляем времячко
Serial.println("Data reception is open"); //пишем, что открыт прием данных
}
}
if (condition_1 == 1) //если условие 1 единичка, то принимаем данные
{
vaule_XP = vaule_X; // данные в предыдущей итерации
vaule_YP = vaule_Y;
vaule_X = map(analogRead(axis_X), 0, 1023, -10, 10); //данные в текущей итерации
vaule_Y = map(analogRead(axis_Y), 0, 1023, -10, 10);
Serial.print("X: "); //пишем данные в КОМ
Serial.print(vaule_X);
Serial.print(" | Y: ");
Serial.println(vaule_Y);
delay(500); // ждем просто так
if ((vaule_X == vaule_XP) && (vaule_Y == vaule_YP)) //если данные в предыдущей итерации и в текущей совпадают, значит изменения не произошло, значит бездействуем
{
if (condition_2 == 0) // если условие 2 нолик, то это значит, что бездействие началось только что
{
nT = millis(); // запоминаем время начала бездействия
condition_2 = 1; // условию 2 присваиваем единичку, чтобы время nT не перезаписвалось с каждой новой итерацией
}
if (condition_2 == 1) //если условие 2 единичка, значит бездействие уже идет
{
kT = millis(); // текущее время
if (kT - nT >= k_time) // если бездействие длилось 5 секунд
{
condition_2 = 0; //заканчиваем бездействие
condition_1 = 0; //закрываем прием данных
Serial.println("Data reception is close"); //пишем, что прием данных закрыт
}
}
}
else { condition_2 = 0;} //если значения поменялись, присваиваем условию 2 нолик и в следующий раз ожидание бездействия начнется сначала
}
}