Бегущие огни на 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. Не меняя местами провода, измените программу так, чтобы огонёк бегал в обратном направлении.



© 2024 globusks.ru - Ремонт и обслуживание автомобилей для новичков