Главная » 2017 » Сентябрь » 11 » Ардуино пишет письма. Разбор Альфы ч.1. Функции.
06:39
Ардуино пишет письма. Разбор Альфы ч.1. Функции.

Предисловие.

"Разбор Альфы"- статьи из учебного курса робототехнического клуба. В них, имеющий базовые знания в программировании не найдет для себя ни чего нового. Новичок напротив, может найти для себя много интересного. Как конкретно в написании кода, так и в общей логике предмета.

подготовлено для РТК "Техник"

 

 

Часть первая. Функции.    

Перед вами первая часть описания исходника альфа версии. У разрабатываемого нами приложения пока нет ни какого названия. Поэтому просто - приложение.

В этом описании мы не будем разбирать код построчно от начала - до конца. В место этого мы рассмотрим логику выполнения приложения и некоторые приемы с этим связанные.    
Не смотря на то что программный код выполняется (принято считать) по порядку сверху-вниз. Программы редко пишутся также. Да и выполнение программы таким образом, можно считать чисто условным. На самом деле, очень часто, по порядку выполняются только операторы отдельных блоков. А сами блоки мало того что могут выполнятся не по порядку, а вообще находиться в разных файлах. Такие блоки называются функциями (в некоторых языках программирования могут называться подпрограммами).
В разборе кода самое главное понять логику выполнения программы, особенно если писали ее не вы. Обычно назначение функций описывают в комментариях, чтобы всем было понятно и самим не забыть. В процессе программирования мы часто используем функции. Например когда мы создаем подключение по последовательному порту, мы пишем всего одну строчку:  
Myport = new Serial ( this, [имя порта], [скорость в бодах]);
А программа сама вызывает подключенную библиотеку и совершает с ней необходимые действия. При этом основная часть кода, используемая при создании порта, скрыта от нас. И находится в подключенной библиотеке. 
Сегодня мы рассмотрим, так называемые пользовательские функции. То есть функции которые мы создаем сами, для удобства, экономии времени и прочего. Мы рассмотрим две основные возможности функции - это исполняться когда нам нужно, и принимать переданные ей значения.
Пользовательские функции не входят в основной цикл программы. Они расположены вне функций setup и draw.



Пример общего вида скетча.

void setup() {
  // Функция setup
}

void draw() {
  // Функция draw
 function2(); // Вызов функции 2
 // Программный код
 function1(); // Вызов функции 1
}

void function1() {
  // Пользовательская функция 1
}

void function2() {
  // Пользовательская функция 2
}


В представленном общем виде скетча мы видим, что после функций setup() и draw(), следуют две пользовательские функции, function1() и function2(), выделенные оранжевым цветом. Не смотря на их последовательное расположение в скетче, при гипотетическом (при предполагаемом) запуске кода выполнится сначала function2(), а затем function1(). Потому что пользовательские функции выполняются только после их вызова. В данном случае вызов пользовательских функций осуществляется из функции draw(). Сначала function2(), а потом finction1()

Рассмотрим функцию SystemTime().

Эта функция исправляет текущую время и дату до привычного нам вида. Вот код функции:


void SystemTime() {//Для исправления времени и даты +0.
  if (second() < 10) {// Если секунды меньше 10, то ......
    sec = "0"+second(); // Добавляем ноль перед значением секунды. Если секунды
    // равны 5, тогда переменная sec = 05
  } else {// Иначе. 
    sec = ""+second();//К секундам прибавляем НИЧЕГО.
  }
  // Добавляем ноль к минутам
  if (minute() < 10) {// Также поступаем и с минутами.
    min = "0"+minute();
  } else {
    min = ""+minute();
  }
  // Добавляем ноль к часам
  if (hour() < 10) {// И с часами.
    hour = "0"+hour();
  } else {
    hour = ""+hour();
  }
  // Добавляем ноль ко дню
  if (day() < 10) {// И с днями.
    day = "0"+day();
  } else {
    day = ""+day();
  }
  // Добавляем ноль к месяцу
  if (month() < 10) {// И с месяцем.
    mon = "0"+month();
  } else {
    mon = ""+month();
  }
  textSize(12);//Размер шрифта
  text (day+". "+mon+". "+year(), 220, 65);// Печатаем исправленную дату.
  text (hour +" : "+ min +" : "+ sec, 220, 35);// Печатаем исправленное время.
}


Second(), minute(), hour(), day(), month(), year() - возвращают значения текущего времени (секунды, минуты, часы) и текущую дату (день, месяц, год). Возвращают, значит являются этим. Например int min = minute() - означает, что переменная min равна числу минут текущего времени. Если текущее время например 12:14, то min = 14

Почему нам понадобилось исправлять текущее время? Дело в том что second(), minute(), и т.д. возвращают значения без ноля. Имеется в виду ноль который стоит перед числом секунд, минут, часов и т.д., если их значения меньше десяти.

Пример 1 - Время неисправленное  9:3:8

Пример 2 - Время исправленное 09:03:08

Как видно из примеров выше, исправленное время привычнее для восприятия. Хотя некоторым может быть все равно. Но мы не некоторые, поэтому исправим.

Мы используем функцию SystemTime() в главном (основном) цикле программы - в функции draw(). Мы вызываем ее в конце функции.

И наша программа выполняет функцию SystemTime() как часть кода в функции draw. Хотя код самой функции SystemTime() написан в конце скетча. Оператор вызова функции - это своего рода ссылка на блок кода, который нужно выполнить. И который называется:

void SystemTime() {//Исправление текущего времени +0.
// код программы
}

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

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

Из скриншота видно что у нас три таких индикатора. Они одинаковые, отличаются только координатой по оси Y. Код рисующий  индикацию включенной опции небольшой и состоит из семи строк.

  noFill();// Рисовать без заливки.
  stroke(100);//Цвет абриса.
  strokeWeight(3);//Толщина абриса.
  rect(Xcheck, Ycheck, 20, 20, 2, 2, 2, 2);// Рисуем прямоугольник в 
  // координатах Xcheck, Ycheck, ширина 20, высота 20, и скругление всех
  // углов (фаска) 2.
  stroke(255);// Цвет абриса.
  line(Xcheck+5, Ycheck+5, Xcheck+10, Ycheck+15);// Рисуем линии в
  line(Xcheck+10, Ycheck+15, Xcheck+20, Ycheck-5);// виде галочки.

Учитывая что у нас подобных опций несколько ,пока три, то и код рисования увеличится в три раза. А если опций будет десять, или двадцать. Для того чтобы не плодить одинаковые куски кода и ускорить работу над приложением, мы создадим функцию. И при вызове функции будем передавать ей координаты, в которых должен быть нарисован индикатор. Ниже приведен листинг (код) функции, которая "ожидает" принятия координаты по X (int Xcheck) и координаты по Y (int Ycheck).


void CheckOn (int Xcheck, int Ycheck) {// Функция принимает переданные ей при вызове
  //координаты и присваивает их значения переменным Xcheck и Ycheck.
  noFill();// Рисовать без заливки.
  stroke(100);//Цвет абриса.
  strokeWeight(3);//Толщина абриса.
  rect(Xcheck, Ycheck, 20, 20, 2, 2, 2, 2);// Рисуем прямоугольник в 
  // координатах Xcheck, Ycheck, ширина 20, высота 20, и скругление всех
  // углов (фаска) 2.
  stroke(255);// Цвет абриса.
  line(Xcheck+5, Ycheck+5, Xcheck+10, Ycheck+15);// Рисуем линии в
  line(Xcheck+10, Ycheck+15, Xcheck+20, Ycheck-5);// виде галочки.
}
Вызывая функцию мы передаем ей значения по X и Y.
CheckOn(20, 110);

В скобках мы указываем параметры которые следует передать. В конкретном примере это 20 и 110. Функция их принимает и присваивает эти значения переменным Xcheck и Ycheck соответственно.

Обратите внимание что мы передаем не координаты, а значения (числа). А числа уже используем в роли координат через присвоение переменным. Иными словами - передать можно что угодно и использовать как угодно.

Таким образом используя один и тот же код мы можем рисовать индикаторы в разных местах. И сколько угодно раз. Не увеличивая объем кода. Конечно код должен быть написан с учетом его специфики. А именно, если мы передаем координаты для рисования нескольких объектов, то координаты рисуемых объектов должны быть относительными и привязанными к передаваемым значениям. Он об этом в следующей части разбора.

Ссылка на начало истории "Ардуино пишет письма"  

Категория: ЖЕЛЕЗО/ПРОГРАММИРОВАНИЕ. | Просмотров: 600 | Добавил: prototypestudio | Теги: Processing, программирование ардуино, исходник, программирование, Function, функции, Ардуино пишет письма
Всего комментариев: 0
Добавить комментарий