## Vianočné svetielka #### alebo ako ovládať vianočné svetlá na diaľku cez MQTT s ESP32 [mirek](https://bletvaska.github.io) / [**Namakaný deň - Webináre**](http://www.namakanyden.sk/webinare/)
## Motivácia
## Interaktívny vianočný stromček v SOS * autor: Matúš Čopík * riešenie: ESP8266 + Arduino IDE + HTTP server + PHP stránka * článok: [Technické zákulisie interaktívneho vianočného stromčeka](https://www.sos.sk/articles/sos-supplier-of-solution/technicke-zakulisie-interaktivneho-vianocneho-stromceka-2119) (15.2.2018) * Namakaný deň 2018: [Ako pripojiť vianočný stromček na internet](http://www.namakanyden.sk/2018/#main-track) ([video](https://archive.tp.cvtisr.sk/?31959103))
[![ESP32](images/esp32.jpg)](https://www.espressif.com/en/products/socs/esp32)
[![MicroPython](images/logo-micropython.jpg)](http://micropython.org)
[![MQTT](images/logo-mqtt.svg)](https://mqtt.org)
## NeoPixel
## NeoPixel je WS2812 ![WS2812](images/ws2812.jpg)
## LED pásik s WS2812B ![WS2812B Led Strip](images/ws2812b.led.strip.png)
## Modul WS2812B ![WS2812B Module](images/ws2812b.module.png) Notes: * https://freesvg.org/ws2812b-led-strip
![WS2812B Led Strips](images/ws2812b.led.strips.jpg) Notes: * https://www.eledsolutions.com/eled-strip-lighting-solutions/
## NeoPixel a uPython * modul [`neopixel`](https://docs.micropython.org/en/latest/esp8266/tutorial/neopixel.html) * obsahuje triedu `NeoPixel` * inicializácia: ```python from machine import Pin from neopixel import NeoPixel np = NeoPixel(Pin(12), 50) ```
## Ovládanie pixelov ![Controlling Individual Pixels](images/control.leds.png)
```python from machine import Pin from neopixel import NeoPixel np = NeoPixel(Pin(12), 50) np[0] = (255, 0, 0) # prvy pixel np[3] = (125, 204, 223) np[7] = (120, 153, 23) np[10] = (255, 0, 153) np[-1] = (0, 0, 255) # posledny pixel np[np.n // 2] = (0, 255, 0) # prostredny pixel np.write() ```
## Svetelné efekty
## Zmazanie všetkých pixelov ![Clear All Pixels](images/effect-clear.png)
```python def clear(pixels): for i in range(pixels.n): pixels[i] = (0, 0, 0) pixels.write() ```
## Nastavenie všetkých pixelov na jednu farbu ![Set All Pixels to the Same Color](images/effect-set.color.png)
```python def set_color(pixels, r, g, b): for i in range(pixels.n): pixels[i] = (r, g, b) pixels.write() ```
## Cycle efekt ![Cycle Effect](images/effect-cycle.png)
```python def cycle(pixels, r, g, b, wait): clear(pixels) for pos in range(pixels.n): pixels[pos] = (r, g, b) pixels.write() sleep_ms(wait) pixels[pos] = (0, 0, 0) else: pixels.write() ```
## Bounce efekt ![Bounce Effect](images/effect-bounce.png)
```python def bounce(pixels, r, g, b, wait): set_color(pixels, r, g, b) for pos in range(pixels.n): pixels[pos] = (0, 0, 0) pixels.write() sleep_ms(wait // 2) pixels[pos] = (r, g, b) pixels.write() sleep_ms(wait // 2) for pos in range(pixels.n - 1, -1, -1): pixels[pos] = (0, 0, 0) pixels.write() sleep_ms(wait // 2) pixels[pos] = (r, g, b) pixels.write() sleep_ms(wait // 2) ```
```python def bounce(pixels, r, g, b, wait): set_color(pixels, r, g, b) for i in range(2 * pixels.n - 1): if (i // pixels.n) % 2 == 0: pos = i % pixels.n else: pos = pixels.n - 1 - (i % pixels.n) - 1 pixels[pos] = (0, 0, 0) pixels.write() sleep_ms(wait) pixels[pos] = (r, g, b) else: pixels.write() ```
## And Now for Something Completely Different
## Ďiaľkové ovládanie cez *Internet* pomocou *MQTT*
## MQTT a uPython * obsahuje moduly [`umqtt.simple`](https://pypi.org/project/micropython-umqtt.simple/) a [`umqtt.robust`](https://pypi.org/project/micropython-umqtt.robust/) vo verzii *1.0* * existujú aj novšie verzie *2.0* * použijeme verejný broker [`broker.hivemq.com`](http://www.mqtt-dashboard.com) * online [MQTT Websocket client](http://www.hivemq.com/demos/websocket-client/) * topic pre správy: `iotlab/things/stromcek`
## Pripojenie ```python from umqtt.robust import MQTTClient # connect to WiFi do_connect('ssid', 'password') # connect to MQTT broker client = MQTTClient('client-id', 'broker-ip', 1883) client.set_callback(on_message) client.connect() client.subscribe('iotlab/things/stromcek') while True: client.wait_msg() ```
## `on_message() Callback` ```python def on_message(topic, message): print('>> {}: {}'.format(topic, message)) if message == b'cycle': cycle(np, 255, 0, 0, 100) elif message == b'bounce': bounce(np, 0, 255, 0, 100) elif message == b'rainbow': rainbow_cycle(np, 100) else: print('>> Error: unknown effect {}!'.format(message)) ```
## Houston, we have a problem
## Generátory
![How Generators Work?](images/tape.png)
[![Python Generators](images/python.generators.webp)](https://realpython.com/introduction-to-python-generators/)
## Cycle ako Generátor ```python def cycle(pixels, r, g, b, wait): clear(pixels) while True: for pos in range(pixels.n): pixels[pos] = (r, g, b) pixels.write() sleep_ms(wait) pixels[pos] = (0, 0, 0) yield else: pixels.write() ```
## Aktualizácia * zo všetkých efektov spraviť generátory * nekonečná slučka a `yield` * aktualizovať `on_message()` * globálna premenná `animation` * priradiť jej príslušnú animáciu * upraviť hlavnú slučku ```python global animation animation = bounce(np, 255, 0, 0, 100) while True: client.check_msg() next(animation) ```
## Webové rozhranie
![Warning](images/warning.png)
## Živý stream
## Otázky?

Namakaný Newsletter

Ak nechcete, aby vám ušli akcie organizované makačmi okolo Namakaného dňa, odoberajte newsletter. Vždy vám dáme vedieť, keď budeme niečo namakané organizovať.

## Ďalšie zdroje * [Controlling NeoPixels](https://docs.micropython.org/en/latest/esp8266/tutorial/neopixel.html) - uPython dokumentácia pre modul `neopixel` * [MicroPython: WS2812B Addressable RGB LEDs with ESP32 and ESP8266](https://randomnerdtutorials.com/micropython-ws2812b-addressable-rgb-leds-neopixel-esp32-esp8266/) * [Datasheet](http://www.world-semi.com/solution/list-4-1.html) - pre rozličné verzie WS2812 * [webinar.py](webinar.py) - zdrojový kód vytvorený počas webináru
## Poďakovanie * **Matúš Čopík** - za nápad, podnety, svetielka a pomoc pri realizácii * **Bianka Rujáková** - za mocnú podobu webovej stránky
![qr code](https://api.qrserver.com/v1/create-qr-code/?data=http://bit.ly/2KtBJUa&size=300x300) (**http://bit.ly/2KtBJUa**)