Программирование рождественских огней на Python

Как закодировать собственное светодиодное световое шоу с помощью Raspberry Pi

Сезон отпусков официально начался, а это значит, что нужно делать покупки, печь и, конечно же, украшать. В магазинах товаров для дома продаются десятки и десятки светильников разных форм, цветов и спецэффектов. Но вы когда-нибудь хотели создать свои собственные праздничные огни с нестандартными цветами и движениями? Несколько простых строк Python делают это возможным.

Это мой первый проект Raspberry Pi, и я очень рад поделиться им с вами перед праздниками. Я использовал Raspberry Pi для управления индивидуально адресуемыми светодиодными лентами. В отличие от типичных праздничных огней, эти полосы позволяют настраивать входы для каждого светодиода. Ссылки на материалы указаны ниже.

Фон

Светодиоды WS2812B — это светодиоды с индивидуальной адресацией, что позволяет программировать отдельные светодиоды. Лента имеет 3 кабеля, идущих к каждому светодиоду:

  1. Отрицательная линия питания/земля (черный)
  2. Положительная линия питания (красная)
  3. Линия данных (зеленая)

У этой марки светодиодной ленты раздвоены линии питания (красный и черный кабели), чтобы было проще подключиться к отдельному блоку питания. Несмотря на то, что в конце 5 кабелей, есть только 3 пути.

На другом конце ленты имеется штыревой разъем, который позволяет последовательно добавлять другие светодиодные ленты. Однако добавление дополнительных полос может привести к перегреву, если мощности недостаточно.

Материалы

  1. "Светодиодные светильники". Я использовал две 5-метровые полосы WS2812B. Однако любые светодиоды WS281X должны быть совместимы с библиотекой rpi-ws281x.
  2. Raspberry Pi. Я использовал Raspberry Pi 3, но подойдет любой Raspberry Pi с заземлением и 18-контактным разъемом GPIO.
  3. Соединительные кабели «папа-мама
  4. "Источник питания"
  5. Инструменты для зачистки проводов (по желанию)

Направления проводки

Перед запуском убедитесь, что Raspberry Pi и внешний источник питания отключены.

  1. Используйте кабель-перемычку, чтобы подключить кабель заземления светодиодных лент (черный) к контакту заземления на Raspberry Pi. На приведенной ниже схеме контакт 6 используется в качестве земли.
  2. Используйте кабель-перемычку для подключения линии передачи данных светодиодной ленты (зеленой) к GPIO 18 на Raspberry Pi. На Raspberry Pi 3 GPIO 18 — это контакт 12.
  3. Подключите светодиодную ленту к внешнему источнику питания с помощью соединительного элемента. Возможно, вам придется снять часть изоляции с линий электропередач.
  4. Включите Raspberry и внешний источник питания.

Код

В следующих инструкциях предполагается, что на Raspberry Pi установлена ​​ОС Raspian. Запустите код на терминале Raspberry Pi.

Я рекомендую использовать безголовую настройку Raspberry Pi, которая позволит вам получить удаленный доступ к Raspberry Pi. Однако в этом нет необходимости.

Обновление системы

  1. Обновить существующие пакеты
sudo apt-get update

2. Установите git на Raspberry Pi

sudo apt install git

3. Деактивируйте звук, отредактировав следующий файл

sudo nano /etc/modprobe.d/snd-blacklist.conf

4. Добавьте следующую строку в открытый файл. Нажмите Ctrl-O и Ctrl-X, чтобы сохранить и закрыть.

blacklist snd_bcm2835

5. Используйте редактор nano, чтобы открыть файл конфигурации.

sudo nano /boot/config.txt

6. Используйте Ctrl-W для поиска файла. Добавьте #, чтобы закомментировать следующую строку.

#dtparam=audio=on

7. Перезапустите Raspberry Pi, чтобы все изменения вступили в силу.

sudo reboot

Установить и протестировать библиотеку

  1. Клонируйте библиотеку.
git clone https://github.com/rpi-ws281x/rpi-ws281x-python.git

2. Отредактируйте входные параметры в тестовом файле.

sudo nano rpi-ws281x-python/examples/strandtest.py

Моя установка включает в себя две полосы по 150 светодиодов, всего 300 светодиодов. LED_COUNT — единственная переменная, которую мне нужно изменить.

# LED strip configuration:
LED_COUNT = 300       # Number of LED pixels.

Используйте Ctrl-O и Ctrl-X, чтобы сохранить и закрыть файл.

3. Протестируйте установку!

sudo python3 rpi-ws281x-python/examples/strandtest.py

Настроить свет

Чтобы настроить свои источники света, я скопировал strandtest.py из библиотеки rpi-ws281x-python, чтобы создать xmas.py.

# Change directory
cd rpi-ws281x-python/examples

# Copy strandtest.py and name copy xmas.py
cp strandtest.py xmas.py

Это позволило мне изменить существующие функции и создать новые, не перезаписывая strandtest.py. В xmas.py я добавил функцию, при которой все индикаторы выключаются при прерывании клавиатуры (Ctrl-C) или если скрипт выполняется до завершения. После завершения сценарий занимает чуть менее 4 часов.

                                                      
#!/usr/bin/env python3

import time
from rpi_ws281x import PixelStrip, Color
import argparse
import numpy 

# LED strip configuration:
LED_COUNT = 300        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 75  # Set to 0 for darkest and 255 for brightest
LED_INVERT = False    # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53


# Define functions which animate LEDs in various ways.
def colorWipe(strip, color, wait_ms=50):
    """Wipe color across display a pixel at a time."""
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color)
        strip.show()
        time.sleep(wait_ms / 1000.0)


def theaterChase(strip, color, wait_ms=50, iterations=10):
    """Movie theater light style chaser animation."""
    for j in range(iterations):
        for q in range(3):
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, color)
            strip.show()
            time.sleep(wait_ms / 1000.0)
            for i in range(0, strip.numPixels(), 3):
                strip.setPixelColor(i + q, 0)

def candyCane(strip, red_start):
   for i in range(strip.numPixels()):
      strip.setPixelColor(i, Color(255,255,255))
   for i in range(strip.numPixels()):
      if i % 10 == red_start or i == 10:
         for j in range(i, i + 5):
            strip.setPixelColor(j, Color(255, 0, 0))
   strip.show()

def candyCaneMoving(strip, iterations):
   i = 0
   for iter in range(iterations):
      candyCane(strip,i)
      if i < 9:
         i += 1
      else: i = 0
      time.sleep(1)

# Main program logic follows:
if __name__ == '__main__':
    # Process arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')
    args = parser.parse_args()

    try:
       # Create NeoPixel object with appropriate configuration.
       strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
       # Intialize the library (must be called once before other functions).
       strip.begin()

       print('Color wipe animations.') 
       candyCaneMoving(strip, 3600) 
       colorWipe(strip, Color(127,127,127))

       LED_BRIGHTNESS = 255
       # Create NeoPixel object with appropriate configuration
       strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL) 
       # Intialize the library (must be called once before other functions).
       strip.begin()
       theaterChase(strip,Color(127,0,0),1000,1000)
       theaterChase(strip,Color(0,127,0),1000,1000) 
       theaterChase(strip,Color(127,127,127),1000,1000) 
       colorWipe(strip, Color(255, 0, 0)) # Red wipe 
       time.sleep(600) 
       colorWipe(strip, Color(0, 255, 0)) # Green wipe 
       time.sleep(600) 
       colorWipe(strip, Color(0, 0, 0), 10)

    except  KeyboardInterrupt:
      colorWipe(strip, Color(0, 0, 0), 10)

Запланировать задачу

Я хотел, чтобы мой свет включался каждую ночь без участия пользователя, поэтому я запланировал задачу с помощью Cron. Cron поставляется с операционной системой Raspberry Pi Raspian.

  1. Откройте таблицу заданий Cron в режиме редактора.
crontab -e

Выберите редактор. Я рекомендую нано.

2. Добавьте задачу в файл.

0 17 * * * sudo python3 ~/rpi-ws281x-pi/examples/xmas.py

Задания Cron имеют формат [minute] [hour] [day of month] [month] [day of week] [command to execute]. * означает любое значение, поэтому Cron выполнит команду для всех значений в этом поле. Вышеупомянутое задание будет выполняться в 17:00 (или 17:00) каждый день каждого месяца.

Полученные результаты

Рекомендации

Подключайте и управляйте светодиодными лентами WS2812 RGB через Raspberry Pi. Учебники по Raspberry Pi. https://tutorials-raspberrypi.com/connect-control-raspberry-pi-ws2812-rgb-led-strips/

Руководство для начинающих по Cron Jobs и Crontab. PiMyLifeUp. https://pimylifeup.com/cron-jobs-and-crontab/

Заключение

Спасибо, что прочитали о моем первом проекте Raspberry Pi. Если у вас есть какие-либо вопросы, пожалуйста, свяжитесь с нами или оставьте комментарий. Я более чем счастлив помочь. Кроме того, я хотел бы услышать, какие шаблоны вы хотели бы видеть для будущих светодиодных проектов.

Спасибо, что прочитали мою статью. Если вам нравится мой контент, подпишитесь на меня или присоединяйтесь к Medium.

Свяжитесь со мной в LinkedIn, Twitter или Instagram.

Все отзывы приветствуются. Я всегда стремлюсь узнать новые или лучшие способы ведения дел.

Не стесняйтесь оставлять комментарии или обращаться ко мне по адресу [email protected].