Віримо в перемогу ЗСУ!
Працюємо з 09:00 до 19:00 Пн-Пт

Ця стаття із серії уроки Arduino. Тема цього уроку: Arduino функції і як з ними боротися.

Ми дізнаємося для чого вони потрібні і навчимося створювати свої функції і використовувати їх в скетчах.

Заходьте на наш канал Youtube

Функція - це фрагмент програмного коду, до якого можна звертатися з різних місць програми. Її можна представити наприклад як печатку, штамп - один раз виготовляємо і потім штампуємо в різних документах, причому по ходу можна міняти аргументи (в даному випадку дату), і колір чорнила, які ми передаємо в тіло печатки.


Ще функцію можна представити як форму для випічки - один раз виготовляємо і потім в ній випікаємо різні кекси з різного тіста і з різними начинками, але з однаковою формою. Так ось в залежності від вхідних даних, так званих аргументів, буде залежати вихідний результат - готовий кекс - так звані зворотні дані.


Основне покликання функцій в програмуванні - це оптимізація багаторазового виконання однотипного шматка програмного коду, що дозволяє уникнути повторюваних сегментів коду в програмі і марного використання наявної пам'яті. При цьому кожен раз звертаючись до функції, ми заново використовуємо код, який написано в одному екземплярі. І ще важливо те, що результат виконання функції буде змінюватися зі зміною вхідних аргументів переданих у функцію. При цьому так само стає зручно вносити правки в цей повторюваний код, адже він лежить в одному місці - в тілі функції.


Але прикол в тому, що в Arduino IDE програмісти функції частіше використовують не за канонічним призначенням. Так як функції легко дозволяють структурувати програму на окремі сегменти коду зі своїми індивідуальними завданнями, їх використовують для дроблення великих складних скетчів на структурні частини. Це дозволяє розробляти програми легші для читання та розуміння. Так само окремі функції легко переносити в нові скетчі для інших проектів.


Загальний опис функції

Опис функції у скетчі в загальному вигляді має наступну структуру. У ній тип зворотніх даних, ім'я функції, вхідні аргументи, тіло функції укладене в фігурні лапки. У тілі функції знайомі операнди, а так же необов'язковий операнд return, який завершує виконання інструкцій функції і передає дані, заданого типу в місце виклику функції. Для нас, новачків, функції відрізняються типом повернених даних та кількістю вхідних аргументів.


Різновиди функцій

Я найчастіше користуюся функціями, які нічого не приймають як аргументи і нічого не повертають. Тип void в типі зворотніх даних функції повідомляє компілятору, що не потрібно лаятися, якщо функція нічого не поверне. У такій функції можна наприклад управляти станами входів-виходів, друкувати що-небудь в монітор порту, або змінювати зовнішні змінні. У тілі функції можна проводити маніпуляції над глобальними змінними. Змінювати їх значення, використовувати їх в операндах. Так само можна створювати внутрішні змінні, які видно тільки в цій функції і при кожному її виклику створюються заново. Тобто не зберігають значення з минулого виклику. Але з позначенням static внутрішні змінні можуть зберігати значення з минулого виклику і їх теж дозволено тут юзати. Детальніше про цей нюанс можна дізнатися з уроку Arduino видимість змінних.

void my_function()
{  
  digitalWrite(13, LOW);  
  Serial.println(analogRead(A0));  
  a = b + 2;  
  int var1;  
  static int var2;  
  var1 = a * b;  
  var2 = var1 - 3;
}

Функція може приймати аргументи, але нічого не повертати.

void my_function(int var1, byte var2)
{  
  digitalWrite(13, LOW);  
  Serial.println(analogRead(A0));  
  a = var1 * 4;  
  b = var2 - 3;
}

Може також не приймати аргументи, але повертати дані заданого типу.

int my_function()
{  
  digitalWrite(13, LOW);  
  Serial.println(analogRead(A0));  
  int var1 = a + b;  
  return var1;
}

А також приймати аргументи та повертати.

int my_function(int var1)
{  
  digitalWrite(13, LOW);  
  Serial.println(analogRead(A0));  
  return (var1 * 5);
}

Виклик функцій

Звертаються до функцій в тексті скетчу зазвичай такими шляхами:

Якщо функція нічого не повертає то

void loop()
{  
  my_func();
}
void loop()
{  
  my_func(var1, var2);
}

Якщо повертає то

void loop()
{  
  var1 = my_func();
}
void loop()
{  
  var1 = my_func(var2, var3);
}

Або навіть можна використовувати як частину логічної умови

void loop()
{  
  if (my_func())  
    {  }
}
void loop()
{  
  if (my_func(var1)>10)  
    {    }
}

В тілі функції оператор return завершує виконання функції та повертає дані. Його в одній функції можна використовувати не один раз.

int my_func()
{  
  if (var1 > 100)  
  {    
    return 1;  
  }else{    
    return 0;  
  }
}

А також з його допомогою можна просто завершити виконання функції при досягненні потрібної умови.

void my_function()
{  
  // код  
  return;  
  //этот код  
  //не будет выполнен
}

Що стосується красивого структурування скетчу для arduino подібного контролера, то функції дозволяють привести текст функції main і головного циклу програми до мінімалістичного вигляду. При цьому всередині самих функцій може міститися великий скетч зі складними обчисленнями і зверненням до різних комунікацій. Саме тіло кожної функції може зберігатися в окремому файлі, редагуватися в окремій вкладці програми Arduino IDE.

void setup()
{  
  my_func1();
}

void loop()
{  
  my_func2();  
  my_func3();  
  my_func4();
}

Рекомендації для кращіх скетчів

Я вам раджу структурувати по можливості свій скетч на такі кластери як наприклад: конфігурація входів-виходів, обробка дискретних входів, обробка аналогових входів, обробка алгоритму завдання проекту, мережеві комунікації із зовнішніми пристроями, обробка виходів. У наступному відео з серії Arduino уроки розглянемо приклад, як можна розкласти ці завдання за окремими функціями і оформити їх окремими файлами для зручності розробки і налагодження.

void setup()
{  
  config_func();
}

void loop()
{  
  din_func();  
  ain_func();  
  run_func();  
  comm_func();  
  outs_func();
}

Висновки

А поки нам необхідно запам'ятати, що функція визначається в програмі один раз, а викликатися може безліч разів. При кожному виклику функції в неї можна передати нові значення аргументів. Функція так само може повертати нам дані зумовленого типу, а може і нічого не повертати - тоді ми її визначаємо як тип void. Дякуємо за підписку, лайк і коментар і до нових зустрічей.

void loop()
{  
  var1 = my_function(4, 6) + my_function(1, 7);  
  var2 = my_function(-2, 0) - 4;  
  Serial.println(my_function(0, -5)); 
}

int my_function(int a, int b)
{  
  digitalWrite(13, LOW);  
  Serial.println(analogRead(A0));  
  int var1 = a + b;  
  return var1;
}

24.01.2021

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Стойка роликова для вісі Х 2шт. з кріпленням

Стойка роликова для вісі Х 2шт. з кріпленням

Монтажна панель з МДФ для організації вісі Х автоматичного лазерного гравера.Отвори під кроковий дви..

160.94грн.

Гвинт М2,5х14мм нержавійка

Гвинт М2,5х14мм нержавійка

Гвинт з нержавійки з різьбою М2,5 для кріплення елементів любительських проектівДовжина різьби 14 мм..

1.06грн.

Стабілізатор напруги 5В 1,5А L7805CV

Стабілізатор напруги 5В 1,5А L7805CV

Стабілізатор напруги у вигляді мікросхеми з трьома ногамиВикористовується для стабілізації нестабілі..

12.03грн.

Радіатор для транзистора 34х25х12мм

Радіатор для транзистора 34х25х12мм

Радіатор алюмінієвий для пасивного охолодження різноманітних напівпровідникових силових компонентів:..

28.58грн.

Універсальна плата під мікросхеми SOP16 або SSOP16

Універсальна плата під мікросхеми SOP16 або SSOP16

Універсальна монтажна плата, дозволяє проводити монтаж різноманітних мікросхем з поверхневим монтаже..

13.22грн.