Найти тему
ТехноБобёр

Создание функций. Управление «светофором» с помощью функций.

Наверняка вы уже заметили, что с каждым уроком устройства и программы становятся все сложнее и богаче функционально, количество строк в скетчах все больше. Так вот, для тех случаев, когда скетчи слишком большие в программировании предусмотрен такой инструмент как функция. В общем случае функция - это фрагмент программного кода (например математическая операция) Поэтому можно оформить какие-либо действия в виде функции один раз и далее только вызывать их, когда они нужны. При этом использование функций дает ряд преимуществ. Они позволяют организовать программу, сокращают текст скетчей и делают их компактными, облегчают использование кода в других программах, делая его модульным. Дополнительно еще и экономится память контроллера.

Одновременно важно отметить, что такие функции могут находиться не только в той программе, где они вызываются. Они могут быть размещены в отдельном файле и вызываться оттуда. Такие сборники функций называются библиотеками. Библиотеки могут быть внешними (в Ардуино IDE располагаются в папке libraries) или системными («зашиты» в файлы самой Ардуино IDE). В предыдущих статьях мы часто пользовались такими библиотеками - например в уроке для управления жидкокристаллическим экраном. Это позволило очень легко управлять экраном, а программный код с простым вызовом библиотечных функций очень удобный и короткий. Без использования системных функций (digitalWrite(), pinMode() и т. д.) не обходится не один скетч.

Создание полноценных библиотек - это задача более сложная, чем написание скетчей Ардуино IDE, поскольку в общем случае при их формировании используются команды обращения памяти контроллера и его микроконтроллеру с непростым и менее понятным синтаксисом. Поэтому текущем уроке мы ограничимся созданием функций именно как подпрограмм в той же программе, которой они будут вызываться.

Идея проста. Светофор показывает зеленый сигнал для автомобилей, пока не появится пешеход на регулируемом переходе. Он нажимает кнопку и запускает светофорный цикл, который будет зависеть от времени суток. В светлое время суток, когда обычно автомобилей много, цикл будет запускаться через 10 секунд, чтобы в меньшей степени препятствовать интенсивному потоку машин. В темное же время, когда машин на дороге уже мало, эта пауза будет в 5 раз меньше.

Пошагово алгоритм работы будет таким:

включен зеленый светодиод, пока не будет нажата кнопка; после нажатия кнопки выдерживается пауза в зависимости от уровня

освещенности; после завершения паузы зеленый моргает 3 раза в течение 3-х секунд; далее включается одновременно желтый и зеленый сигналы на 1 секунду; затем включается красный сигнал на 10 секунд, а зеленый и желтый гаснут; в завершение цикла включаются красный и желтый сигналы на 1 секунду; включается зеленый сигнал, который работает, пока снова не будет нажата кнопка.

Соедините светодиоды с контроллером через резисторы с помощью макетной платы и проводов, как это показано на рисунке.

Для схемы потребуется:

1. Контроллер.

2. Макетная плата.

3. Провода.

4. Тактовая кнопка.

5. Резистор 10 к0м - 2шт.

6. Резистор 240 Ом - 3 шт.

7. Фоторезистор.

8. Светодиод красный.

9. Светодиод зеленый.

10. Светодиод желтый.

Схема сборки.
Схема сборки.

Реализуем описанный алгоритм с использованием функций. Текст скетча приведен на следующей картинке.

В основном блоке void loop() скетча используются следующие функции:

morganie(green,0.5,3); - вызов функции, выполняющей трехкратное моргание светодиодом

green с временным шагом 0,5 секунды.

vkl2(green,yellow,1); - функция включает светодиоды green и yellow на 1 секунду и выключает их.

vkl(red,10); - вызов функции, которая включает красный светодиод на 10 секунди выключает.

Также переменной del присваивается значение от выполнения функции pauza (svet, bazvrem); - функция возвращает время необходимой паузы в секундах в зависимости от степени освещения комнаты.

Все эти функции являются пользовательскими и созданы (определены) они в той же программе, в которой выполняется их вызов . Поэтому для того чтобы они выполняли необходимые нам действия, ихнужно создать.

-2
Программа, продолжение 1-вой картинки.
Программа, продолжение 1-вой картинки.

Существуют два основных вида функций с возвращаемыми параметрами и без возвращаемых параметров. Рассмотрим последовательно оба варианта. Начнем с более простой разновидности: с функции без возвращаемого параметра. Такая функция просто выполняет какие то действия на основании тех параметров, которые переданы в нее. То есть в результате выполнения всех команд в теле функции мы не получим ничего, кроме собственно выполнения нения этих моманд. В качестве примера рассмотрим функцию тorganie из написанного скетча, кото рая выполняет моргание светодиодом в светофорном цикле. Для создания функции необходимо записать за пределами функций void() и setup().

В первой строке выполняется определение функции, Слово void означает, что функция не возвращает, void мая, morganie - имя функции, которое используется в i<=raz;i++)( теле программы для ее вызова, в круглых скобках ука- for (inti=0; digitalWrite(colour, LOW), заданы аргументы, которые являются исходными данные delay(time*1000); ми для проведения вычислений внутри самой функции. digitalWrite(colour, LOW). Обратите внимание, что при перечислении аргументов в скобках сразу определяется их тип (аргументы colour и delay(time*1000); raz - целочисленных, time - число с плавающей запятой). Далее в фигурные скобки заключаются выражения, являющиеся «телом» функции.

В нашем случае функция выполняет моргание светодиодом, и в качестве аргументов используется переменная colour, которая определяет номер контакта, к которому подключен светодиод, переменная time, определяющая частоту моргания, и переменная raz, определяющая количество вклю- чений-выключений светодиода. Таким образом, записав эту функцию, мы можем вызывать её в любой момент в нашей програм-

ме. При обращении в программе к функции morganie() происходит выход из основной программы, и выполняется «тело» вызываемой функции. В скобках указываются параметры, которые передаются в выражения, входящие в состав функции.

В нашем скетче при вызове функции morganie(green,0.5,3) передается константа green (она имеет значение 11), число 0,5, определяющее частоту моргания и число 3, которое представляет собой количество морганий. Когда программа переходит к функции morganie(), она присваивает её параметрам, записанным в скобках, значения, которые были переданы из основной программы. Переменной colour присваивается значение green, которое равно 11, переменной time присваивается значение 0,5, а переменной raz - значение 3. Далее выполняются все команды из тела функции уже с конкретными параметрами. Функции vkl1 и vkl2 используются для включения-выключения сигналов «светофора», опреде-

Теперь рассмотрим функции с возвращаемым параметром. Функция с возвращаемым параметром помимо выполнения float pauza (intsvet, int bazvrem) каких-либо вычислительных или логических операций на выходе выдает определенный результат в виде параметра. Синтаксис float vrem; такой функции немного отличается. В нашем скетче использован- if (svet<100) на функция pauza для вычисления задержки перед запуском (vrem = bazvrem/5;) светофорного цикла в зависимости от уровня освещения, Грани- else (vrem = bazvrem;} судебного времени суток (tma) соби- return vrem; рался буерный будильник.

Здесь символы float в первой строке задают тип возвращаемого параметра, в круглых скобках также указываются входные параметры (в данном случае это уровень освещенности svet и базовое время паузы с момента нажатия кнопки до начала светофорного цикла). В фигурных скобках «тело» функции, в котором сравнивается текущая освещенность с условной границей темного времени суток. Если освещенность больше 100 единиц, то пауза перед переключением автомобильного светофора на красный сигнал уменьшается в пять раз. Это значение присваиваем переменной vrem. return vrem; - команда производит возврат значения переменной vrem в основную программу.

Возвращаемые функции вызываются в программе аналогично невозвращаемым, но значение функции, как правило, присваивается какой-либо переменной или используется напрямую. В нашем случае переменной del присвоено значение возвращаемой функции pauza.

del = pauza (svet, bazvrem); - в качестве значений аргументов в функции pauza() передаются количество света, определенное с помощью команды analogRead(foto), и базовое время (имя константы bazvrem), которое составляет 10 секунд. В итоге после вызова функции она будет выполнена, в результате чего будет произведен расчет времени задержки, которое будет возвращено в основную программу и это значение присвоится переменной del.

В качестве небольшого дополнения можно упомянуть еще один частный случай использования функций. Если при создании пользовательских функций нет необходимости передавать в них параметры из основной программы, а требуется просто вызвать функцию и выполнить ряд команд, то в круглых скобках ничего не пишется, они остаются пустыми, но символы скобок должны присутствовать обязательно во избежание возникновения синтаксических ошибок.

Скетч тут: https://disk.yandex.ru/d/11bkrOQfPLV-JQ