[sape_tizer]
Ср. Май 31st, 2023

Что и как строить на земельном участке или обо всем понемногу

Все о инструментах, строительстве, работах, АРДУИНО, электрика, электроника и многое другое

Урок 5. Функции

Этот урок будет посвящен одной из интереснейшей теме программирования- функциям. Что это такое? Это небольшая подпрограмма, находящаяся в теле основной программы, которую можно использовать много раз в течении одного цикла программы. С чем это можно сравнить? Приведу пример из жизни человека: например  у нас есть функция дыхания. Мы даже не задумываемся- дышим и все с такой частотой с которой нужно организму, т.е. дыханием мы потребляем необходимое количество кислорода в воздухе. Мы можем дышать ровно и медленно когда спим, резко и часто когда заняты работой или спортом и т.д. Но функция дыхания у нас одна- мы просто дышим. Организм сам вызывает эту функцию когда ему надо. Так же и в программировании- мы можем определить функцию и вызывать ее по мере надобности. Например используем программу из урока 2:

/* Фоторезистор и светодиод

www.samosdel.ru
14.05.2015
*/

void setup() {

// назначаем выводы, 10- выход
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop() {

//вводим условие на получение данных
if (analogRead(0)==0)

{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
digitalWrite(13, LOW);
analogWrite(10, analogRead(0)/4);
Serial.println(analogRead(0));
delay(100);
}

Допишем после всей программы такие строки:

void blink(){

digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second

а в теле программы удалим такие же строки и добавим вызов функции:

blink();

Программа примет следующий вид:

/* Фоторезистор и светодиод
14.05.2015
*/

void setup() {
// назначаем выводы, 10- выход
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop() {
//вводим условие на получение данных
if (analogRead(0)==0){

blink();                      //вызываем функцию  blink()

}
digitalWrite(13, LOW);
analogWrite(10, analogRead(0)/4);
Serial.println(analogRead(0));
delay(100);

}

void blink()                     //функция blink

{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second

}

Теперь при обрыве резистора под фотодиодом будет так же выдаваться сигнализация об аварийном состоянии. Вы сразу спросите- как я пойму что именно испортилось- фоторезистор или подтягивающий резистор? Хороший вопрос. Но на это есть еще более лучший ответ. Мы можем передавать в функцию значения и она будет работать по этим значениям. Хочу сразу заметить что функции с оператором void не возвращают в программу никаких значений, передавать в них можно но что то получить- нет, поэтому их надо использовать только в каких то глобальных случаях. В нашем примере сделаем следующее: Вместо void blink()  напишем int blink() — от этого совершенно ничего не изменится и программа так же будет работать. А вот теперь передадим нужные данные. Для этого допишем в int  blink()  —int blink(int x), заменим delay (1000); на delay (x); в обоих случаях. А в функции вызова целые значения, например blink (500); на обрыв фоторезистора и blink (1000); на обрыв подтягивающего резистора. Таким образом получим такую программу:

/* Фоторезистор и светодиод
14.05.2015
*/

void setup() {
// назначаем выводы, 10- выход
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop() {
//вводим условие на получение данных
if (analogRead(0)==0){

blink(500);                      //вызываем функцию  blink() при обрыве фоторезистора

}

if (analogRead(0)>=1020){

blink(1000);                      //вызываем функцию  blink() при обрыве подтягивающего резистора

}

digitalWrite(13, LOW);
analogWrite(10, analogRead(0)/4);
Serial.println(analogRead(0));
delay(100);

}

int blink(int x)                     //функция blink

{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(x); // wait 
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(x); // wait 

}

Теперь мы получаем разные сигналы при разных неисправностях! При обрыве фоторезистора светодиод будет мигать 2 раза в секунду, при обрыве подтягивающего резистора- 1 раз в секунду. Как мы это получили?  При проверке уровня сигнала (если на входе 0) вызываем функцию blink со значением 500. Сама функция подставляет переданное значение в те места где мы ее прописали. Кроме того мы можем менять не только частоту  мигания но и длительность свечения и длительность паузы. Попробуйте это сделать сами. Даю подсказку: в функции blink допишите int blink(int x, int y).  Остальное попробуйте сами додумать. Если что то кому то непонятно- пишите в комментариях- разберем подробнее.

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

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

Например: x=blink(50) где х- объявленная переменная в секции void setup(), blink(50)— функция с параметром 50. Для присваивания значения функции используется оператор return.

Например функция blink может выглядеть следующим образом:

int blink(int x)                     //функция blink

{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(x); // wait 
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(x); // wait 
return 100*x;
}

Обратите внимание на тип функции int blink(int x)— в данном примере тип integer, значит и возвращаемые значения функции должны быть того же типа, т.е. integer. Данная функция возвращает значение 100*x (при этом следует помнить о пределах значений переменных и, если значения не вписываются, применить другой тип функции).

Следующий урок >>

Добавить комментарий