Catégories
Liens
Sur une interface representant les differentes lumieres.
On peut enregistrer une sequence en appuyant sur des boutons (ou interface photoresitance)
Pour le dimmer il faut utiliser la lib https://github.com/RobotDynOfficial/RBDDimmer
Ca clignote un peu quand on est pres du zero… il faut plutot se ballader entre 5% et 100% pour eviter ces clignotements…
Le code source est consultable sur le git du projet. Il est composé de C/Arduino pour les ESP8266, de python pour le serveur/backend et de javascript pour l'interface web.
Les ESP8266 sont alimentés en 5v via un petit convertisseur 230VAC → 5VDC dédié. Ils alimentent à leur tour un module dimmer avec détection du point zéro qui alimentera en PWM l'ampoule halogène. Un potentiomètre permet de contrôler manuellement l'ampoule et de désactiver la réception OSC.
ESP8266 | dimmer | Potentiomètre | convertisseur 220VAC→5VDC |
---|---|---|---|
G | GND | patte externe | -v |
5v | +v | ||
3v3 | VCC | patte externe | |
A0 | patte centrale | ||
D1 | PWM | ||
D2 | ZC |
Les ESP8266 se connectent sur un routeur dédié dont le SSID et éventuellement mot de passe est défini dans le code :
static char* PSK = NULL; static char* SSID = "bergen.olo";
Un nom d'hôte unique les identifie au sein du réseau. Celui-ci permettra de faire correspondre chaque ESP à une fenêtre donnée de l'interface web. Ce nom d'hôte est composé de light immédiatement suivi d'un chiffre entre 0 et 11 (ex : light2). Il est également défini dans le code :
#define FIXED_HOSTNAME "light0"
Dès leur connexion au réseau, ils se présenterons en donnant leur nom d'hôte et leur IP au serveur (par défaut en broadcast). Si celui-ci leur répond, ils stockeront l’adresse IP d'où provient la réponse qu'ils utiliseront pour toute communication ultérieure. Si nécessaire, il est possible de flasher les ESP Over The Air par le port 8266. ⇐
Un Raspberry Pi est utilisé pour servir une interface web via un script python3 utilisant flask et socketIO. L'interface présente 12 fenêtres sous forme de deux rangées de six cases. Si les ESP8266 représentant une fenêtre ne sont pas branchés, la case reste inactive.
La déclaration des ESP8266 attendus se fait dans le fichier config.py où il est possible d'entrer sous forme de liste les identifiants des ESP8266 connectés : activeWindows = [0, 1, 2, 4, 5, 6, 7, 8, 10, 11]
les numéros de 0 à 11 correspondant aux identifiants donnés aux lampes.
La génération de son côté client se fait par la librairie Tone.js qui permet de créer un oscillateur multiple et d'y ajouter de la réverb. Les réglages de l'oscillateur (ADSR, nombre d'oscillateurs, déphasage, forme d'onde) sont stockés dans le fichier static/js/index.js :
var synth = new Tone.PolySynth(3, Tone.Synth, { "oscillator" : { "type" : "fatsine", "count" : 3, "spread" : 30 }, "envelope" : { "attack" : 0.1, "decay" : 0.1, "sustain" : 0.5, "release" : 0.4, "attackCurve" : "exponential" }, }).toMaster();
Les notes utilisées pour chaque fenêtre sont réglable dans le fichier config.py :
notes = ["C", "D", "E", "G", "A"] # list of notes that will be played on the UI startOctave = 3 # lowest octave to be played playNotesOnUI = True # play sounds corresponding to lights on the UI when sequences are played
Il est totalement impossible de garantir une lecture synchrone de ces sons avec les lumières sur le téléphone de chaque participant connecté.
Le tout peut devenir très vite cacophonique.
L'enregistrement d'une séquence débute avec le bouton startRec. L'utilisateur peut alors cliquer sur les icônes correspondant aux fenêtres qu'il veut allumer. Une pression maintenue correspondra à une lumière continue. Une fois la séquence voulue enregistrée, un appui sur le bouton stopRec clôturera l'enregistrement. La durée maximale d'enregistrement est réglable en ms dans le fichier config.py : sequenceMaxLength = 30000
Une fois atteinte, l'enregistrement est automatiquement clôturé, comme si l'utilisateur avait cliqué sur stopRec Le bouton play envoie la séquence au serveur qui commencera immédiatement à la lire en boucle. Le bouton remove uniquement la dernière séquence jouée depuis cet appareil tandis que le bouton clear effacera toutes les séquences en cours de lecture.
Chaque séquence est lue en boucle, atténuée à chaque itération. L'atténuation est réglable (en pourcent par itération) dans le fichier config.py :dampeningPerLoop = 10
. Cette atténuation peut être renforcée par une atténuation additionnelle dépendant du nombre de séquences utilisant les mêmes lampes : si une séquence est la seule à utiliser certaines lampes, elle mettra plus de temps à disparaître. Ce paramètre est réglable dans config.py dampeningPerUser
(0 = désactivé)
Serveur et lampes communiquent en OSC par UDP, le serveur écoute sur le port 9000 et transmet sur le port 8000 (donc l'inverse pour les ESP8266).
Liste des messages OSC implémentés :
Pour créer un portail captif, on utilise un routeur flashé sous DD-WRT qui permet d'utiliser dnsmasq pour router tout le trafic entrant vers le raspberry pi. Celui-ci se voit donc assigner une IP fixe (10.0.0.100) et on ajoutera l'option address=/#/10.0.0.100
dans la configuration dnsmasq du routeur. Enfin, puisque le réseau Wifi sera public, on désactive l'interface de gestion du routeur en wifi, qui restera accessible depuis ses prises ethernet.
Côté Pi, la communication serveur/client est gérée par flask qui redirigera toutes les requêtes vers la page d'accueil de l'interface web. Le SSL n'étant pas implémenté, les requêtes SSL ne pourront aboutir. Les websockets via flask-socketio assurent une communication fluide entre front-end et backend (envoi de séquences vers le serveur, déclenchement de sons sur l'interface des clients…). Le serveur web écoute sur le port 8080 mais une redirection d'iptables redirige le port 80 sur le port 8080.
Idée design tasseau + conserve.. :ololamp.blend
Materiaux