Программирование на Arduino. Урок 3. Циклические операторы на практике.

Пришло время снова окунуться в мир Aduino!

Этот урок уже третий, так что пора переходить от слов к делу! Давайте рассмотри примеры применения алгоритмов на практике. И так, по порядку: на прошлом уроке мы изучили уcловные и циклические операторы.
Начнем с условных. Итак, где же мы можем их применять? Да практически везде! Ведь это один из самых используемых нелинейных операторов.
И, для примера, вот задачка: По нажатию кнопки включать светодиод, по второму нажатию выключать его.
Звучит достаточно просто, приступим.
Прежде, чем подавать сигналы включения, выключения или считывания данных с какого либо элемента, необходимо «объяснить» микроконтроллеру, что мы к нему подключили. Для того, чтобы подключить светодиод, нам нужна земля (GND) и сигнальный провод, который мы подключим к цифровому (или аналоговому) пину на плате. У светодиода есть особенность: мы обязательно должны включить в электрическую схему резистор номиналом 220 Ом (для светодиода 5V), чтобы ограничить ток, который будет протекать в цепи (рабочий ток через пин не должен превышать 0,05 А). Исходя из этого, схема подключения будет выглядеть так:


Теперь давайте разберемся в алгоритме для подключения светодиода:
void setup()
{
 pinMode(13, OUTPUT); \\конфигурируем пин так, чтобы получать с него сигал, т.е. на передачу сигнала с МК
}
void loop()
{
 digitalWrite(13, HIGH); \\передаем высокий сигнал (включаем светодиод)
 delay(500); \\даем ему на выполнение предыдущей команды 500 мс (0,5 сек)
 digitalWrite(13, LOW);\\ теперь выключаем
 delay(500); \\выключаем тоже на 0,5 сек
}

Так как цикл loop-бесконечный, светодиод будет включаться и выключаться до тех пор, пока мы не отключили плату от компьютера (от внешнего источника питания, если Arduino подключена так).


Теперь давайте подключим кнопку. Для этого нам снова понадобится всего два провода, подключенных к Arduino: земля (GND) и сигнал (с любого цифрового пина, например, 13). Схема подключения выглядит так:

Схема подключения светодиода

Теперь нам нужно научиться определять тот момент, когда кнопка нажата и здесь уже нам пригодится знания об условных операторах.
#define BUTTON_PIN 3
#define LED_PIN 13
boolean button_old = true; // нажата ли кнопка?
boolean led_now = false; // включен ли светодиод


void setup()
{
 pinMode(LED_PIN, OUTPUT);
 pinMode(BUTTON_PIN, INPUT_PULLUP);
}
 
void loop()
{
 boolean button_new = digitalRead(BUTTON_PIN); //определяем, была ли нажата кнопка
 if (button_old && !button_new) { //проверяем не было ли «нажатие» дребезгом (нужно пояснить. что это??)
 delay(10); //для этого еще раз опрашиваем кнопку, нажата ли она
 button_new = digitalRead(BUTTON_PIN);
 if (!button_new) {// если если в момент считывания через 10 мс кнопка все еще нажата-то это физическое нажатие
 led_now= !led_now; //меняем состояние светодиода на противоположное (если он горел, то выключить, есть был выключен-включить)
 digitalWrite(LED_PIN, led_now);
 }
 }
 button_old = button_new; \\для следующего шага запоминаем текущее состояние кнопки как старое значение
}

Итак, на этом небольшом скетче наглядно можно увидеть, что если в первой строке опроса кнопки значение будет false (кнопка не нажата), то условие для оператора if будет ложно и вся остальная часть программы, заключенная внутри оператора, не выполнится.

А теперь давайте добавим в этот же алгоритм полное ветвление (т.е. если кнопка не нажата, будет выполняться другое действие).
Пусть это будет еще один светодиод, который будет гореть тогда, когда не горит первый.
В схему добавится еще один светодиод (другого цвета), который нужно будет подключить по такой же схеме, как и первый, обязательно с резистором на 220 Ом к любому свободному сигнальному пину на Arduino.
А вот так будет выглядеть программная реализация:
#define BUTTON_PIN 3
#define LED_PIN_1 13
#define LED_PIN_2 12
boolean button_old = true; // нажата ли кнопка?
boolean led_1_now = false; // включен ли светодиод 1
boolean led_2_now = true; // включен ли светодиод 2


void setup()
{
 pinMode(LED_PIN_1, OUTPUT);
 pinMode(LED_PIN_2, OUTPUT);
 pinMode(BUTTON_PIN, INPUT_PULLUP);
}
 
void loop()
{
 boolean button_new = digitalRead(BUTTON_PIN); //определяем, была ли нажата кнопка
 if (button_old && !button_new) { //проверяем не было ли «нажатие» дребезгом (нужно пояснить. что это??)

 delay(10); //для этого еще раз опрашиваем кнопку, нажата ли она
 button_new = digitalRead(BUTTON_PIN);
 if (!button_new) { // если в момент считывания через 10 мс кнопка все еще нажата, то это физическое нажатие
 led_1_now= !led_1_now; //меняем состояние светодиода на противоположное (если он горел, то выключить, есть был выключен-включить)
 digitalWrite(LED_PIN_1, led_1_now);
 }
 }
 else {
 digitalWrite(LED_PIN_2, led_2_now);
 delay(100);
 }
 button_old = button_new; //для следующего шага запоминаем текущее состояние кнопки как старое значение
}

Существует еще один вариант решения второй задачи, который будет давать тот же результат, но реализован с помощью неполного ветвления:
#define BUTTON_PIN 3
#define LED_PIN_1 13
#define LED_PIN_2 12
boolean button_old = true; // нажата ли кнопка?
boolean led_1_now = false; // включен ли светодиод 1
boolean led_2_now = true; // включен ли светодиод 2
void setup()
{
 pinMode(LED_PIN_1, OUTPUT);
 pinMode(LED_PIN_2, OUTPUT);
 pinMode(BUTTON_PIN, INPUT_PULLUP);
}
 
void loop()
{
 boolean button_new = digitalRead(BUTTON_PIN); //определяем была ли нажата кнопка
 if (button_old && !button_new) { //проверяем не было ли «нажатие» дребезгом (нужно пояснить. что это??)

 delay(10); //для этого еще раз опрашиваем кнопку, нажата ли она
 button_new = digitalRead(BUTTON_PIN);
 if (!button_new) {// если в момент считывания через 10 мс кнопка все еще нажата, то это физическое нажатие
 led_1_now= !led_1_now; //меняем состояние светодиода на противоположное (если он горел, то выключить, есть был выключен-включить)
 led_2_now= !led_2_now;//со вторым светодиодом тоже самое, меняем его состояние на противоположное
 digitalWrite (LED_PIN_1, led_1_now);
 digitalWrite (LED_PIN_2, led_2_now);
 }
 }
 button_old = button_new; //для следующего шага запоминаем текущее состояние кнопки как старое значение
}

В решении любой задачи существует не одно решение, поэтому не бойтесь экспериментировать!
В следующей статье разберем применение циклических операторов на практике.

Новость отредактировал: April - 27-11-2020, 22:18

Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.