Вогні, що біжать на arduino. Повертачі, що біжать на стрічці WS2812 і Arduino

Вогні, що біжать на arduino. Повертачі, що біжать на стрічці WS2812 і Arduino

22.08.2023

Робимо вогні, що біжать, зі світлодіодів на Arduino. У даному випадку використовується Arduino Mega 2560, який потенційно здатний керувати доріжкою, що біжить, з 54-х світлодіодів. Але схема та програма не зміняться, якщо ви використовуватимете інші контролери з платформи Arduino такого типу (UNO, Leonardo...)

Схема підключення світлодіодів до Ардуїно Мега 2560

Так виглядає скетч у вікні стандартної програми для програмування Ардуїно.

Текст програми для реалізації вогнів, що біжать на платформі ардуїно.

int first_out = 11; //перший дискретний вихід

int last_out = 13; //останній дискретний вихід

//блок для ініціалізації входів-виходів та інших вихідних даних

last_out = last_out + 1; //додаємо одиницю для коректного використання у циклах

//Визначення 11-го, 12-го і 13-го дискретних висновків плати Ардуїно як виходи

for (i = first_out; i< last_out; i++) { pinMode(i, OUTPUT); }

for (t = first_out; t< last_out; t++) { //перебираем номера дискретных выходов 11,12,13 поочереди

digitalWrite(t, HIGH); //Запалювання наступного світлодіода

delay(500); //Затримка 500мсек

for (i = first_out; i< last_out; i++) { digitalWrite(i, LOW); }//гасим все светодиоды

Для збільшення кількості керованих світлодіодів у гірлянді, у програмі потрібно буде просто замінити значення змінних first_out та last_out. Перша змінна зберігає початковий дискретний вихід контролера, а друга останній із групи виходів, що йдуть поспіль. Наприклад, якщо ми хочемо підключити 10 світлодіодів у гірлянду, вводимо такі значення: first_out = 4, last_out = 13. І світлодіоди до висновків по порядку з 4-го до 13-го. А перший і другий висновок дискретних входів-виходів краще не чіпати, оскільки їм заважає USB-порт, підключений до комп'ютера.

У цьому уроці ми продовжимо роботу зі світлодіодами, але кількість світлодіодів збільшимо до 5. І зробимо ефект вогню, що біжить. Для управління світлодіодами використовуватимемо маніпуляції з портами Arduino. Ми безпосередньо записуватимемо дані в порти Arduino. Це краще, ніж працювати з конкретними входами/виходами контролера. Це дозволить встановити значення для світлодіодів за допомогою лише однієї операції.

Arduino UNO має 3 порти:
B (цифрові входу/виходу з 8 по 13)
C (аналогові входи)
D (цифрові входи/виходи з 0 по 7)

Кожен порт управляється 3 регістрами. Реєстр DDRвизначає чим буде нога (pin) входом чи виходом. За допомогою регістру PORT можна встановити pin у стан HIGHабо LOW. За допомогою регістра PIN можна вважати стан ніжок Arduino, коли вони працюють на вхід.

Ми будемо використовувати порт B. Спочатку ми повинні встановити всі ніжки порту B як цифрові виходу. У порту B є лише 6 ніжок. Біти регістру для порту DDRB повинні бути встановлені в 1, якщо нога буде використовуватися як вихід (OUTPUT), і в 0, якщо нога буде використовувати як вхід (INPUT). Біти портів нумеруються з 0 до 7, але не завжди містять всі 8 ніг.
Приклад:
DDRB = B00111110; // встановити ніжки порту з 1 по 5 як виходу, а 0 як вхід.

Зверніть увагу, що у мікроконтролерах фірми Microchip все навпаки. 0 біт – нога працює як вихід, а 1 – як вхід.

У нашому проекті вогню, що біжить, ми будемо використовувати 5 виходів:
DDRB = B00011111; // встановити ноги порту з 0 по 4 як виходу

Для запису значень у порт необхідно використовувати регістр PORTB.
Засвітити перший світлодіод можна командою:
PORTB = B00000001;
перший та четвертий:
PORTB = B00001001;

Тепер ви бачите, як легко ми можемо вмикати та вимикати світлодіоди. Тепер розповімо вам про операторів зсуву

Є 2 оператори двійкового зсуву: оператор зсуву вліво<< и оператор сдвига вправо >>. Оператор зсуву вліво<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> Зсув біти вправо.

Приклад:
varA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

Тепер повернемося до нашої програми, яка показана нижче.
Нам потрібно ввести 2 змінні:перша upDown буде містити значення куди рухатися - вгору чи вниз, а друга cylon - які світлодіоди запалювати.

У функції setup()ми визначаємо які ніжки мають працювати як виходу.

У головному циклі програми loop(), світлодіоди по черзі загоряються вгору шляхом збільшення змінної cylon, а коли доходить до найвищого, то змінної upDownприсвоюється 0 і світлодіоди спалахують вниз по черзі.

/* Вогонь, що біжить. 5 світлодіодів */ unsigned char upDown=1; // починаємо з руху нагору unsigned char cylon=0; // визначає черговість LED void setup() ( DDRB = B00011111; // встановлюємо порт B з 0 по 4 як виходу ) void loop() ( if(upDown==1)( // якщо йдемо вгору, то cylon++; if( cylon>=4) upDown=0;// коли досягнутий найбільший номер LED, то в наступному циклі йдемо вниз) else (cylon--; if(cylon==0) upDown=1; // коли досягнуть найменший номер LED, то в наступному циклі йдемо вгору) PORTB = 1<< cylon; //сдвиг delay(200); // пауза 200 мс }

У цьому уроці ми продовжимо роботу зі світлодіодами, але кількість світлодіодів збільшимо до 5. І зробимо ефект вогню, що біжить. Для управління світлодіодами використовуватимемо маніпуляції з портами Arduino. Ми безпосередньо записуватимемо дані в порти Arduino. Це краще, ніж працювати з конкретними входами/виходами контролера. Це дозволить встановити значення для світлодіодів за допомогою лише однієї операції.

Arduino UNO має 3 порти:

  • B (цифрові входу/виходу з 8 по 13)
  • C (аналогові входи)
  • D (цифрові входи/виходи з 0 по 7)

Кожен порт управляється 3 регістрами. Регістр DDR визначає, чим буде нога (pin) входом або виходом. За допомогою регістру PORT можна встановити pin у стан HIGH або LOW. За допомогою регістра PIN можна вважати стан ніжок Arduino, коли вони працюють на вхід.

Ми будемо використовувати порт B. Спочатку ми повинні встановити всі ніжки порту B як цифрові виходу. У порту B є лише 6 ніжок. Біти регістру для порту DDRB повинні бути встановлені в 1, якщо нога буде використовуватися як вихід (OUTPUT), і в 0, якщо нога буде використовувати як вхід (INPUT). Біти портів нумеруються з 0 до 7, але не завжди містять всі 8 ніг.

приклад:

DDRB = B00111110; // встановити ніжки порту з 1 по 5 як виходу, а 0 як вхід.

Зверніть увагу, що у мікроконтролерах фірми Microchip все навпаки. 0 біт – нога працює як вихід, а 1 – як вхід.

У нашому проекті вогню, що біжить, ми будемо використовувати 5 виходів:

DDRB = B00011111; // встановити ноги порту з 0 по 4 як виходу

Для запису значень у порт необхідно використовувати регістр PORTB. Засвітити перший світлодіод можна командою:

PORTB = B00000001;
перший та четвертий:
PORTB = B00001001;

Тепер ви бачите, як легко ми можемо вмикати та вимикати світлодіоди. Тепер розповімо вам про операторів зсуву

Є 2 оператори двійкового зсуву: оператор зсуву вліво<< и оператор сдвига вправо >>. Оператор зсуву вліво<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> Зсув біти вправо.

Приклад:

VarA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

Тепер повернемося до нашої програми, яка показана нижче. Нам потрібно ввести 2 змінні: перша upDownміститиме значення куди рухатися - вгору чи вниз, а друга cylonякі світлодіоди запалювати.

У функції setup()ми визначаємо які ніжки мають працювати як виходу.

У головному циклі програми loop(), світлодіоди по черзі загоряються вгору шляхом збільшення змінної cylon, а коли доходить до найвищого, то змінної upDownприсвоюється 0 і світлодіоди спалахують вниз по черзі.

Ардуїно початківцям

У цьому уроці ми продовжимо роботу зі світлодіодами, але кількість світлодіодів збільшимо до 5. І зробимо ефект вогню, що біжить. Для управління світлодіодами використовуватимемо маніпуляції з портами Arduino. Ми безпосередньо записуватимемо дані в порти Arduino. Це краще, ніж працювати з конкретними входами/виходами контролера. Це дозволить встановити значення для світлодіодів за допомогою лише однієї операції.

Arduino UNO має 3 порти:

  • B (цифрові входу/виходу з 8 по 13)
  • C (аналогові входи)
  • D (цифрові входи/виходи з 0 по 7)

Кожен порт управляється 3 регістрами. Регістр DDR визначає, чим буде нога (pin) входом або виходом. За допомогою регістру PORT можна встановити pin у стан HIGH або LOW. За допомогою регістра PIN можна вважати стан ніжок Arduino, коли вони працюють на вхід.

Ми будемо використовувати порт B. Спочатку ми повинні встановити всі ніжки порту B як цифрові виходу. У порту B є лише 6 ніжок. Біти регістру для порту DDRB повинні бути встановлені в 1, якщо нога буде використовуватися як вихід (OUTPUT), і в 0, якщо нога буде використовувати як вхід (INPUT). Біти портів нумеруються з 0 до 7, але не завжди містять всі 8 ніг.

Приклад:

DDRB = B00111110; // встановити ніжки порту з 1 по 5 як виходу, а 0 як вхід.

Зверніть увагу, що у мікроконтролерах фірми Microchip все навпаки. 0 біт – нога працює як вихід, а 1 – як вхід.

У нашому проекті вогню, що біжить, ми будемо використовувати 5 виходів:

DDRB = B00011111; // встановити ноги порту з 0 по 4 як виходу

Для запису значень у порт необхідно використовувати регістр PORTB. Засвітити перший світлодіод можна командою:

PORTB = B00000001;
перший та четвертий:
PORTB = B00001001;

Тепер ви бачите, як легко ми можемо вмикати та вимикати світлодіоди. Тепер розповімо вам про операторів зсуву

Є 2 оператори двійкового зсуву: оператор зсуву вліво<< и оператор сдвига вправо >>. Оператор зсуву вліво<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> Зсув біти вправо.

Приклад:

varA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

Тепер повернемося до нашої програми, яка показана нижче. Нам потрібно ввести 2 змінні: перша upDownміститиме значення куди рухатися - вгору чи вниз, а друга cylonякі світлодіоди запалювати.

У функції setup()ми визначаємо які ніжки мають працювати як виходу.

У головному циклі програми loop(), світлодіоди по черзі загоряються вгору шляхом збільшення змінної cylon, а коли доходить до найвищого, то змінної upDownприсвоюється 0 і світлодіоди спалахують вниз по черзі.

Код: /* Вогонь, що біжить. 5 світлодіодів */ unsigned char upDown=1; // починаємо з руху нагору unsigned char cylon=0; // визначає черговість LED void setup() ( DDRB = B00011111; // встановлюємо порт B з 0 по 4 як виходу ) void loop() ( if(upDown==1)( // якщо йдемо вгору, то cylon++; if( cylon>=4) upDown=0;// коли досягнутий найбільший номер LED, то в наступному циклі йдемо вниз) else (cylon--; if(cylon==0) upDown=1; // коли досягнуть найменший номер LED, то в наступному циклі йдемо вгору) PORTB = 1<< cylon; //сдвиг delay(200); // пауза 200 мс

У цьому експерименті ми змушуємо вогник бігти за світлодіодною шкалою.

СПИСОК ДЕТАЛІВ ДЛЯ ЕКСПЕРИМЕНТУ

- 1 плата Arduino Uno;

- 1 безпайкова макетна плата;

- 1 світлодіодна шкала;

- 10 резисторів номіналом 220 Ом;

- 11 дротів «тато-тато».

ПРИНЦИПОВА СХЕМА

СХЕМА НА МАКЕТНІЙ ПЛАТІ

СКЕТЧ

скачати для Arduino IDE
// Світлодіодна шкала підключена до групи пінів розташованих // підряд. Даємо зрозумілі імена першому і останньому пінам #define FIRST_LED_PIN 2 #define LAST_LED_PIN 11 void setup() ( // у шкалі 10 світлодіодів. Ми могли б написати pinMode 10 // раз: для кожного з пінів, але це б роздуло код і // зробило його зміну більш проблематичним.// Тому краще скористатися циклом.Ми виконуємо // pinMode для (англ. for) кожного піна (змінна pin) // від першого (= FIRST_LED_PIN) до останнього включно // (<= LAST_LED_PIN), всякий раз продвигаясь к следующему // (++pin увеличивает значение pin на единицу) // Так все пины от 2-го по 11-й друг за другом станут выходами for (int pin = FIRST_LED_PIN; pin <= LAST_LED_PIN; ++pin) pinMode(pin, OUTPUT); } void loop() { // получаем время в миллисекундах, прошедшее с момента // включения микроконтроллера unsigned int ms = millis(); // нехитрой арифметикой вычисляем, какой светодиод // должен гореть именно сейчас. Смена будет происходить // каждые 120 миллисекунд. Y % X — это остаток от // деления Y на X; плюс, минус, скобки — как в алгебре. int pin = FIRST_LED_PIN + (ms / 120) % 10; // включаем нужный светодиод на 10 миллисекунд, затем — // выключаем. На следующем проходе цикла он снова включится, // если гореть его черёд, и мы вообще не заметим отключения digitalWrite(pin, HIGH); delay(10); digitalWrite(pin, LOW); }

ПОЯСНЕННЯ ДО КОДУ

  • За допомогою виразу forми організуємо цикл із лічильником . У цьому випадку для налаштування портів на вихід. Щоб зробити такий цикл, потрібно:
    • Ініціалізувати змінну-лічильник, надавши їй первісне значення. У нашому випадку: int pin = FIRST_LED_ PIN ;
    • Вказати умову, до досягнення якої повторюватиметься цикл. У нашому випадку: pin<= LAST_LED_ PIN ;
    • Визначити правило, яким буде змінюватися лічильник. У нашому випадку ++pin(Див. нижче про оператора ++ ).
  • Наприклад, можна зробити цикл for (int i = 10; i > 0; i = i - 1). В цьому випадку:
    • Змінної i надається значення 10 ;
    • Це значення задовольняє умову i > 0 ;
    • Тому блок коду, поміщений цикл, виконується перший раз;
    • Значення iзменшується на одиницю, згідно з заданим правилом, і набуває значення 9 ;
    • Блок коду виконується вдруге;
    • Все повторюється знову і знову аж до значення iрівного 0 ;
    • Коли iстане рівна 0 , умова i > 0не виконається, та виконання циклу закінчиться;
    • Контролер перейде до коду, наступного за циклом for ;
  • Поміщайте код, який потрібно зациклити між парою фігурних дужок. {} якщо в ньому більше однієї інструкції;
  • Змінна-лічильник, що оголошується в операторі forможе використовуватися всередині циклу. Наприклад, у цьому експерименті pinпослідовно приймає значення від 2 до 11 і, будучи переданою в pinModeдозволяє налаштувати 10 портів одним рядком, поміщеною в цикл;
  • Змінні-лічильники видно лише всередині циклу. Тобто. якщо звернутися до pinдо або після циклу компілятор видасть помилку про неоголошену змінну;
  • Конструкція i = i - 1у поясненні вище не є рівнянням! Ми використовуємо оператор присвоєння = для того, щоб у змінну iпомістити значення, що дорівнює поточному значенню i, зменшеному на 1 ;
  • Вираз ++pin- Це т.зв. оператор інкремента , застосований до змінної pin. Ця інструкція дасть той самий результат, що pin = pin + 1;
  • Аналогічно інкременту працює оператор декременту - - , що зменшує значення на одиницю. Докладніше про це у статті про арифметичні операції;
  • Тип даних unsigned intвикористовують із зберігання цілих чисел без знака, тобто. тільки невід'ємних . За рахунок зайвого біта, який тепер не використовується для зберігання знака, ми можемо зберігати у змінній такого типу значення до 65 535 ;
  • Функція millisповертає кількість мілісекунд, що пройшли з моменту включення або перезавантаження мікроконтролера. Тут ми використовуємо її для відліку часу між перемикання світлодіодів;
  • За допомогою виразу (ms/120) % 10ми визначаємо, який із 10 світлодіодів має горіти зараз. Перефразовуючи, ми визначаємо який відрізок завдовжки 120 мс йде зараз і який його номер усередині поточного десятка. Ми додаємо порядковий номер відрізка до номера порту, який у поточному наборі виступає першим;
  • Те, що ми гасимо світлодіод за допомогою digitalWrite(pin, LOW)всього через 10 мс після включення непомітно оку, т.к. дуже скоро буде знову обчислено, який із світлодіодів включати, і він буде включений - щойно погашений або наступний.

ПИТАННЯ ДЛЯ ПЕРЕВІРКИ СЕБЕ

  1. Чому в цьому експерименті ми підключаємо світлодіодну шкалу, не використовуючи транзистор?
  2. Якби ми включали світлодіоди лише на портах 5, 6, 7, 8, 9, що потрібно було б змінити у програмі?
  3. За допомогою якоїсь іншої інструкції можна виконати дію, еквівалентну ++pin ?
  4. У чому різниця між змінними типами intі unsigned int ?
  5. Що повертає функція millis() ?
  6. Як у цьому експерименті ми обчислюємо номер порту, у якому потрібно включити світлодіод?

ЗАВДАННЯ ДЛЯ САМОСТІЙНОГО РІШЕННЯ

  1. Змініть код так, щоб світлодіоди перемикалися раз на секунду.
  2. Не вимикаючи порти, зробіть так, щоб вогник біг тільки по чотирьох розподілах шкали.
  3. Переробіть програму так, щоб замість int pin = FIRST_LED_ PIN + (ms/120) % 10переміщенням вогника керував цикл for .
  4. Не змінюючи місцями дроти, змініть програму так, щоб вогник бігав у зворотному напрямку.



© 2023 globusks.ru - Ремонт та обслуговування автомобілів для новачків