Программирование на Arduino. Урок 4. "Карманная гирлянда".

Всем привет! В предыдущей статье мы разбирали циклические операторы, пора применить их на практике! :) У нас сегодня новый урок и новая задачка, над которой зачастую ломают голову новички в программировании Arduino, а к нам она попала благодаря любопытному ученику, который хотел сделать что-то необычное.

Условия задачи таковы:
У нас есть микроконтроллер Arduino, тактовая кнопка (рассмотри два варианта: когда количество кнопок совпадает с количеством режимов, и когда кнопка у нас всего одна, а переключаться нужно между несколькими режимами), несколько светодиодов разного цвета (пусть пока их будет 3).

Приступим к решению этой задачи:
И для начала разберемся как «объяснить» микроконтроллеру, какие элементы мы будем использовать.
Для того чтобы управлять светодиодом, достаточно использовать команду:

digitalWrite(номер пина, к которому подключён светодиод).
Пример:
digitalWrite(5);

Но вот, чтобы горел он как-нибудь необычно, нужно воспользоваться своей фантазией и операциями алгебры логики, но пугайтесь, сейчас обо всем по-порядку:

Этап 1: Подключение тактовой кнопки и считывание с нее сигнала:

Рис. 1 Подключение тактовой кнопки


Этап 2: Включение светодиода по нажатию кнопки:

#define BUTTON_PIN 3 //назначаем пины, которые будут отвечать да работу кнопки и светодиода
#define LED_PIN 13

boolean buttonWasUp = true; //задаем начальные значения для переменных
boolean ledEnabled = false;

void setup()
{
 pinMode(LED_PIN, OUTPUT); //конфигурируем пины, пин кнопки на вход(с него мы будем считывать данные)
 pinMode (BUTTON_PIN, INPUT_PULLUP); //пин светодиода на выход, на него мы будем подавать сигнал
}

void loop()
{
 boolean buttonIsUp = digitalRead(BUTTON_PIN); //проверяем, нажата ли кнопка
 if (buttonWasUp && !buttonIsUp) { //Если нажата, нам нужно подождать 10 миллисекунд
 delay (10); //чтобы убедиться, что это не случайный дребезг
 buttonIsUp = digitalRead (BUTTON_PIN); //Убедившись, что все хорошо и кнопка нажималась
 if (!buttonIsUp) { //Выполняем действие - меняем состояние светодиода на противоположное
 ledEnabled = !ledEnabled;
 digitalWrite(LED_PIN, ledEnabled);
 }
 }
 buttonWasUp = buttonIsUp; //Запоминаем, что мы нажимали кнопку
} //Теперь при следующем нажатии на нее, мы снова изменим состояние светодиода на противоположное
Программа управления светодиодом с помощью одной кнопки

Для считывания сигнала с кнопки необходимо проверять нажатие дважды с небольшой задержкой (от 5-10 мс) для предотвращения реагирования на дребезг. В примере программы выше описано именно такое считывание: введены две переменных buttonWasUp и buttonIsUp, в которые записываются значения считывания сигнала с кнопки с интервалом в 10 мс. В переменной ledEnabled записано значение, которое передается на светодиод. Изначально переменная имеет значение false, т.е. 0, когда считывается нажатие кнопки, значение переменной ledEnabled меняется на противоположное, т.е  true - (1), при следующем считывании нажатия значение снова станет false.
Итак, со считывание сигнала с кнопки мы разобралась.

Этап 3: Количество кнопок равно количеству режимов.
Для увеличения количества элементов, которыми мы будем управлять, мы добавим количество кнопок:
#define BUTTON_PIN_1 3
#define BUTTON_PIN_2 4
#define LED_PIN_1 12
#define LED_PIN_2 13
boolean buttonWasUp_1 = true;
boolean buttonWasUp_2 = true;
boolean ledEnabled_1 = false;
boolean ledEnabled_2 = false;
//Здесь у нас практически тоже самое, вот только кнопок у нас теперь две и два светодиода
void setup()
{
 pinMode(LED_PIN_1, OUTPUT);
 pinMode (LED_PIN_2, OUTPUT);
 pinMode (BUTTON_PIN_1, INPUT_PULLUP);
 pinMode (BUTTON_PIN_2, INPUT_PULLUP);
}
void loop()
{
 boolean buttonIsUp_1 = digitalRead(BUTTON_PIN_1);
 if (buttonWasUp_1 && !buttonIsUp_1) {
 delay(10);
 buttonIsUp_1 = digitalRead (BUTTON_PIN_1);
 if (!buttonIsUp_1) {
 ledEnabled_1 = !ledEnabled_1;
 digitalWrite(LED_PIN_1, ledEnabled_1);
 }
 }
 buttonWasUp_1 = buttonIsUp_1;

 boolean buttonIsUp_2 = digitalRead(BUTTON_PIN_2);
 if (buttonWasUp_2 && !buttonIsUp_2) {
 delay(10);
 buttonIsUp_2 = digitalRead (BUTTON_PIN_2);
 if (!buttonIsUp_2) {
 ledEnabled_2 = !ledEnabled_2;
 digitalWrite(LED_PIN_2, ledEnabled_2);
 }
 }
 buttonWasUp_2 = buttonIsUp_2;
}
Теперь здесь две кнопки и два светодиода


Таким способом можно увеличивать количество кнопок и светодиодов до тех пор пока у нас есть свободные пины.

Этап 4: «Новогодняя гирлянда»
Все видели новогодние гирлянды, в которых по нажатию кнопки переключаются режимы: «Бегущий огонек» или, например, гирлянда начинает постепенно зажигаться и гаснуть.
Давайте попробуем повторить.
Теперь у нас есть всего одна кнопка и несколько режимов «гирлянды», между которыми мы будем переключаться.
Основная идея состоит в том, чтобы считать количество нажатий кнопки. Допустим, у нас три светодиода, между которыми мы хотим переключаться. Тогда нам нужно считать количество нажатий кнопки и находить остаток от деления на три (три режима - остаток от деления на три).

Программа объединяет в себе две предыдущих, с небольшим отличием: использование оператора swich-case, который ставит в соответствие каждому остатку от деления определенное действие.
Подробнее о структуре оператора swich-case расскажу в следующей статье. 
#define BUTTON_PIN 5 //пин, к которому подключена кнопка
#define LED_PIN_1 2 //пин 1 светодиода
#define LED_PIN_2 3 //пин 2 светодиода
#define LED_PIN_3 4 //пин 3 светодиода
int buttonklick = 0; //обнуление переменной-счетчика нажатий кнопки
boolean buttonWasUp = true; // переменная, в которую производится запись была ли кнопка отпущена?

void setup() {
Serial.begin(9600); //подключения монитора порта, для отлаживания программы
//в монитор порта будет выводиться количество нажатий кнопки
for (int i = LED_PIN_1; i <= LED_PIN_3; i++)
{
pinMode(i, OUTPUT);
//конфигурация пинов с помощью цикла с параметром
//i-счетчик параметра
//синтаксис цикла
//for (int i=начальное значение; i(>)<=конечное значение; i++ - шаг)
}

pinMode(BUTTON_PIN, INPUT_PULLUP);
//конфигурация пина для считывания сигнала с кнопки
//INPUT_PULLUP использование внутренних стабилизаторов
//для предотвращения обратного сигнала-дребезга
}

void loop() {
// определить момент «клика» несколько сложнее, чем факт того,
// что кнопка сейчас просто нажата
//для определения клика мы используем "двойную проверку"
boolean buttonIsUp = digitalRead(BUTTON_PIN);
//проверяем, была ли кнопкам нажата
//если «кнопка была нажата и (&&) не отпустили ли мы нажатие сейчас»
if (buttonWasUp && !buttonIsUp)
{
// может это «клик», а может и ложный сигнал (дребезг),
// возникающий в момент замыкания/размыкания пластин кнопки,
// поэтому даём кнопке полностью «успокоиться»...
delay(10);
// считываем сигнал снова
buttonIsUp = digitalRead(BUTTON_PIN);

if (!buttonIsUp)
{ // если она всё ещё нажата...
//считаем количество кликов по кнопке
//прибавляя к предыдущему количеству кликов еще одно
buttonklick = buttonklick + 1;
}
}
//вводим переменную, значение которой будет связано с количеством нажатий кнопки
//ставим в соответствие количеству нажатий определенное действие

int action = buttonklick % 3;
//в переменную действия записывается остаток от деления
//количества нажатий кнопки на количество действий, которые нам необходимо производить
//выводим в монитор порта количество нажатий кнопки и остаток от деления
Serial.println("buttonklick");
Serial.print(buttonklick);
Serial.println("action");
Serial.print(action);
//каждому значению переменной действия
//ставим в соответствие определённое действие
switch (action) {
//Если остаток от деления количества кликов нв количество действий равен 0, то:
case 0: {
digitalWrite(LED_PIN_1, HIGH); //включаем первый светодиод
digitalWrite(LED_PIN_3, LOW); //и выключаем предыдущий
delay(100); //минимальное время, между последовательными переключениями
break;
}
//Если остаток от деления количества кликов на количество действий равен 1, то:
case 1: {
digitalWrite(LED_PIN_2, HIGH);
digitalWrite(LED_PIN_1, LOW);
delay(100);
break;
}
//Если остаток от деления количества кликов на количество действий равен 2, то:
case 2: {
digitalWrite(LED_PIN_3, HIGH);
digitalWrite(LED_PIN_2, LOW);
delay(100);
break;
}
}
}
Программа для "Новогодней гирлянды"

Готовые программы Вы можете скачать по ссылке здесь:

В следующих статьях ждите еще больше интересных проектов. Будем рады, если Вы напишете свои пожелания, о том, что бы Вы хотели видеть на нашем сайте :) 


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