Outils pour utilisateurs

Outils du site


issue171:micro-ci_micro-la

This month, we will be talking about using the WS2812 Integrated Light Source on the Raspberry Pi Pico, and on the ESP32 and ESP8266 microcontrollers. The sharp-eyed among you who are good and loyal readers, might be thinking that, last month, I said we would be talking about NeoPixels. You are correct. I did. And we are. NeoPixels is a brand name that belongs to Adafruit. It stands for the individually addressable RGB color LEDs; strips all based on the WS2812 and WS2811 LED with drivers that use a single wire protocol. So, TECHNICALLY, not all WS2812 LEDs are NeoPixel displays. The ESP32 and ESP8266 microcontrollers both have a driver that is included in the distribution of MicroPython. For the Raspberry Pi Pico, the communications to the LEDs needs to be done via PIO programming - Raspberry Pi’s assembly language. Luckily, there is a library available for the Pico to handle the communications. You can find it at: https://github.com/benevpi/pico_python_ws2812b. This library works very well, but has been forked and updated. However, the new libraries don’t work correctly from the Thonny IDE, and it’s a real pain to write your code, and then try to run your file outside of the IDE. We’ll use the ws2812b library for now.

Ce mois-ci, nous allons parler de l'utilisation de la source lumineuse intégrée WS2812 sur le Raspberry Pi Pico et sur les microcontrôleurs ESP32 et ESP8266. Les plus attentifs d'entre vous, qui sont de bons et loyaux lecteurs, pensent peut-être que, le mois dernier, j'ai dit que nous parlerions des NeoPixels. Vous avez raison. Je l'ai dit. Et nous en parlons.

NeoPixels est une marque qui appartient à Adafruit. Elle désigne les LEDs de couleur RVB adressables individuellement ; des bandes toutes basées sur les LEDs WS2812 et WS2811 avec des pilotes qui utilisent un protocole à fil unique. Donc, TECHNIQUEMENT, toutes les LED WS2812 ne sont pas des afficheurs NeoPixel.

Les microcontrôleurs ESP32 et ESP8266 ont tous deux un pilote qui est inclus dans la distribution de MicroPython. Pour le Raspberry Pi Pico, la communication avec les LEDs doit se faire via la programmation PIO - le langage d'assemblage du Raspberry Pi. Heureusement, il existe une bibliothèque disponible pour le Pico qui gère les communications. Vous pouvez la trouver à l'adresse suivante : https://github.com/benevpi/pico_python_ws2812b. Cette bibliothèque fonctionne très bien, mais elle a été forkée et mise à jour. Cependant, les nouvelles bibliothèques ne fonctionnent pas correctement à partir de l'IDE de Thonny et c'est une véritable souffrance d'écrire votre code, puis d'essayer d'exécuter votre fichier en dehors de l'IDE. Nous utiliserons la bibliothèque ws2812b pour le moment.

Setting up your breadboard NeoPixel type devices take a good bit of power. If you are using only a single LED, then it’s not too big of a deal, but if you have 8, 24, 30 or 60 LEDs, you will need an external power source of about 5 volts DC. I say about 5 volts, since 5 volts is the absolute maximum voltage you should provide to the NeoPixel type devices. The current requirement of multiple LEDs is surprising, and if you attempt to use the USB power to drive the LEDs, it will quickly become too high for the PC to provide. I use a 3 x AA rechargeable battery pack for my setup, with NIMH (Nickel Metal Hydride) batteries. This provides about 4.6 volts (1.2 volts each) of power when the batteries are fully charged. This is low enough to provide enough, but not too much, power.

Configurer votre planche d'essai

Les dispositifs de type NeoPixel prennent une bonne quantité d'énergie. Si vous n'utilisez qu'une seule LED, ce n'est pas un gros problème, mais si vous avez 8, 24, 30 ou 60 LEDs, vous aurez besoin d'une source d'alimentation externe d'environ 5 volts DC. Je dis environ 5 volts, car 5 volts est la tension maximale absolue que vous devez fournir aux dispositifs de type NeoPixel. Les besoins en courant de plusieurs LEDs sont surprenants, et si vous essayez d'utiliser l'alimentation USB pour alimenter les LEDs, cela deviendra rapidement trop élevé pour le PC.

J'utilise un pack de piles rechargeables 3 x AA pour mon installation, avec des piles NIMH (Nickel Metal Hydride). Elles fournissent une alimentation d'environ 4,6 volts (1,2 volts chacune) lorsque les piles sont complètement chargées. C'est une alimentation suffisamment faible mais suffisante, sans trop.

While the connections for the RPi Pico and the ESP32/8266 are very similar, I will include one of each. In the illustrations, I will use a WS2812 8-LED stick. This stick has a fairly common set of connections that will easily work for the stick and most any flat strip, no matter the length and number of LEDs. All devices will have at least 3 input pins. Ground, +5 volt DC, and a pin for data in. No matter if you are using an 8-LED stick or a 1 metre 60-LED weatherproof strip, the connections are basically the same. As you can see in the image below, there are four inputs on each side of the stick. On the left, there are 2 for ground, one for data in and one for the +5 volt power. The right side has the same pins with the exception of Data Out, which is used (if needed) to add another stick. One other thing to note is that the breadboard images show a 3 x AAA battery pack. It should actually be a 3 x AA battery pack. I couldn’t find the actual image in Fritzing.

Bien que les connexions pour le RPi Pico et l'ESP32/8266 soient très similaires, je vais inclure un exemple de chaque. Dans les illustrations, j'utiliserai une barre de 8 LEDs WS2812. Cette barre a un ensemble de connexions assez commun qui fonctionnera facilement pour elle et la plupart des bandes plates, peu importe la longueur et le nombre de LEDs. Tous les appareils ont au moins 3 broches d'entrée : la masse, le +5 volt DC et une broche pour l'entrée des données. Peu importe que vous utilisiez une barre de 8 LEDs ou une bande étanche de 1 mètre de 60 LEDs, les connexions sont fondamentalement les mêmes.

Comme vous pouvez le voir sur l'image ci-dessous, il y a quatre entrées de chaque côté de la barre. Sur la gauche, il y en a 2 pour la masse, une pour les données et une pour l'alimentation +5 volts. Le côté droit a les mêmes broches à l'exception de Data Out, qui est utilisé (si nécessaire) pour ajouter une autre barre.

Une autre chose à noter, c'est que les images de la plaque d'essai montrent un pack de piles 3 x AAA. Il devrait en fait s'agir d'un pack de 3 piles AA. Je n'ai pas pu trouver la bonne image dans Fritzing.

Raspberry Pi Pico For the Pico, we put the 3 x AA battery pack to the + and minus rails of the bread board. The data-in pin of the LED stick is connected to physical pin 21, which is GPIO 16. The Ground and +5 volt pins of the stick are also connected to the power rails of the breadboard. Finally, be sure to connect the ground rail to a ground pin of the Pico. It is important that all devices share a common ground reference. ESP32/8266 The ESP series breadboard connections are very similar to the Pico. The main difference is where the ground and data pins are. You can use any ground pin for the ground, and any GPIO pin for the data pin. In the case of this image, I decided to use pin # 27 (GPIO 16) as the data pin and pin # 38 as the ground pin. You can use whatever pins you wish.

Raspberry Pi Pico

Pour le Pico, nous avons placé le pack de 3 piles AA sur les rangées + et - de la plaque d'essai. La broche d'entrée des données de la barre de LED est connectée à la broche physique 21, qui est le GPIO 16. Les broches de masse et de +5 volts de la barre sont également connectées aux rangées d'alimentation de la carte d'essai. Enfin, veillez à connecter la rangée de la masse à une broche de masse du Pico. Il est important que tous les appareils partagent une référence de masse commune.

ESP32/8266

Les connexions de la plaque d'essai de la série ESP sont très similaires à celles du Pico. La principale différence réside dans l'emplacement des broches de masse et de données. Vous pouvez utiliser n'importe quelle broche de masse pour la masse, et n'importe quelle broche GPIO pour la broche de données. Dans le cas de cette image, j'ai décidé d'utiliser la broche n° 27 (GPIO 16) comme broche de données et la broche n° 38 comme broche de masse. Vous pouvez utiliser les broches que vous souhaitez.

The Code Raspberry Pi Pico First, download the repository from the github site above. Save it to a convenient folder and unzip it. Then copy the file ws2812b.py to the pico as well as the example files. We’ll look at the flash.py example first. import time from ws2812b import ws2812b Now we’ll take a look at the first two lines of code. The first sets the number of LEDs that you have on your device. Be sure that it matches the number of LEDs that you really have. Many stick type displays have only 8 LEDs. Some strips have 30 to 60 on them. The ring that I have has 24 LEDs.

Le code

Raspberry Pi Pico

Tout d'abord, téléchargez le dépôt à partir du site github ci-dessus. Enregistrez-le dans un dossier approprié et décompressez-le. Copiez ensuite le fichier ws2812b.py sur le pico ainsi que les fichiers d'exemple.

Nous allons d'abord examiner l'exemple flash.py.

import time

from ws2812b import ws2812b

Maintenant nous allons regarder les deux premières lignes de code. La première définit le nombre de LEDs que vous avez sur votre appareil. Assurez-vous que cela correspond au nombre de LEDs que vous avez réellement. Beaucoup d'afficheurs de type barre n'ont que 8 LEDs. Certaines bandes en ont de 30 à 60. L'anneau que j'ai a 24 LEDs.

The second line instantiates the ws2812b class into the variable pixels. Notice that the first parameter is the number of LEDs, the second is the state machine that will be used. This is normally either a 0 or a 1. The next parameter is the GPIO pin number. The last is the delay that you want to use before resetting the LED set. It should be safe to use 0, unless you need to do a lot of processing. num_leds = 24 pixels = ws2812b(num_leds, 0, 16, delay=0) Next comes the brightness value. This can be useful if you are like me, and the LEDs blind you because they are so bright. The next two lines fill every LED on your device to 10,10,10 (R,G,B values) and then the information is sent out to the LED device with the pixels.show() command. pixels.brightness(30) pixels.fill(10,10,10) pixels.show()

La deuxième ligne instancie la classe ws2812b dans la variable pixels. Remarquez que le premier paramètre est le nombre de LED, le second est la machine d'état qui sera utilisée. Il s'agit normalement d'un 0 ou d'un 1. Le paramètre suivant est le numéro de la broche GPIO. Le dernier est le délai que vous souhaitez utiliser avant de réinitialiser le jeu de LEDs. Il vaut mieux utiliser 0, sauf si vous avez besoin de faire beaucoup de traitement.

num_leds = 24

pixels = ws2812b(num_leds, 0, 16, delay=0)

Ensuite vient la valeur de la luminosité. Cela peut être utile si vous êtes comme moi et que les LED vous aveuglent parce qu'elles sont trop lumineuses. Les deux lignes suivantes remplissent chaque LED de votre appareil à 10,10,10 (valeurs R, G, B) et ensuite l'information est envoyée au périphérique LED avec la commande pixels.show().

pixels.brightness(30)

pixels.fill(10,10,10)

pixels.show()

At this point, we set up a simple loop (above) and for each LED that you have set up at the beginning of the code, which sets the color. Then it sends the data out and pauses for a little bit. Now, the code might look fairly easy until you get to the set_pixel line. Here (below) is the actual function from the library. It makes it much easier to understand what’s happening. You can see that the set_pixel function takes 4 parameters. The pixel number, and the red, green and blue values. So going back to the loop above, we can step through the code and see the values that are being sent to the LED device. I’ll show only 7 values, which should give you a good idea of what happens. 0 0 3 6 1 1 4 7 2 2 5 8 3 3 6 9 4 4 7 0 5 5 8 1 6 6 9 2 … When we run the program, all the LEDs will blink different colors in a quickly changing pattern.

À ce stade, nous mettons en place une simple boucle (en haut) qui, pour chaque LED que vous avez configurée au début du code, définit la couleur. Ensuite, elle envoie les données et s'arrête un peu.

Le code peut sembler assez simple jusqu'à ce que vous arriviez à la ligne set_pixel. Voici (ci-dessous) la vraie fonction tirée de la bibliothèque. Elle permet de comprendre beaucoup plus facilement ce qui se passe.

Vous pouvez voir que la fonction set_pixel prend 4 paramètres. Le numéro du pixel, et les valeurs rouge, verte et bleue.

En revenant à la boucle ci-dessus, nous pouvons parcourir le code et voir les valeurs qui sont envoyées au dispositif de LED. Je ne vais montrer que 7 valeurs, ce qui devrait vous donner une bonne idée de ce qui se passe.

0 0 3 6 1 1 4 7 2 2 5 8 3 3 6 9 4 4 7 0 5 5 8 1 6 6 9 2 …

Lorsque nous exécutons le programme, toutes les LEDs clignotent de différentes couleurs dans un schéma qui change rapidement.

The other example program I want to point out is the fireflies.py program. It is supposed to simulate the flitting of fireflies on a summer’s evening. I have to admit that it is more impressive on a 1 metre 30+ LED strip than on the 8-LED strip. import time import ws2812b import random numpix = 24 # Number of NeoPixels # Pin 16 is where NeoPixels are connected strip = ws2812b.ws2812b(numpix, 0, 16) Remember to set the number of LEDs that your device has as well as the GPIO pin that the device is connected to.

L'autre exemple de programme que je veux signaler est le programme fireflies.py. Il est censé simuler le vol des lucioles un soir d'été. Je dois admettre qu'il est plus impressionnant sur une bande de 1 mètre de 30 LEDs ou plus que sur la bande de 8 LEDs.

import time

import ws2812b

import random

numpix = 24 # Nombre de NeoPixels

# La broche 16 est celle où les NeoPixels sont connectées

strip = ws2812b.ws2812b(numpix, 0, 16)

N'oubliez pas de définir le nombre de LEDs que votre dispositif possède ainsi que la broche GPIO à laquelle le dispositif est connecté.

colors = [ [232, 100, 255], # Purple [200, 200, 20], # Yellow [30, 200, 200], # Blue [150,50,10], [50,200,10], ] Here (top right) max_len and min_len is the maximum and minimum length of time the LEDs are on. The num_flashes refers to the number of “fireflies” that are active at one time. This is the display function that handles the glowing and flitting of the virtual flies (which are actually beetles in real life). Shown bottom right. Most of the demo programs that I have found have similar loops as the above two programs. And they have a similar while loop that, when stopped, the LEDs are still active. So I wrote the following short program to clear the LEDs when I’m done with the demo. I call it led_clear.py

colors = [

[232, 100, 255], # violet
[200, 200, 20], # Jaune
[30, 200, 200], # Bleu
[150,50,10],
[50,200,10],

]

Ici (en haut à droite) max_len et min_len sont les durées maximale et minimale d'allumage des LEDs. « num_flashes » fait référence au nombre de « lucioles » qui sont actives à un moment donné.

Il s'agit de la fonction d'affichage qui gère le scintillement et le vol ici et là des mouches virtuelles (qui sont en fait des coléoptères dans la vie réelle). Voir en bas à droite.

La plupart des programmes de démonstration que j'ai trouvés ont des boucles similaires à celles des deux programmes ci-dessus. Et ils ont une boucle while similaire qui fait que, lorsqu'ils sont arrêtés, les LED sont toujours actives. J'ai donc écrit le petit programme suivant pour éteindre les LED quand j'en ai fini avec la démo. Je l'ai appelé led_clear.py

# LED Clear from ws2812b import ws2812b num_leds = 24 pixels = ws2812b(num_leds, 0, 16, delay=0) pixels.brightness(100) pixels.fill(0,0,0) pixels.show() ESP32/ESP8266 My initial thought was to rewrite the flash program presented for the Pico to work on the ESP microcontrollers. However, I remembered that I had a great demo from randomnerdtutorials.com that would provide a better example of how to use the library. So, instead of flash, I present neopixel1.py (top right). The same code should run unmodified on the ESP8266, since they share the same library.

# Extinction des LED

from ws2812b import ws2812b

num_leds = 24

pixels = ws2812b(num_leds, 0, 16, delay=0)

pixels.brightness(100)

pixels.fill(0,0,0)

pixels.show()

ESP32/ESP8266

Mon idée initiale était de réécrire le programme flash présenté pour le Pico afin qu'il fonctionne sur les microcontrôleurs ESP. Cependant, je me suis souvenu que j'avais une excellente démo venant de randomnerdtutorials.com qui peut fournir un meilleur exemple de la façon d'utiliser la bibliothèque. Donc, au lieu de flash, je présente neopixel1.py (en haut à droite). Le même code devrait fonctionner sans modification sur l'ESP8266, puisqu'ils partagent la même bibliothèque.

Notice that the library for the neopixel devices is named “neopixel”. The variable n is the number of LEDs the device has, and the variable p is the GPIO pin that will be used. So the variable np is the neopixel object. You need to address each pixel individually and pass the RGB values as a tuple. You can see this in the clear function presented directly below. def clear(): for i in range(n): np[i] = (0, 0, 0) np.write() The next function (middle right) is called bounce, which, as you might expect, causes a single LED to move through each available position and, when it gets to the starting point, it reverses direction.

Remarquez que la bibliothèque pour les dispositifs neopixel est nommée « neopixel ». La variable n est le nombre de LED que possède le dispositif, et la variable p est la broche GPIO qui sera utilisée.

La variable np est donc l'objet neopixel. Vous devez adresser chaque pixel individuellement et transmettre les valeurs RVB sous forme de tuple. Vous pouvez voir cela dans la fonction clear présentée directement ci-dessous.

def clear() :

for i in range(n) :
  np[i] = (0, 0, 0)
  np.write()

La fonction suivante (au milieu à droite) s'appelle bounce, qui, comme on peut s'y attendre, fait passer une seule LED par chaque position disponible et, lorsqu'elle arrive au point de départ, elle inverse la direction.

The set_color function, again, does as the name suggests. It sets all the pixels (defined in n) to the RGB color at the brightness you desire. def set_color(r, g, b, brightness): for i in range(n): np[i] = (int(r*brightness), int(g*brightness), int(b*brightness)) np.write() The cycle function (bottom right) will cause a single LED to light and walk through the strip at the defined color and brightness, at a defined speed. The next function, wheel (next page, top right), is a support function used by the rainbow_cycle function below.

La fonction set_color, encore une fois, fait ce que son nom suggère. Elle définit, pour tous les pixels (définis dans n), la couleur RVB et la luminosité que vous souhaitez.

def set_color(r, g, b, brightness) :

for i in range(n) :
    np[i] = (int(r*luminosité), int(g*luminosité), int(b*luminosité))
np.write()

La fonction cycle (en bas à droite) permet d'allumer une seule LED ; la couleur et la luminosité définies parcourent toute la bande, à une vitesse définie.

La fonction suivante, wheel (page suivante, en haut à droite), est une fonction de support utilisée par la fonction rainbow_cycle ci-dessous.

Now that we have all of the functions defined, we’ll walk through each of them, one at a time. We’ll print to the REPL terminal which function is being run. print('Clear') clear() print('Set Color') set_color(0,102,.5,230) time.sleep(2) clear() print('Cycle') cycle(0,102,230,.5,200) print('Bounce') bounce(0,255,250,.5,200) clear() time.sleep(2) print('Rainbow Cycle') rainbow_cycle(.5,5) clear() print('Program Ends')

Maintenant que nous avons défini toutes les fonctions, nous allons les passer en revue, une par une. Nous allons indiquer au terminal REPL quelle fonction est exécutée.

print('Éteindre')

clear()

print('Mettre la couleur')

set_color(0,102,.5,230)

time.sleep(2)

clear()

print('Cycle')

cycle(0,102,230,.5,200)

print('Rebonds')

bounce(0,255,250,.5,200)

clear()

time.sleep(2)

print('Cycle de l'arc-en-ciel')

rainbow_cycle(.5,5)

clear()

print('Fin du programme')

It should be fairly easy to understand how the program actually works. I’ve included on the github repository a port of the fireflies program for the ESP called fireflies1.py. As an added benefit, I’ve added a small call to the Touchpad function we discussed previously that will break the forever loop when the touchpad is detected. All of the code and image files can be found at https://github.com/gregwa1953/FCM171_MicroThisMicroThat . I sincerely hope that I have inspired you to get some NeoPixel type devices and play with them. After all (as if I needed to give you a reason), Christmas, Hanukkah, and the rest of the festive holiday season celebrations are less than 6 months from now. Just picture what these little devices can do for your decorations this year and how jealous your neighbors will be. Until next time, as always; stay safe, healthy, positive and creative!

Il devrait être assez facile de comprendre comment le programme fonctionne vraiment. J'ai inclus dans le dépôt github un portage du programme fireflies pour l'ESP appelé fireflies1.py. En prime, j'ai ajouté un petit appel à la fonction Touchpad dont nous avons parlé précédemment qui interrompra la boucle éternelle lorsqu'une touche sur la plaque sera détectée.

L'ensemble du code et les fichiers images se trouvent à l'adresse https://github.com/gregwa1953/FCM171_MicroThisMicroThat .

J'espère sincèrement que je vous ai donné envie de vous procurer des appareils de type NeoPixel et de jouer avec. Après tout (comme si j'avais besoin de vous donner une raison), Noël, Hanoucca et le reste des célébrations de la saison des fêtes sont dans moins de 6 mois. Imaginez ce que ces petits appareils peuvent faire pour vos décorations cette année et combien vos voisins seront jaloux.

Jusqu'à la prochaine fois, comme toujours, restez en sécurité, en bonne santé, positif et créatif !

issue171/micro-ci_micro-la.txt · Dernière modification : 2021/08/06 10:16 de auntiee