Уроки Ардуино: Два светофора для перекрестка дороги на базе 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 на макетной плате
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.