Уроки Ардуино: Два светофора для перекрестка дороги на базе Arduino. Часть 2..
Сегодня у нас вторая часть урока по созданию на базе Arduino двух светофоров для перекрестка дороги (урок Ардуино №1). Напоминаем, детали для создания светофора Ардуино Вы сможете найти в каждом из конструкторов Arduino серии «Дерзай» («Базовый», «Изучаем Arduino» и «Умный дом»).
Вот этот список деталей:
- Arduino Uno;
- Кабель USB;
- Плата прототипирования;
- Провода «папа-папа» — 7 шт;
- Резисторы 220 Ом – 6 шт;
- Светодиоды красные – 2 шт;
- Светодиоды зеленые – 2 шт;
- Светодиоды желтые – 2 шт.
И схема (см. рисунок 1), которую мы собирали в первой части урока.

Рисунок 1. Схема соединений
В первой части урока мы написали скетч работы одного светофора. Теперь добавим второй светофор. Второй светофор горит красным цветом, когда первый зеленым, и наоборот. Сделать это было несложно и на первом уроке, но сейчас мы рассмотрим методы программирования, оптимизирующие программу. Мы рассмотрим массивы (или списки) и научимся использовать функции.
Массивы (arrays) — именованный набор однотипных переменных, с доступом к отдельным элементам по их индексу. Например, создадим массив, в котором будут собраны контакты для подключения светодиодов двух наших светофоров. В программном коде Arduino это будет выглядеть так:
int pinleds[]={7,8,9,10,11,12};
Мы создали массив из 6 элементов. Индексация массива начинается с 0.
Нулевой элемент массива pinleds[0]=7 – вывод для подключения зеленого светодиода первого светофора.
Первый элемент массива pinleds[1]=8 – вывод для подключения желтого светодиода первого светофора.
Второй элемент массива pinleds[2]=9 – вывод для подключения красного светодиода первого светофора.
Третий элемент массива pinleds[3]=10 – вывод для подключения зеленого светодиода второго светофора.
Четвертый элемент массива pinleds[4]=11 – вывод для подключения желтого светодиода второго светофора.
Пятый элемент массива pinleds[5]=12 – вывод для подключения красного светодиода второго светофора.
Если бы мы объявляли значения выводов Arduino, как в скетче из первой части урока, это выглядело бы так:
#define PIN_GREEN1 7 #define PIN _RED1 9 #define PIN_YELLOW1 8 #define PIN_GREEN2 10 #define PIN _RED2 12 #define PIN_YELLOW2 11
И сравните код для включения всех 6 светодиодов при работе с массивами
for(int i=0;i<6;i++)
{digitalWrite(pinleds[i], HIGH);}
И без
digitalWrite(PIN_GREEN1, HIGH); digitalWrite(PIN_YELLOW1, HIGH); digitalWrite(PIN_RED1, HIGH); digitalWrite(PIN_GREEN2, HIGH); digitalWrite(PIN_YELLOW2, HIGH); digitalWrite(PIN_RED2, HIGH);
Теперь рассмотрим использование функций. Функции используют для многократного использования повторяющегося кода. Это фрагмент программного кода, к которому можно обратиться из другого места программы. Функция может принимать параметры и должна возвращать некоторое значение, возможно пустое. Функции, которые возвращают пустое значение, часто называют процедурами.
Каждая функция в языке Си должна быть определена, то есть должны быть указаны:
тип возвращаемого значения;
имя функции;
информация о формальных аргументах;
тело функции.
Создадим функцию, которая будет принимать состояние светодиодов светофора (данные будем передавать в качестве массива) и устанавливать состояния выводов, к которым подключены светодиоды двух наших светофоров. В языке С нельзя передать весь массив как аргумент функции. Однако можно передать указатель на массив, т.е. имя массива без индекса.
// список состояний светодиодов 1-горит, 0- потушен
// [green1,yellow1,red1,green2,yellow2,red2]
// все потушены
int leds[]={LOW,LOW,LOW,LOW,LOW,LOW};
// функция зажигания светодиодов светофора
void trafficlight(int statled[5])
{
for(int i=0;i<6;i++)
{
digitalWrite(pinleds[i],statled[i]);
}
}
Вынесем все возможные состояния светофоров в массивы в основном циклк программы loop()
// список состояний светодиодов 1-горит, 0- потушен
// [green1,yellow1,red1,green2,yellow2,red2]
// 1 светофор - зеленый, 2 светофор - красный
int leds1[]={HIGH,LOW,LOW,LOW,LOW, HIGH};
// 1 светофор - желтый с зеленым, 2 светофор - желтый c красным
int leds2[]={HIGH,(int)blinkyellow,LOW,LOW,(int)blinkyellow,HIGH};
// 1 светофор - красный, 2 светофор - зеленый
int leds3[]={LOW,LOW,HIGH,HIGH,LOW,LOW};
// 1 светофор - желтый c красным, 2 светофор - желтый с зеленым
int leds4[]={LOW,(int)blinkyellow,HIGH,HIGH,(int)blinkyellow,LOW};
И тогда для установки необходимых значений светофора необходимо вызвать функцию trafficlight(), передав в качестве аргумента указатель на нужный массив, например
trafficlight(leds4);
Создадим в Arduino IDE новый скетч, занесем в него код из листинга 1 и загрузим скетч на на плату Arduino.
Листинг 1
// Выводы Arduino для подключения светодиодов
// список
// [green1,yellow1,red1,green2,yellow2,red2]
int pinleds[6]={7,8,9,10,11,12};
// список состояний светодиодов 1-горит, 0- потушен
// [green1,yellow1,red1,green2,yellow2,red2]
// все потушены
int leds[]={LOW,LOW,LOW,LOW,LOW,LOW,};
// время горения светодиодов в мсек
// зеленый
#define TIME_GREEN 5000
// красный
#define TIME_RED 5000
// желтый
#define TIME_YELLOW 3000
// период мигания желтого
#define TIME_BLINK 300
// переменная blink для чередования мигания желтого
boolean blinkyellow=true;
void setup()
{
// настроить выводы Arduino как выходы
// и потушить все светодиоды
for(int i=0;i<6;i++)
{
pinMode(pinleds[i], OUTPUT);
digitalWrite(pinleds[i],leds[i]);
}
}
// the loop function runs over and over again forever
void loop()
{
// 1 - зеленый, 2 - красный
// список состояний светодиодов 1-горит, 0- потушен
// [green1,yellow1,red1,green2,yellow2,red2]
int leds1[]={HIGH,LOW,LOW,LOW,LOW, HIGH};
trafficlight(leds1);
delay(TIME_GREEN);
blinkyellow=true;
// 1 - желтый с зеленым, 2- желтый c красным
for(int i=0;i<(TIME_YELLOW/TIME_BLINK);i++)
{
int leds2[]={HIGH,(int)blinkyellow,LOW,LOW,(int)blinkyellow,HIGH};
trafficlight(leds2);
delay(TIME_BLINK);
blinkyellow=!blinkyellow;
}
// 1 - красный, 2 - зеленый
int leds3[]={LOW,LOW,HIGH,HIGH,LOW,LOW};
trafficlight(leds3);
delay(TIME_GREEN);
blinkyellow=true;
// 1- желтый c красным, 2 - желтый с зеленым
//for(int i=0;i<(TIME_YELLOW/TIME_BLINK);i++)
for(int i=0;i<TIME_YELLOW;i=i+TIME_BLINK)
{
int leds4[]={LOW,(int)blinkyellow,HIGH,HIGH,(int)blinkyellow,LOW};
trafficlight(leds4);
delay(TIME_BLINK);
blinkyellow=!blinkyellow;
}
}
// функция зажигания светодиодов светофора
void trafficlight(int statled[5])
{
for(int i=0;i<6;i++)
{
digitalWrite(pinleds[i],statled[i]);
}
}
После загрузки наблюдаем работу наших двух светофоров (см. рисунок 3). Изменяя значения констант TIME_GREEN, TIME_RED , TIME_YELLOW мы изменяем время «горения» каждого светодиода, константой TIME_BLINK мы регулируем период мигания желтых светодиода.

Рисунок 3. Работа двух светофоров Arduino на макетной плате




Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.