Как настроить долгое нажатие на что-то, кроме кнопки?

Я написал программу для ночника. Есть 4 режима:

  • на,
  • регулируемая яркость,
  • таймер,
  • выкл.

Для ввода вместо кнопки я использую датчик расстояния. После считывания определенного расстояния (например, при проведении рукой над датчиком расстояния) он переходит в следующий режим.

Для режима регулируемой яркости он считывает датчик расстояния и сопоставляется с ШИМ. Выходной штифт подключен к MOSFET, который переключает 12-вольтовый светодиод.

Кажется, это медленный способ циклического прохождения системы. Я бы хотел, чтобы вместо этого, если пользователь провел рукой над датчиком, он включался или выключался. Однако, если пользователь ждал 3 секунды, держа руку над датчиком, он включал режим регулировки яркости. Меня больше не беспокоит функция таймера, и я ее уберу.

Весь код уже есть, за исключением того, что мне нужна помощь в написании функции, которая будет отслеживать, как долго датчик считывает определенное расстояние. Допустим, например, если датчик считывает расстояние от 1 до 3 дюймов в течение 3 секунд, он перейдет в режим регулировки яркости. Если он меньше этого, он будет только переключаться вкл./выкл. Если рука остается дольше 3 секунд, он также включит режим регулировки яркости.

//-----------------------------------------------------------
// ИСПОЛЬЗОВАНИЕ ДАТЧИКА РАССТОЯНИЯ ДЛЯ ПЕРЕКЛЮЧЕНИЯ РАЗЛИЧНЫХ РЕЖИМОВ
// ДЛЯ СВЕТОДИОДНОГО НОЧНИКА
// вондераше
//-----------------------------------------------------------

// объявляет библиотеку для датчика расстояния
#include <NewPing.h>
// константы
#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define MAX_DISTANCE 200
const unsigned long onTime = 5000;
const unsigned long onTimer = 1200000;

int state = 1;

// объявляет объект NewPing
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
    Serial.begin(9600);
}

void loop() {
    delay(50);
    // считывать расстояния
    int distance = sonar.ping_in();
    static enum { ON, ADJUST, TIMER } state;

    // если диапазон расстояний находится между определенными значениями, переключить состояние
    if (distance > 1 && distance < 3) {
        switch(state) {
        case ON:
          {
            // включает светодиоды
            Serial.println("ON");
            analogWrite(3, 255);
            analogWrite(5, 255);
            state = ADJUST;
            delay(1000);
          }
          break;
        case ADJUST:
          {
            // позволяет пользователю устанавливать яркость в зависимости от расстояния руки до датчика
            Serial.println("Adjusting Brightness");
            int distance2 = 0;
            int mappedBrightness = 0;
            unsigned long previousMillis = millis();
            unsigned long currentMillis = millis();

            // таймер для установки яркости
            while ((currentMillis - previousMillis) < onTime) {
                int distance2 = sonar.ping_in();
                if (distance2 >= 1 && distance2 <= 6) {
                    mappedBrightness = map(distance2, 0, 6, 13, 255);
                    analogWrite(3, mappedBrightness);
                    analogWrite(5, mappedBrightness);
                }
                currentMillis = millis();
            }
            Serial.print("Mapped Brightness = ");
            Serial.println(mappedBrightness);
            delay(1000);
            state = TIMER;
          }
          break;

        case TIMER:
          {
            Serial.println("TIMER - 20 MINS");
            // объявление переменной
            unsigned long ontime = 50;
            unsigned long previousMillis = millis();
            unsigned long currentMillis = millis();

            // затемняет светодиоды до 25 процентов
            analogWrite(3, 64);
            analogWrite(5, 64);
            delay(1000);
            // таймер для светодиодов
            while ((currentMillis - previousMillis) < onTimer) {
                int distance2 = sonar.ping_in();
                // останавливает таймер, если провести рукой
                if (distance2 >= 1 && distance2 <= 4) {
                    break;
                }
                currentMillis = millis();
            }
            // выключить светодиоды - либо произошло скольжение руки, либо истекло время таймера
            Serial.println("Turn off LEDs.");
            analogWrite(3, 0);
            analogWrite(5, 0);
            delay(1000);
            state = ON;
          }
          break;
        }
    }
}

, 👍1


1 ответ


1

Это не слишком отличается от длительного нажатия кнопки. Давайте рассмотрим код для обнаружения длительного нажатия кнопки, длящегося более 3 секунд.

buttonState = digitalRead(PIN1);

if (buttonstate == HIGH)
{
    if ((currentMillis - previousMillis) > THREE_SECONDS)
    {
        // Поместите свой код здесь
    }
}
else  // т.е. buttonState == LOW
{
    previousMillis = currentMillis;
}

Хорошо, код можно оптимизировать. Однако он показывает код для долгого нажатия кнопки и, надеюсь, его легко понять новичкам. Код выше считывает состояние кнопки, и если оно ВЫСОКОЕ (т. е. нажато), он затем проверяет, проработал ли таймер более 3 секунд. Однако если отпустить кнопку, таймер сбрасывается.

Теперь рассмотрим код для датчика расстояния:

int distance = sonar.ping_in();

if (distance >= 1 && distance <= 3)
{
    if ((currentMillis - previousMillis) > THREE_SECONDS)
    {
        // Поместите свой код здесь
    }
}
else  // т.е. за пределами диапазона
{
    previousMillis = currentMillis;
}

Вы заметите, что меняются только первые две строки. Надеюсь, это поможет!!

,