PIGotron

Néopixels comme un ohon

La Raspberry Pi Zero W est une carte très intéressante. Si l'on oublie les difficultés d'approvisionnements (la fondation préfère diriger les 400 000 exemplaires fabriqués chaque mois vers les industriels plutôt que les particuliers qui ont largement contribué à la construction de l'écosystème) on constate que la carte offre un compromis puissance-tarif intéressant. Le facteur de forme et la consommation (qui défini en partie la chauffe) permettent de la caser facilement dans petits espaces sans ventilation, de faire "de l'enfoui". Dans cet article on va "travailler comme un ohon", d'où le titre, pour gérer un neopixel ring avec la carte. L'objectif est de fabriquer une fusée-player audio, avec une animation lumineuse dans le nuage de la fusée. Durant le parcours on va découvrir un container dédié, bien dans l'esprit ohon !

Ca ne marchera jamais !

Un anneau de pixels ring est composé de plusieurs LEDs qui sont chacune adressables individuellement. Chaque "LED" est en fait composé de trois sources RVB (Rouge Vert Bleu) et chaque couleur est addressable. En conséquence toutes les couleurs sont possibles pour chacune des LEDs de l'anneau. Les anneaux existent dans différents formats, on peut avoir une seule LED ou un anneau de 35 par exemple. Il existe aussi des "strips", des bandelettes de neopixels qui sont la même électronique dans un facteur de forme différent.

Chaque anneau propose 4 connecteurs :

  • DI pour Digital Input, permet de commander les LEDs

  • 5V

  • Ground

  • DO pour Digital Out, qui permet de chainer les LEDs ou les anneaux...

En général on peut programmer un microcontrôleur type Arduino en ajoutant une résistance et un condensateur au montage. Avec un Raspberry Pico, pas besoin de composants électroniques supplémentaires. Mais avec une Raspberry Zero 2, qui n'est pas un microcontrôleur, il y a deux raisons principales pour que cela ne fonctionne pas du tout :

  1. le système de LEDs nécessite un timing très précis pour fonctionner et le système d'exploitation de la Raspberry est un système multitâches qui ne gère pas le contrôle temps réel de chaque GPIO

  2. le système de LEDs nécessite une commande (DI) en 5 volts et les GPIOs de la Raspberry sont en 3.3 volts.

Les Raspberry Pi sont des cartes qui bénéficient d'un écosystème formidable et la société Adafruit a mis au point du logiciel permettant de gérer les néopixels avec une Raspberry. La librairie CircuitPython résout le problème du contrôle de GPIO en temps réel en utilisant le matériel PWM et DMA de la carte. PWM c'est pour Pulse Width Modulation, une technique de modulation qui génère des impulsions variables sur une sortie digitale qui représente l'amplitude d'un signal analogique. DMA, c'est pour Direct Memory Access, une technologie qui permet de faire communiquer un sous système matériel avec la mémoire, sans passer par le processeur (en gros). Cela permet ici de transférer des données depuis la mémoire vers la sortie PWM sans solliciter le processeur et donc sans interruption du système d'exploitation qui gère l'attribution du temps CPU pour chaque tâche. Voilà pour le point 1, il est temps d'aller boire un café.

Pour le point 2, en général on utilise un circuit de Shift Level qui permet de passer de 3 vers 5 volts. Cela dit, la documentation sur le ouaibe indique que l'on peut se passer de composants supplémentaires : il est possible que cela fonctionne. De mon point de vue, il n'y a qu'a essayer, on verra bien.

Par contre, attention à la consommation. Si l'on travaille comme un cochon en prenant l'alimentation sur les pins de la Raspberry, alors il faudra ne pas trop tirer dessus. Je n'ai plus d'alimentation de laboratoire à disposition, impossible de faire des mesures actuellement et proposer des données chiffrées, mais le point est le suivant : ne pas allumer toutes les LEDs au maximum de luminosité, le risque est de "cramer" la Raspberry.

Connexion

Comme on l'a dit, on va prendre l'alimentation du neopixel sur la Raspberry.

Le 5V est en haut sur les pattes 2 ou 4 et on va prendre Ground sur la patte 20.

Pour notre la commande de l'anneau, on va utiliser GPIO18 qui se trouve sur la pin "12".



Pour la petite histoire, j'ai tenté sur une autre pin mais c'est bien GPIO18 qu'il faut utiliser ou un autre des papatte PWM, GPIO18, 12, 13 et 19 sur les broches numérotées 12, 32, 33, 35.

Sur GPIO10, une LED s'allume et après c'est fini.


Sur l'anneau, on a soudé (comme un ohon) du câble Dupont.

Le connecteur D0 (Digital Out) qui permet de chainer les bandeau de LEDs n'est pas soudé, on ne va gérer qu'un seul anneau.

Voilà ci-dessous le résultat, des câbles Dupont soudés, on va pouvoir tester !


Bibliothèques ADAFRUIT

Afin d'utiliser les bibliothèques proposées par Adafruit dans du code python, il faut commencer par les installer ! Autre point, comme pour la gestion des petits écrans LCD via I2C, c'est le compte root qui doit être utilisé. Voici les deux commandes à passer :

sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel

sudo python3 -m pip install --force-reinstall adafruit-blinka

Lors du premier test du code, l'erreur suivante est générée :

RuntimeError: ws2811_init failed with code -13 (Unable to initialize SPI)

Mmm... Le message nous indique ce qui ne fonctionne pas : c'est SPI. D'accord, direction "raspi-config" pour activer l'interface SPI.

C'est le logiciel de configuration depuis la ligne de commande. On le lance avec la commande suivante :

sudo raspi-config

Dans le premier menu on sélectionne 3 Interface Options.

Et l'on va sélectionner le menu qui permet d'activer le SPI.

Inutile de rebooter, c'est fonctionnel tout de suite.

En relançant le code, l'erreur n'est plus présente.

Et voilà, maintenant cela fonctionne, au moins sur une LED. On a notre preuve de concept, notre POC, on va pouvoir ajouter quelques lignes de code pour allumer d'autres LEDs et définir quelques animations.

import board

import neopixel


# Define Digital pin connected to NeoPixels

# Number of NeoPixels

# Starts with a little brightness to avoid burning the Raspberry Pi Zero W

pixels = neopixel.NeoPixel(board.D10, 16, brightness=0.2, auto_write=True)

# Show on!

pixels[0] = (0, 100, 0)

De 16 à 24 LEDs

J'ai écris quelques lignes de code pour faire tourner le "neopixel ring 16"plusieurs jours d'affilés et cela à fonctionné sans que l'anneau chauffe.

La Raspberry a bien un peu chauffé, mais 40° c'est largement acceptable.

Du coup, j'ai commandé des anneaux à 24 LEDs, et comme disais Confucius, plus on a de LEDs, plus on s'amuse.

Au passage le prix rendu en France a bien augmenté, il me semble que c'est x2 par rapport à il y a deux ans.

Un autre ohon !

Je me tâtais pour écrire une petite application en python avec bottle qui est un micro-framework qui permet de fabriquer un site ouaibe, une application disais-je pour commander les LEDs via un browser : depuis le smartphone, la tablette ou un ordinateur. En même temps, ces dernières semaines il a beaucoup été question de Docker et Portainer et on a expliqué sur ce site comment installer le tout et profiter du travail de la communauté.

Or voilà t-y pas qu'en consultant la liste des containers mis à disposition par la communauté pi.hosted, je tombe sur ça :

Quelqu'un l'a déjà codé et contenairisé et d'autres l'ont testé et proposé dans la liste de pi.hosted !

Bon, autant le signaler tout de suite, c'est du travail de ohon...

L'installation est pourrie et ensuite on dispose d'un site ouaibe qui est aussi beau qu'une Traban.

Une copie d'écran ci-contre, oui, c'est dégueulasse. Mais d'une part cela fonctionne, d'autre part c'est bien dans l'esprit qui nous anime...

Alors du coup, je vais vous expliquer comment j'ai fait pour le faire fonctionner.


Juste avant, pour le plaisir, une copie du site de l'auteur. C'est splendide et je propose à la SNCF d'embaucher le gars à n'importe quel tarif.

Comme ça on aura des applications SNCF fonctionnellement et graphiquement au même niveau. Et puis si on pouvait aussi faire en sorte que les trois soient effectivement présents sur les rails, qu'ils arrivent et partent à l'heure, ça ferait du bien pour la productivité du pays.

Cette beauté se trouve ici : http://www.penguintutor.com/projects/pixel-server


Installation

Bon, cela a fini par tomber en marche. Il y a un script d'installation ici qui n'a pas marché pour moi. En lisant le script j'ai vaguement compris que deux ou trois fichiers été générés, je ne commente pas plus, je vais juste indiquer ce que j'ai fait.

Dans le dossier /portainer/Files/AppData/Congi/pixel-server j'ai créé trois fichiers :

  • auth.cfg

  • pixelserver.cfg

  • user.cfg (ce fichier est vide)

Dans le fichier auth.cfg j'ai ajouté la ligne suivante :

network_allow_auth = 0.0.0.0

Et dans le fichier pixelserver.cfg j'ai ajouté les lignes suivantes :

ledcount=16

gpiopin=18

ledfreq=800000

leddma=5

ledmaxbrightness=50

ledinvert=False

ledchannel=0

striptype=RGB

## GRB

algorithm=Argon2

Je conseille aussi de limiter la luminosité avec le paramètre ledmaxbrightness afin de ne pas trop tirer de courant sur les petites papattes de la cartounette.

Postinstallation !

Une fois que le container est lancé, pendant qu'il fonctionne, il faut ajouter un utilisateur avec la commande suivante (remplacez user par un nom d'utilisateur et password par un mot de passe) :

sudo docker exec -it pixel-server sh -c 'python3 createadmin.py <user> <password> >> users.cfg'

Ensuite relancez le container avec l'interface de portainer et rendez-vous à l'adresse ip de la carte sur le port 85 par exemple.

Il faudra se signer en utilisant le user password défini plus haut et enfin il sera possible de bénéficier de ce superbe site ouaibe permettant de gérer les LEDs.


Le site dispose aussi d'une partie Settings qui permet de définir de nombreux paramètres.

Encore une fois : ce n'est pas très joli mais cela à le mérite de fonctionner.

Pour info, si un paramètre modifié ne semble rien changer, redémarrez le container !

Onlusion*

Il y a quelques semaines je me suis posé la question de la pertinence d'utiliser le Logitech Media Server (le serveur audio) ou Squeezelite (le client audio) dans un container.

J'étais incapable d'imaginer sur quoi cela allait déboucher. Ce n'est que le début du voyage, mais je trouve que cela vaut vraiment le coup d'installer Docker + Container sur la Raspberry Pi Zero 2 (ou les autres cartes).

Cela permet de mettre en oeuvre de nombreux containers supplémentaires auxquels on ne peux pas penser a priori. En l'occurrence, Le pixel-server, jamais je n'aurai pu imaginer passer une petite heure à installer ce container. Je suis persuadé ne pas être au bout de mes surprises et je suis ravi de pouvoir partager tout ça avec le lectorat du site.

Le point de néopixel ring s'inscrit dans un projet un petit peu plus grand dont nous reparlerons dans les jours qui viennent, on procède par étape. Il faudra revenir lire le site pour connaître la suite !

*Je sais, il manque du c à Onlusion pour que ça fasse Conclusion, mais on avait dit qu'on faisait un article de ohon !