Arduino примеры скетчей бегущие огни с плавным. Бегущие поворотники на ленте WS2812 и Arduino

Ардуино начинающим

В этом уроке мы продолжим работу со светодиодами, но количество светодиодов увеличим до 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 светодиодов */ 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 мс }

Давайте еще ​​немного поморгаем светодиодами. Давайте создадим с Вашей Arduino линейку светодиодов, моргающих слева направо и справа налево, и используя не один, а восемь штук. Заставим моргать светодиоды в бесконечном цикле последовательности 1-2-3-4-5-6-7-8-7-6-5-4-3-2-1-2-3 - ... с задержкой в ​​одну секунду.
Вам понадобится:

  • Ваши стандартные настройки Arduino (компьютер, кабель, Uno или совместимый)
  • 8 светоизлучающих диодов.
  • 8 резисторов 360 Ом 0,25 Вт. Резисторы необходимы для ограничения тока светодиодов.
  • Макетная плата и соединительного провода
Предлагаю сделать задержку переменной. Так что вы могли легко изменить её .
В исходном проекте «мигающий светодиод», описанный в книге Массимо Банци, использовался цифровой вывод 13. На этот раз, вы можете использовать цифровые контакты со 2 до 9. Аппаратная сторона проста - подключите провод от каждого цифрового контакта к аноду светодиода, затем подключите соединительным проводом резистор 360 Ом резистор и далее катод светодиода на землю. См. схему ниже:

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

0.1 алгоритм работы программы.
Устанавливаем, что все контакты мы будем использовать как выходы Создаем переменную для хранения длительность задержки в миллисекундах Начинаем бесконечно повторяемый цикл включить контакт 2, ждать установленное время задержки, выключить его включить контакт 3, ждать установленное время задержки, выключить его Повторите эти операции для остальных выходов - с 4 до 9 Затем сделайте то же самое, но в обратном направлении до контакта 3 Окончание бесконечного цикла Что получилось у Вас? Ни чего страшного нет, если у вас ни чего не получилось. Так как Вы учитесь. Но чтобы сэкономить ваше время ниже приведен код для данной схемы .

int del=100; // sets a default delay time, 100 milliseconds (one tenth of a second)
void setup()
{
// initialize the digital pins as outputs:
// later on there will be easier ways to do this
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
// the loop() method repeats indefinitely until you turn off the power
void loop()
{
digitalWrite(2, HIGH); // turn on LED on pin 2
delay(del); // wait (length determined by value of "del")
digitalWrite(2, LOW); // turn it off

delay(del); // wait


delay(del); // wait


delay(del); // wait


delay(del); // wait


delay(del); // wait


delay(del); // wait

digitalWrite(9, HIGH); // turn on LED on pin 9
delay(del); // wait
digitalWrite(9, LOW); // turn it off
digitalWrite(8, HIGH); // turn on LED on pin 8
delay(del); // wait
digitalWrite(8, LOW); // turn it off
digitalWrite(7, HIGH); // turn on LED on pin 7
delay(del); // wait
digitalWrite(7, LOW); // turn it off
digitalWrite(6, HIGH); // turn on LED on pin 6
delay(del); // wait
digitalWrite(6, LOW); // turn it off
digitalWrite(5, HIGH); // turn on LED on pin 5
delay(del); // wait
digitalWrite(5, LOW); // turn it off
digitalWrite(4, HIGH); // turn on LED on pin 4
delay(del); // wait
digitalWrite(4, LOW); // turn it off
digitalWrite(3, HIGH); // turn on LED on pin 3
delay(del); // wait
digitalWrite(3, LOW); // turn it off

В этом эксперименте мы заставляем огонёк бежать по светодиодной шкале.

СПИСОК ДЕТАЛЕЙ ДЛЯ ЭКСПЕРИМЕНТА

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

В этом уроке мы продолжим работу со светодиодами, но количество светодиодов увеличим до 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 varA = 1 varA = 1

Теперь вернемся к нашей программе, которая показана ниже. Нам нужно ввести 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