Создание светодиодного сканера Knight Rider с помощью Arduino
СДЕЛАЙ САМ

Создание светодиодного сканера Knight Rider с помощью Arduino

Вы когда-нибудь мечтали о собственном автомобиле Knight Industries Two Thousand (KITT) – ну, знаете, из фильма Knight Rider? Сделайте свою мечту на шаг ближе к реальности, построив светодиодный сканер!

Вы когда-нибудь мечтали о собственном автомобиле Knight Industries Two Thousand (KITT) – ну, знаете, из Knight Rider? Сделайте свою мечту на шаг ближе к реальности, построив светодиодный сканер! Вот конечный результат:

Что вам нужно

Для этого проекта нужно не так много деталей, и многие из них у вас уже есть:

  • 1 x Arduino UNO или аналогичный.
  • 1 x Breadboard.
  • 8 красных светодиодов.
  • 8 x 220 Ом резисторов.
  • 1 x 10k Ом потенциометр.
  • Провода для подключения.

Если у вас есть стартовый набор Arduino, скорее всего, у вас есть все эти детали (что можно сделать с помощью стартового набора?)

Подойдет почти любая Arduino, если у нее есть восемь доступных выводов (Никогда не пользовались Arduino раньше? Начните здесь). Для управления светодиодами можно использовать регистр сдвига, хотя для данного проекта это не нужно, так как у Arduino достаточно выводов

План сборки

Это очень простой проект. Хотя он может показаться сложным из-за большого количества проводов, каждая отдельная деталь очень проста. Каждый светодиод подключен к отдельному выводу Arduino. Это означает, что каждый светодиод можно включать и выключать по отдельности. Потенциометр подключен к аналоговому входу Arduino, который будет использоваться для регулировки скорости сканера

Схема

Подключите внешний левый контакт (если смотреть спереди, то контакты внизу) потенциометра к земле. Противоположный внешний вывод подключите к +5В. Если потенциометр работает неправильно, поменяйте местами эти контакты. Подключите средний контакт к аналоговому входу 2 Arduino

Подключите анод (длинную ножку) каждого светодиода к цифровым контактам с первого по восьмой. Катоды (короткие ножки) подключите к заземлению Arduino

Код

Создайте новый скетч и сохраните его под именем ‘knightRider’. Вот код:

constintleds   = {};// Led pins
constinttotalLeds =
inttime =50// Default speed

voidsetup()
  // Initialize all outputs
  forinti =; i <= totalLeds; ++i) {
    pinMode(leds i , OUTPUT);
  }.

voidloop()
  forinti =; i < totalLeds -; ++i) {
    // Scan left to right
    time = analogRead();
    digitalWrite(leds i , HIGH);
    delay(time);
    digitalWrite(leds i + , HIGH);
    delay(time);
    digitalWrite(leds i , LOW);
  }
  forinti = totalLeds; i >; --i) {
    // Scan right to left
    time = analogRead();
    digitalWrite(leds i , HIGH);
    delay(time);
    digitalWrite(leds i - , HIGH);
    delay(time);
    digitalWrite(leds i , LOW);
  }

Давайте разложим это на части. Каждый вывод светодиода хранится в массиве:

constintleds   = {};

Массив – это, по сути, коллекция связанных элементов. Эти элементы определяются как константные (‘const’), что означает, что они не могут быть изменены в дальнейшем. Вы не обязаны использовать константу (код будет прекрасно работать, если убрать ‘const’), хотя это рекомендуется

Доступ к элементам массива осуществляется с помощью квадратных скобок (‘ ‘) и целого числа, называемого индексом. Индексы начинаются с нуля, поэтому ‘leds 2 ‘ вернет третий элемент массива – контакт 3. Массивы делают код более быстрым в написании и легким в чтении, они заставляют компьютер делать тяжелую работу!

Цикл for используется для настройки каждого контакта в качестве выхода:

forinti =; i <= totalLeds; ++i) {
    pinMode(leds i , OUTPUT);

Этот код находится внутри функции ‘setup()’, так как его нужно выполнить только один раз в начале программы. Циклы For очень полезны. Они позволяют выполнять один и тот же код снова и снова, каждый раз с разным значением. Они идеально подходят для работы с массивами. Объявляется целое число ‘i’, и только код внутри цикла может получить доступ к этой переменной (это известно как ‘область видимости’). Значение i начинается с нуля, и на каждой итерации цикла i увеличивается на единицу. Как только значение i станет меньше или равно переменной ‘totalLeds’, цикл ‘прервется’ (остановится)

Значение i используется для доступа к массиву ‘leds’. Этот цикл обращается к каждому элементу массива и конфигурирует его как выход. Вы могли бы вручную набрать ‘pinMode(pin, OUTPUT)’ восемь раз, но зачем писать восемь строк, если можно написать три?

В то время как некоторые языки программирования позволяют определить количество элементов в массиве (обычно с помощью синтаксиса типа array.length), Arduino не делает это так просто (это требует немного больше математики). Поскольку количество элементов в массиве уже известно, это не проблема

Несколько светодиодов горят одновременно.

Внутри главного цикла (void loop()) находятся еще два цикла for. В первом из них светодиоды включаются и выключаются от 1 до 8. Во втором цикле светодиоды включаются и выключаются в диапазоне 8 – 1. Обратите внимание, что текущий вывод включен, и текущий вывод плюс один также включен. Это обеспечивает одновременное включение двух светодиодов, что делает сканер более реалистичным

В начале каждого цикла в переменную ‘time’ считывается значение потенциометра:

time = analogRead();

Это делается дважды, по одному разу внутри каждого цикла. Это необходимо постоянно проверять и обновлять. Если бы это было вне циклов, это все равно бы работало, но была бы небольшая задержка – это будет выполняться только после завершения цикла. Поты являются аналоговыми, поэтому используется ‘analogRead(pin)’. Он возвращает значения от нуля (минимум) до 1023 (максимум).Arduino может преобразовать эти значения в нечто более полезное, однако они идеально подходят для данного случая

Задержка между сменой светодиодов (или скорость сканера) задается в миллисекундах (1/1000 секунды), поэтому максимальное время составляет чуть более 1 секунды

Расширенный сканер

Внешние пары подсвечиваются.

Теперь, когда вы знаете основы, давайте рассмотрим кое-что более сложное. Этот сканер будет зажигать светодиоды попарно, начиная снаружи и работая внутри. Затем он поменяет направление и перейдет от внутренних пар к внешним. Вот код:

constintleds   = {};// Led pins
constinttotalLeds =
constinthalfLeds =
inttime =50// Default speed

voidsetup()
  // Initialize all outputs
  forinti =; i <= totalLeds; ++i) {
    pinMode(leds i , OUTPUT);
  }.

voidloop()
  forinti =; i < (halfLeds -); ++i) {
    // Scan outside pairs in
    time = analogRead();
    digitalWrite(leds i , HIGH);
    digitalWrite(leds (totalLeds - i) - , HIGH);
    delay(time);
    digitalWrite(leds i , LOW);
    digitalWrite(leds (totalLeds - i) - , LOW);
    delay(time);
  }
  forinti = (halfLeds -); i >; --i) {
    // Scan inside pairs out
    time = analogRead();
    digitalWrite(leds i , HIGH);
    digitalWrite(leds (totalLeds - i) - , HIGH);
    delay(time);
    digitalWrite(leds i , LOW);
    digitalWrite(leds (totalLeds - i) - , LOW);
    delay(time);
  }

Этот код немного сложнее. Обратите внимание, как оба цикла переходят от нуля к ‘halfLeds – 1’ (3). Это делает сканер лучше. Если бы оба контура шли от 4 – 0 и 0 – 4, то одни и те же светодиоды мигали бы дважды в одной и той же последовательности – это выглядело бы не очень хорошо

Теперь у вас должен быть работающий светодиодный сканер Knight Rider! Эту схему легко модифицировать, чтобы использовать большее количество или большие светодиоды, или реализовать свой собственный шаблон. Эту схему очень легко перенести на Raspberry Pi (новичок в Pi? Начните здесь) или ESP8266

Вы строите реплику KITT? Я буду рад увидеть все, что связано с ‘Найт Райдером’, в комментариях

Об авторе

Алексей Белоусов

Привет, меня зовут Филипп. Я фрилансер энтузиаст . В свободное время занимаюсь переводом статей и пишу о потребительских технологиях для широкого круга изданий , не переставая питать большую страсть ко всему мобильному =)

Комментировать

Оставить комментарий