КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Raspberry Pi Pico: подключаем кнопку (Arduino IDE)





Общие сведения

В этом уроке мы научимся обрабатывать состояния кнопки. Для показательности во втором и третьем примере будет использоваться светодиод, с которым мы работали в прошлом уроке.

Для этого урока нам понадобится:

Подключение

Подключим Trema-модуль Светодиод согласно таблице

Вывод модуля Вывод Pi Pico
Vcc 3V3(OUT)
GND GND
S GP15

Подключим Trema-модуль Кнопку согласно таблице

Вывод модуля Вывод Pi Pico
Vcc 3V3(OUT)
GND GND
S GP2

Выводим состояние кнопки в монитор последовательного порта

В следующем примере состояние кнопки считывается в цикле и выводится в монитор:

// определяем вывод к которому подключена кнопка
#define BUT_PIN 2

// создаём переменную для хранения последнего состояния кнопки
bool last_button = false;

void setup()
{
    // Инициируем последовательный порт
    Serial.begin(115200);
    // Устанавливаем работу вывода кнопки на вход
    pinMode(BUT_PIN, INPUT);
}

void loop()
{
    // записываем текущее состояние кнопки
    bool button = digitalRead(BUT_PIN);

    // если текущее состояние кнопки не соответсвует предыдущему
    if (last_button != button) {
        // записываем новое состояние кнопки
        last_button = button;

        // если кнопка нажата, выводи информацию в последовательный порт
        if (button) {
            Serial.println("Кнопка нажата");
        }
    }
    delay(100);
}

Переключаем светодиод

В данном примере мы переключаем состояние светодиода при помощи кнопки. Это простое исполнение кнопки как переключателя.

Пример:

// определяем вывод к которому подключена кнопка
#define BUT_PIN 2
// определяем вывод к которому подключён светодиод
#define LED_PIN 15

// сосдаём переменные для хранения состояния кнопки и светодиода
bool last_button = false;
bool led_state = false;

void setup()
{
    // Инициируем последовательный порт
    Serial.begin(115200);
    // Устанавливаем работу вывода кнопки на вход
    pinMode(BUT_PIN, INPUT);
    // устанавливаем режим работы вывода светодиода
    pinMode(LED_PIN, OUTPUT);
}

void loop()
{
    // записываем текущее состояние кнопки
    bool button = digitalRead(BUT_PIN);

    // если состояние изменилось
    if (last_button != button) {
        // записывем состояние в глобальную переменную
        last_button = button;

        // если состояени - кнопка отжата
        if (!button) {
            // переключаем состояние переменной светодиода
            led_state = !led_state;
            // устанавливаем уровень на выводе светодиода
            digitalWrite(LED_PIN, led_state);
        }
    }
    delay(100);
}

Устранение дребезга

При нажатии или отпускании кнопка может поменять своё состояние несколько раз в течении 50-100 миллисекунд (попробуйте убрать строчку delay(100) из предыдущего примера и посмотрите, что произойдёт). Это называется дребезг кнопки (bounce).

Для устранение этого в предыдущем примере мы использовали функцию sleep. Теоретически эта функция отличается от типичного для ардуино delay, так как она не блокирует другие задачи, запущенные в операционной системе, если таковая имеется, но в контексте данных уроков sleep всё же блокирует текущий поток выполнения. Поэтому рассмотрим неблокирующее устранение дребезга.

Алгоритм данного примера кажется сложным, но на самом деле он очень прост:

  • проверяем состояние кнопки
    • если состояние кнопки изменилось - записываем время изменения
  • продолжаем выполнять программу дальше
    • если подошёл интервал проверки DEBOUNCE_MS и состояние кнопки до сих пор отличается от записанного ранее, значит состояние кнопки действительно изменилось
      • записываем новое состояние
// вывод к которому подключена кнопка
#define BUT_PIN 2
// вывод к которому подключён светодиод
#define LED_PIN 15
// интервал для устранения дребезга
#define DEBOUNCE_MS 100
// интервал для вывода информации в последовательный порт
#define PRINT_INTERVAL 2000

// переменные для хранения состояний кнопки
bool button_state = false;
bool last_state = false;
// переменная для хранения состояние светодиода
bool led_state = false;
// переменные для хранения относительного времени событий
unsigned long debounce_millis, print_millis;

void setup()
{
    // инициируем работу с последовательным портом
    Serial.begin(115200);
    // Устанавливаем работу вывода кнопки на вход
    pinMode(BUT_PIN, INPUT);
    // Устанавливаем работу вывода светодиода на выход
    pinMode(LED_PIN, OUTPUT);
}

void loop()
{
    // записываем текущее состояние кнопки
    bool current_state = digitalRead(BUT_PIN);

    // если состояние изменилось, записываем время изменения
    if (current_state != last_state) {
        debounce_millis = millis();
    }

    // если подошёл интервал устранения дребезга
    if (millis() - debounce_millis > DEBOUNCE_MS) {

        // если состояние кнопки не соответсвует записаному ранее
        if (current_state != button_state) {
            // записываем новое состояние
            button_state = current_state;

            // Если новое состояние - отжатая кнопка
            if (!button_state) {
                // Переключаем светодиод
                led_state = !led_state;
                digitalWrite(LED_PIN, led_state);
            }
        }
    }

    // Записиваем последнее состояние кнопки
    last_state = current_state;

    // Выводим текст через интервал
    if (millis() - print_millis > PRINT_INTERVAL) {
        print_millis = millis();
        Serial.println("Выполняем что-то ещё, устранение дребезга кнопки не блокирует поток");
    }
}

Ссылки




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями