Перейти к содержанию

Vladislav G.

Members
  • Постов

    2
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Vladislav G.

  1. 2 часа назад, ARV сказал:

    Я понял так, что топикстартеру надо определить долгое нажатие, и отреагировать на него не так, как на обычное. Но тогда делается все совсем не так, и гораздо, гораздо проще!

    1. Делаем функцию button_is_pressed(), которая вернет 1, если кнопка нажата, и 0 в противном случае. Эта функция занимается тем, что подавляет дребезг (выше вы уже это делали).
    2. А теперь заводим переменную-счетчик и делаем цикл "пока кнопка нажата - инкремент счетчика и задержка в 10 мс".
    3. После выхода из цикла смотрим на счетчик: его значение будет равно длительности удержания кнопки в нажатом состоянии в десятимиллисекундных интервалах. Ну и соответственно, принимаем решение, что надо сделать если счетчик большой или маленький.

    А зачем так изголяться если можно использовать pulseIn(). Просто делаем условие: если кнопка нажата, считаем время, которое держится сигнал.

  2. А так ли важно определить именно  момент клика? Частота ардуино довольно большая и мне кажется, что определения того, что кнопка сейчас нажата вполне достаточно. Если будет известно, что в предыдущей итерации кнопка была не нажата, а в текущей итерации нажата, то погрешности там будут миллисекунды (если конечно код не очень большой с кучей 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 нолик и в следующий раз ожидание бездействия начнется сначала
        }
    
    }

     

×
×
  • Создать...