Теоретичні відомості

Arduino IDE — це інтегроване середовище розробки, призначене для створення, редагування, компіляції та завантаження програм у мікроконтролерні плати сімейства Arduino та сумісні з ними.

Середовище Arduino IDE

Середовище підтримує наступні функції:

  • написання коду мовою, заснованою на C/C++;
  • компіляція коду та перевірка на помилки;
  • завантаження програми (скетчу) у мікроконтролер через USB;
  • моніторинг даних через Serial Monitor;
  • керування підключеними платами та бібліотеками.

Кожна програма (скетч) має стандартну структуру з двох основних функцій:

    
        void setup() {
          // Код ініціалізації — виконується один раз при запуску
        }
        
        void loop() {
          // Основний код — виконується циклічно
        }
    

Функція setup() — використовується для налаштування параметрів мікроконтролера (наприклад, налаштування виводів як виходи або входи).

Функція loop() — виконується безперервно, поки на мікроконтролер подається живлення.

Типи даних

Мова програмування Arduino базується на C/C++, тому більшість типів даних є спільними. Тип даних визначає, які значення може зберігати змінна і скільки пам’яті вона займає в мікроконтролері:

  • bool – логічний тип, який використовується для зберігання двох станів: true або false;
  • byte – беззнаковий 8-бітний тип (значення від 0 до 255), часто використовується для керування ШІМ або портами;
  • int – ціле число від -32768 до 32767;
  • unsigned int – ціле число без знаку від 0 до 65535;
  • long – використовується для великих цілих чисел від -2147483648 до 2147483647;
  • unsigned long – великі цілі числа без знаку (від 0 до 4294967295). Часто використовується для вимірювання часу;
  • float – числа з плаваючою точкою (±3.4028235E+38);
  • double – числа з плаваючою точкою. На більшості класичних Arduino-плат (Uno, Nano, Mega) тип double є повною копією типу float. Різниця помітна лише на 32-бітних платформах – точність до 15 десяткових знаків після коми;
  • char – зберігає один символ або байт даних;
  • String – текстовий рядок (об’єктний тип).

Для економії пам’яті на мікроконтролерах із невеликим обʼємом ОЗП (наприклад, Arduino Uno — 2 КБ) бажано використовувати типи з мінімальним розміром. При роботі з таймерами або функцією millis() використовують тип unsigned long. Для текстових даних у простих програмах краще використовувати масив символів char[], а не String, оскільки об’єкти типу String займають більше пам’яті.

Функція pinMode

pinMode в Arduino допомагає встановити режим роботи піна для виконання операцій зчитування або запису. Як правило, ця функція використовується всередині методу setup() і виконується один раз при запуску програми. Неправильне встановлення режиму входів і виходів Arduino може позначитись на працездатності проекту та плати. Синтаксис функції:

pinMode(pin, type)

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

Параметр type вказується тип режиму роботи піна: INPUT, OUTPUT, INPUT_PULLUP.

Для встановлення режиму роботи Arduino в основному використовується два варіанти параметрів: INPUT та OUTPUT. Але іноді при роботі з датчиками потрібно виставити пін в режим з неявно підключеним внутрішнім резистором, тому використовується ще одна константа, яка визначає тип піна INPUT_PULLUP.

Режим INPUT визначає стан піна для роботи з зовнішніми джерелами сигналів (як правило, це різні варіанти датчиків, від яких надходять покази).

В режимі OUTPUT Arduino підтримує пін в стані, при якому на зовнішній пристрій видається максимально можливий струм (плата стає джерелом струму). В цьому режимі зазвичай працюють піни Arduino з підключеними світлодіодами, малопотужними сервоприводами, реле, драйверами двигунів та іншими зовнішніми пристроями.

За замовчуванням, всі піни Arduino встановлені в режим INPUT, тому вказувати це явно не потрібно.

Функція digitalWrite

Функція digitalWrite() – одна з найпопулярніших функцій Arduino. Вона зустрічається практично в будь-якому проекті, де потрібно подати сигнали на підключені пристрої.

Функція дозволяє керувати підключеним обладнанням шляхом подачі або зняття робочої напруги (в більшості випадків – 5В) на піни. Подаючи напругу на підключені пристрої, ми змушуємо їх щось робити: наприклад, вмикати світло, видавати звуки, вмикати двигун. Крім того, за допомогою digitalWrite можна подавати імпульси і передавати інформацію закодованими сигналами і повідомленнями.

Дана функція може сформувати тільки цифровий сигнал в двійковому коді (1 – висока напруга, 0 – низька напруга). На відміну від аналогового сигналу, не можна точно виставити на виході, наприклад, 4,15 вольт. Можливі тільки два значення напруги: мінімальне і максимальне робоче (наприклад, 0 В і 5 В відповідно).

Незважаючи на свою назву, функція може керувати також і аналоговими пінами, виставляючи в них на виході 0 або 5 вольт.

Синтаксис функції:

digitalWrite(pin, value)

pin – будь-який з пінів підключеної плати Arduino.

value – 1 або 0 (краще використовувати константи HIGH і LOW відповідно).

Функція delay

Функція delay являється найпростішою командою і її найчастіше використовують новачки. По суті вона робить затримку, яка призупиняє роботу програми, на вказане в дужках число мілісекунд. Максимальне значення може бути рівне 4294967295 мс, що приблизно дорівнює 50 діб.

Функція digitalRead()

Функція призначена для зчитування значення з заданого входу – HIGH або LOW. Синтаксис функції:

digitalRead(pin)

де pin – номер входу/виходу, з якого буде зчитано сигнал.

Аналогові входи також можуть бути використані як цифрові входи. Звернення до них відбувається за номерами від 14 (для аналогового входу 0) до 19 (для аналогового входу 5).

Директива #define

#define це зручна директива, який дозволяє задати ім'я константі перед тим як програма буде скомпільована. Визначені цією директивою константи не займають програмної пам'яті (на відміну від використання змінних), оскільки компілятор замінює всі звернення до них їх значеннями на етапі компіляції, відповідно вони служать виключно для зручності програміста. Синтаксис:

#define constantName value

Компілятор замінить будь-яке згадування constantName в тексті програми на значення value.

Функція analogRead()

Функція зчитує величину напруги з зазначеного аналогового входу. У складі Arduino є 6-канальний (8-канальний – в Mini та Nano, 16 – в Mega) 10-бітний аналогово-цифровий перетворювач, який перетворює вхідну напругу з діапазону від 0 до 5В в цілочисельні значення в межах від 0 до 1023 відповідно. Синтаксис функції:

analogRead(pin)

де pin – номер аналогового входу, з якого буде зчитуватися напруга.

Функція analogWrite()

Функція формує задану аналогову напругу на виході у вигляді ШІМ-сигналу. Може використовуватися для зміни яскравості світлодіода або керування швидкістю обертання двигуна. Після виклику analogWrite(), на виході буде безперервно генеруватися ШІМ-сигнал з заданим коефіцієнтом заповнення до наступного виклику функції analogWrite() (або до моменту виклику digitalRead() або digitalWrite()) на цьому ж виході.

На більшості плат Arduino (на базі мікроконтролерів ATmega168 або ATmega328) функція analogWrite() працює з виходами 3, 5, 6, 9, 10 і 11. На Arduino Mega функція працює з виходами з 2 по 13.

При роботі з analogWrite() попередній виклик функції pinMode() для перемикання пінів в режим «вихід» не потрібний.

Функція analogWrite() не має нічого спільного з аналоговими входами і функцією analogRead(). Синтаксис функції:

analogWrite(pin, value)

pin – вихід, на якому буде формуватися напругу.

value – коефіцієнт заповнення (лежить в межах від 0 до 255).

Клас Serial

Клас Serial використовується для зв'язку плати Arduino з комп'ютером або іншими пристроями. Всі плати Arduino мають, принаймні, один послідовний інтерфейс (також відомий як UART або USART): Serial. Він прив’язаний до цифрових виходів 0 (RX) та 1 (TX), а також використовується для зв'язку з комп'ютером через USB. Таким чином, під час використання послідовного порту, піни 0 і 1 не можуть використовуватися в якості цифрових входів або виходів.

Для зв’язку з Arduino можна використовувати спеціальну програму моніторингу послідовного порту, вбудовану в програмне забезпечення Arduino. Для виклику програми потрібно натиснути відповідну кнопку на панелі інструментів та встановити ту ж швидкість передачі, що вказується в програмі при виклику методу begin().

Вікно моніторингу послідовного порту Arduino IDE

Arduino Mega має три додаткових послідовних порти: Serial1 з виходами 19 (RX) та 18 (TX), Serial2 з виходами 17 (RX) та 16 (TX), Serial3 з виходами 15 (RX) та 14 (TX).

Функції Serial.begin() та Serial.end()

Функція Serial.begin() ініціює послідовне з’єднання і задає швидкість передачі даних в біт/c (бод). Для обміну даними з комп'ютером використовуються наступні значення: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 або 115200. При з'єднання через порти входу/виходу 0 і 1 можуть бути використані і інші значення швидкості, необхідні пристрою з яким буде здійснюватися обмін даними. Синтаксис функції:

Serial.begin(speed)

де speed – швидкість в біт/c (бод).

Функція Serial.end() закриває послідовне з'єднання, порти RX і TX звільняються і можуть бути використані для введення/виведення.

Функція Serial.available()

Функція отримує кількість байт (символів) доступних для читання з послідовного інтерфейсу зв’язку. Це ті байти, які вже надійшли і записані в буфер послідовного порту. Буфер може зберігати до 64 байт.

Функція не приймає жодних параметрів, однак повертає кількість байт, доступних до читання.

Функція Serial.read()

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

Функції Serial.print(), Serial.println(), Serial.write()

Функція передає дані через послідовний порт як ASCII текст. Ця функція може приймати різні типи даних. Так цілі числа виводяться відповідними їм символами ASCII. Дійсні числа виводяться за допомогою двох ASCII символів, для цілої і дробової частини. Байти передаються як символ з відповідним номером. Симоволи і рядки відсилаються як є. Приклад:

    
        Serial.print(78) передається як "78"
        Serial.print(1.23456) передається як "1.23"
        Serial.print(byte(78)) передається як "N" (в таблиці ASCII "N" під 78 номером)
        Serial.print('N') передається як "N"
        Serial.print("Hello world.") Передається як "Hello world."
    

За допомогою другого опціонально параметра можна задати базис (систему числення) для чисел. Допустимі значення BIN (двійковий), OCT (вісімковий), DEC (десятковий), HEX (шістнадцятковий). Для дійсних (дрібних) чисел другий параметр задає кількість знаків після коми. Приклад:

    
        Serial.print(78, BIN) виводить "1001110"
        Serial.print(78, OCT) виводить "116"
        Serial.print(78, DEC) виводить "78"
        Serial.print(78, HEX) виводить "4E"
        Serial.print(1.23456, 0) виводить "1"
        Serial.print(1.23456, 2) виводить "1.23"
        Serial.print(1.23456, 4) виводить "1.2346"
    

Функція Serial.println() повністю аналогічна функції Serial.print(), але передає дані через послідовне з'єднання з наступним за ним символом розриву рядків (ASCII символ 13 або ‘\r’) і символом нового рядка (ASCII 10 або ‘\n’).

Функція Serial.write() передає дані як бінарний код через послідовне з'єднання. Дані відправляються як один або серія байтів. Для того, щоб передати дані як символи слід використовувати функцію print().

Розглянемо приклад використання послідовного інтерфейсу:

    
        void setup() {
            Serial.begin(9600); //відкриваємо з'єднання з швидкістю 9600 біт/с
        }
 
        void loop() {
            if (Serial.available() > 0) { //перевіряємо об'єм буферу вхідних даних
                int inByte = Serial.read(); //зчитуємо черговий байт даних
                Serial.println(inByte); //передаємо отримане раніше значення
            }
        }
    

Директива #include

#include використовується для підключення сторонніх бібліотек в код програми. Це дає доступ до великої кількості стандартних бібліотек С (бібліотекою називають групи попередньо написаних функцій), і бібліотек написаних спеціально для Arduino.

Варто звернути увагу на те, що #include, так само як і #define, не вимагає крапки з комою в кінці рядка, якщо ж її додати компілятор видасть критичну помилку.

Хід роботи

  1. Ознайомитися з теоретичними відомостями.
  2. В середовищі Tinkercad написати код для прототипу, розробленого в попередній практичній роботі.
Стогодюк Денис Виводити на дисплей значення температури кожні 2 хвилини.
Вірний ВладВиводити на дисплей значення температури кожні 5 хвилин. При температурі вище 20 градусів увімкнути світлодіод.
Скупейко РоманВиводити на дисплей значення температури кожні 5 хвилин
Сумарна Михайло Виводити на дисплей значення температури кожні 2 хвилини. Засвітити світлодіод, коли температура опуститься нижче 10 градусів.
Савонюк ПавлоВиводити на дисплей значення відстані кожні 10 секунд.
Лебезун Максим Виводити на дисплей значення відстані кожні 20 секунд. Якщо буде зафіксовано обʼєкт на відстані менше 15 см – увімкнути світлодіод.
Дацків МаксимВиводити на дисплей значення відстані кожні 20 секунд.
Карпюк ЛізаВиводити на дисплей значення відстані кожні 10 секунд. Якщо буде зафіксовано обʼєкт на відстані менше 25 см – увімкнути світлодіод.
Новак АнтгонВиводити на дисплей повідомлення про спрацювання датчика. Період опитування – 10 секунд.
Фещак ДмитроВиводити на дисплей повідомлення про спрацювання датчика. При фіксації руху – увімкнути світлодіод. Період опитування – 30 секунд.
Богульський Максим Виводити на дисплей повідомлення про спрацювання датчика. Період опитування – 20 секунд.
Новосад БогданВиводити на дисплей повідомлення про спрацювання датчика. При фіксації руху – увімкнути світлодіод. Період опитування – 15 секунд.
Сінкевич ДанилоВиводити на дисплей значення освітленості з періодичністю в 2 хвилини.
Поручнік АнжелікаВиводити на дисплей значення освітленості з періодичністю в 1 хвилину. При низькому рівні освітлення (близькому до 0) увімкнути світлодіод.
Панасюк ДенисВиводити на дисплей значення освітленості з періодичністю в 30 секунд.
Жабчик МаксимВиводити на дисплей значення освітленості з періодичністю в 1 хвилину. При високому рівні освітлення увімкнути світлодіод.
Мачічка МихайлоЗабезпечити обертання валу сервопривода на кут від 0 до 90 градусів, обертаючи ручку потенціометра. Значення кута вивести на дисплей.
Шелепіна ОлександрЗабезпечити обертання валу сервопривода на кут від 0 до 90 градусів, натискаючи на одну з кнопок (перша - зменшення на 10 градусів, друга - збільшення). Значення кута вивести на дисплей.
Порва ДімаЗабезпечити обертання валу сервопривода на кут від 0 до 180 градусів, обертаючи ручку потенціометра. Значення кута вивести на дисплей.
Ільїн ОлександрВиводити на дисплей значення вологості грунту з періодичністю в 30 хвилин.
Пархомчук ДмитроВиводити на дисплей значення вологості грунту з періодичністю в 30 хвилин. Увімкнути світлодіод, коли рівень вологості буде дуже низьким.
Сорока ПавлоВиводити на дисплей значення вологості грунту з періодичністю в 10 хвилин.
Попик Тимофій Виводити на дисплей значення вологості грунту з періодичністю в 15 хвилин. Увімкнути світлодіод, коли рівень вологості буде дуже низьким.
Мирончук Дарія Засвітити стрічку довільним кольором (всі світлодіоди). Натискання на першу кнопку має змінювати колір стрічки на наступний (наперед задані кольори). Натискання на другу – на попеердній. На дисплей вивести назву кольору.
Іван ОдемчукЗасвітити стрічку білим кольором (всі світлодіоди). Натискання на кнопку має змінювати колір першого світлодіода на інший (наперед задані кольори). Наступне натискання – змінювати колір другого і т.д. На дисплей вивести код кольору.
Бєлова ІринаЗасвітити стрічку білим (крім першого, перший – довільним кольором). Натискання на першу кнопку передає цей колір на наступний світлодіод, а поточний робить білим. Друга кнопку – в зворотньому напрямку. На дисплей вивести номер кольорового світлодіода.
Руднік РоманЗабезпечити вмикання лампи розжарування, натисканням на кнопку. Повторне натискання має вимикати лампу. На дисплей вивести поточний стан лампи (увімкнено або вимкнено) та скільки разів вона вмикалася.