Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Zerynth Lamp: умный IoT-светильник на NeoPixel + Zerynth App (Python)

Компоненты и материалы

Софт

О проекте

Умное освещение — драйвер IoT и домашней автоматизации. Руководство: управление NeoPixel лентой через мобильное приложение Zerynth App — цветовая палитра + выбор анимаций.

Шаг 1: Материалы

(Список выше. Фото компонентов в оригинале.)

Шаг 2: Сборка

  1. Установите Wi-Fi Shield и Zerynth Shield на плату (на Photon — только Zerynth Shield на dédié коннекторы).
  2. Подключите NeoPixel к порту на Zerynth Shield.
  3. Поместите всё в корпус лампы.

Шаг 3: Программирование (Zerynth Studio — Python!)

  1. Подключите плату, сделайте «Virtualize» (установка VM).
  2. Создайте проект: 3 файла + project.md — main.py, animation.py, template.html.
  3. Скопируйте код ниже.
  4. Uplink (загрузка) на плату.

После включения лампа коннектится к заданной Wi-Fi сети. Откройте Zerynth App — найдет «Zerynth Lamp», откроет интерфейс: Color Picker + Dropdown анимаций (Little Snakes, Spinner, Rainbow, Pulse) + ползунок скорости.

Код

main.py


import streams
from bcm43362 import bcm43362 as wifi_driver
from wireless import wifi
import animation
from toishield import toishield
from zerynthapp import zerynthapp

streams.serial()

# Wi-Fi
try:
    wifi_driver.auto_init()
    print("Establishing Link...")
    wifi.link("SSID", wifi.WIFI_WPA2, "password")  # <-- ВСТАВЬТЕ СВОИ
    print("Ok!")
except Exception as e:
    print(e)

# HTML-шаблон в флеш
new_resource("template.html")

# Zerynth App callbacks (JS -> Python)
def change_color(r, g, b):
    animation.setup_color(r, g, b)

def change_animation(n):
    animation.setup_anim(n)

def change_speed(n):
    animation.setup_anim_speed(n)

vp = zerynthapp.ZerynthApp("Zerynth Lamp", "Try me!", "resource://template.html")
vp.on("change_color", change_color)
vp.on("change_animation", change_animation)
vp.on("change_speed", change_speed)
vp.run()  # отдельный поток

# Запуск анимации на пине D6, 24 LED
animation.start(D6, 24)

template.html (UI в приложении)


<html>
<head>
  <zerynth/> <zerynth-jquery/> <zerynth-jquery-mobile/> <zerynth-jqwidgets/>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <div data-role="page">
    <div data-role="header"><h1>Zerynth Lamp</h1></div>
    <div role="main" class="ui-content" style="text-align:center">
      <div style="margin: 3px; float: left;" id="dropDownButton">
        <div style="padding: 3px;"><div id="colorPicker"></div></div>
      </div>
      <button class="ui-btn ui-btn-inline ui-shadow" onclick="ZerynthApp.call('change_color',cur_color.r,cur_color.g,cur_color.b)">Colorize!</button>
      <form>
        <div data-role="fieldcontain">
          <label for="animselect">Animation:</label>
          <select name="animselect" id="animselect">
            <option value="0">Little Snakes</option>
            <option value="1">Spinner</option>
            <option value="2">Rainbow</option>
            <option value="3">Pulse</option>
          </select>
        </div>
      </form>
      <form>
        <label for="speedslider">Animation Speed:</label>
        <input type="range" name="speedslider" id="speedslider" data-highlight="true" min="0" max="100" value="50">
      </form>
    </div>
    <div data-role="footer">Powered by Zerynth (www.zerynth.com)</div>
  </div>
  <script>
    var cur_color = {r: 0x54, g: 0x9a, b: 0x97};
    // ... jqxColorPicker init, event handlers -> ZerynthApp.call(...)
  </script>
</body>
</html>

animation.py (логика эффектов)


from neopixel import ledstrips as neo
import threading

lock = threading.Lock()
color = [0x54, 0x9a, 0x97]  # дефолтный цвет
anim = 0
anim_speed = 50
leds = layer0 = layer1 = layer2 = None
npins = 0
stopped = False
stopcolor = [0xff, 0xff, 0xff]

animation_coefficients = [0, 0.2588, 0.5, 0.7071, 0.8660, 0.9659, 1, 0.9659, 0.8660, 0.7071, 0.5, 0.2588]
rainbow = [(0xff,0,0), (0xff,0x7f,0), (0xff,0xff,0), (0,0xff,0), (0,0,0xff), (0x4b,0,0x82), (0x8f,0,0xff)]

def setup_anim(n):
    global layer0, layer1, layer2, anim
    lock.acquire()
    leds.clear(); layer2.clear(); layer0.clear(); layer1.clear()
    n = n % 4
    if n == 0:  # Little Snakes
        layer0[0]=layer0[1]=layer0[2]=(100,0,0)
        layer1[0]=layer1[1]=layer1[2]=(0,100,0)
    elif n == 1:  # Spinner
        for x in range(npins//2):
            layer0[x] = (100//(2*x+1), 0, 0)
            layer1[npins-x-1] = (0, 100//(2*x+1), 0)
        layer2.clear()
    elif n == 2:  # Rainbow
        layer1.clear()
        pstep = 0
        for x in range(npins):
            step = x * len(rainbow) / npins
            rx = (rainbow[int(step)][0] + rainbow[int(pstep)][0]) // 4
            gx = (rainbow[int(step)][1] + rainbow[int(pstep)][1]) // 4
            bx = (rainbow[int(step)][2] + rainbow[int(pstep)][2]) // 4
            layer0[x] = (rx, gx, bx)
            pstep = step
    elif n == 3:  # Pulse
        layer0.clear(); layer1.clear()
    anim = n
    lock.release()

def setup_anim_speed(n):
    global anim_speed
    anim_speed = n

def setup_color(r, g, b):
    global color
    color[0], color[1], color[2] = r, g, b

def animate_background(delay):
    global color
    step = 0
    while True:
        if (anim == 3 or anim == 0) and not stopped:
            lock.acquire()
            layer2.setall(int(color[0]*animation_coefficients[step]/2),
                          int(color[1]*animation_coefficients[step]/2),
                          int(color[2]*animation_coefficients[step]/2))
            lock.release()
            step = (step + 1) % len(animation_coefficients)
        else:
            lock.acquire()
            layer2.clear(); layer2.setall(stopcolor[0], stopcolor[1], stopcolor[2])
            lock.release()
        sleep(delay + 500 - 5*anim_speed)

def animate_foreground(delay):
    while True:
        if not stopped:
            lock.acquire()
            if anim == 0: layer0.lshift(); layer1.rshift()
            elif anim == 1: layer0.rshift(); layer1.rshift()
            elif anim == 2: layer0.rshift(); layer1.rshift()
            elif anim == 3: layer0.lshift(); layer1.lshift()
            lock.release()
        else:
            lock.acquire(); layer0.clear(); layer1.clear(); lock.release()
        sleep(delay + 100 - anim_speed)

def start(pin, numpins):
    global leds, layer0, layer1, layer2, npins
    npins = numpins
    leds = neo.LedStrip(pin, numpins)
    layer0 = neo.LedStrip(pin, numpins)
    layer1 = neo.LedStrip(pin, numpins)
    layer2 = neo.LedStrip(pin, numpins)
    setup_anim(0)
    setup_anim_speed(50)
    thread(animate_background, 500)
    thread(animate_foreground, 50)
    while True:
        leds.clear()
        lock.acquire()
        leds.merge(layer0); leds.merge(layer1)
        leds.merge(layer2, neo.first_color)  # фон только где прозрачно
        lock.release()
        leds.on()
        sleep(50)

def stop(r, g, b):
    global stopped, stopcolor
    stopcolor = [r, g, b]
    stopped = True

def resume():
    global stopped
    stopped = False
    setup_anim(anim)

Шаг 4: Расширение возможностей

Zerynth Shield имеет: тач-сенсор, IR LED, микрофон, датчик света, температуру. Используйте их для реакции лампы на окружение (хлопок, освещение, температуру). Код простой и комментирован. Вопросы — на форуме Zerynth.

Схема

Фото схемы подключения (JPG) в разделе Schematics оригинала.

Производственный процесс

  1. Распространение электрического сигнала со скоростью света: мысленный эксперимент на 186 000 миль
  2. Газовые фонари: эволюция, дизайн и современное производство
  3. Лазерный указатель: дизайн, производство и обзор безопасности
  4. Фонарик: от изобретения к современным инновациям
  5. Галогенные лампы: технологии, история и будущее — экспертный обзор
  6. Светофоры: инженерия, история и будущие инновации
  7. От огня к нити накаливания: эволюция и производство современной лампы накаливания
  8. Создание многодатчиковой системы мониторинга температуры и света с Raspberry Pi и DS18B20
  9. Умный светофор: адаптивное уличное освещение на базе IoT
  10. Цифровой датчик света — управление светодиодом по освещённости на Windows 10 IoT Core