Contrôler l'affichage des LEDs
Le jeu SNAKE que nous allons développer dans cette série d'activités se basera sur une matrice 8x8 de Ws1228b (LED RVB intelligente) pilotées par le GPIO du Raspberry pi.

Les Ws2812b (NeoPixel)
Les Ws2812b appelée NeoPixel sont en fait des LED RVB que l'on peut contrôler numériquement à l'aide d'une liaison série. Cette liaison série nécessite donc un organe de traitement de l'information tel qu'un microcontrôleur ou un MiniPC. Dans cette activité c'est le Raspberry qui se chargera de dialoguer avec les LEDs.
Sur la photo ci-contre on peut apercevoir les 3 LEDs sur le côté gauche reliées par des fils en or au composant chargé de l'interface entre la liaison série et les LEDs RVB. L'intérêt majeure de ces composants est de pouvoir être montées en cascade. L'interface de contrôle ne nécessitera toujours que d'un seul fil pour les données en plus de l'alimentation (5V). Chaque LED consomme 60mA.

Pour transmettre un état logique, L'infromation est condée dans la durée des impulsions qui correspond à trois états : 1, 0 ou Reset :

L'utilisation en cascade de ces éléments permet de garder le même nombre de broches pour piloter un nombre important de module :

Les données sont envoyées par paquet de 24bits en série sur D1. Le premier paquet est pour PIX1, le second pour PIX2 etc... .Quand PIX1 reçoit le premier paquet il le lit. Quand il reçoit le deuxième il le re-transmet à PIX2 idem pour le troisième paquet jusqu'à un signal de reset.
Chaque paquet de 24 bits contient le codage des couleurs (RGB classique)
Emulation
Ne disposant pas (pour l'instant !) de ce type de matrice au labo SIN, nous utiliserons un émulateur développé par Tristan Colombo pour le hors série N°2 de la revue Hackable. En python, cet émulateur est un module que l'on importe (voir TP1) en début de programme :
from vrtneopixel import *
Un point rouge !
Dans un premier temps nous allons tester le petit programme suivant permettant d'éclairer le premier pixel (en haut à gauche) en rouge :
"""Affichage d'un point rougeDate : 29/10/2017"""from vrtneopixel import *
import time
# Variables de configuration de l'ecranLED_COUNT = 64
LED_PIN = 18
LED_FREQ_HZ = 800000
LED_DMA = 5
LED_BRIGHTNESS = 8
LED_INVERT = False
# Creation d'un element permettant de piloter# l'ecran de LEDstrip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS)
# initialisation de l'ecranstrip.begin()
#Affichage de la première led en rougestrip.setPixelColor(0,Color(255,0,0))
strip.show()
#Attendre 10stime.sleep(10)
Appréciez La lisibilité ! Des espaces ont été ajouté à certains endroits pour permettre par exemple d'aligner les affectations des variables de configuration autour du signe '='. Les commentaires sont précédés en python du symbole '#'. Pour insérer des commentaires multi-lignes 3 apostrophes (ou guillemets) en début et en fin de bloc.
Notez bien que toute chaîne isolée est considérée comme un commentaire et n'est donc pas exécutées. Exemple :
" Commentaires "'Commentaires'Les variables de configuration permettent de spécifier différentes grandeur en fonction du hardware, principalement du type de matrice de LED que l'on utilise. Dans notre contexte on se base sur un écran de 8x8=64 LEDs. LED_COUNT est donc initialisé à 64. LED_PIN correspond au numéro de la broche du GPIO du raspberry utilisé. LED_FREQ_HZ correspond à la fréquence de transmission d'un bit (800kHz dans notre cas) et est liée au type de LED que l'on utilise. LED_BRIGHTNESS correspond à la luminosité (max à 255). LED_INVERT est à False indique que l'on transmet bien les données dans le sens RGB et non BGR (sur certaines LED c'est le cas).
L'appel à la fonction Adafruit_NeoPixel avec tous ces paramètres d'entrée, nous renvoie un objet nommé strip. L'appel (obligatoire avant de passer à autre chose) à la méthode strip.begin() permet d'initialiser l'écran. L'autre méthode strip.setPixelColor() permet d'instancier la led en position 0 à la couleur rouge (R=255,G=0,B=0). Les LEDs étant numéroté de 0 (en haut à gauche) à 63 (en bas à droite). strip.show() permet de mettre à jour l'état des LEDs dés son appel. Tant qu'il n'est pas invoqué les LEDs ne changent pas d'état.
La dernière ligne met le programme en attente pendant 10s.
Au lancement de ce programme dans l'éditeur de python vous devriez voir apparaître le point rouge !

En guise d’entraînement, vous pouvez ajouter quelques lignes au programme pour lui permettre de s'éteindre au bout de 10s, sans regarder la solution qui suit.
#Extinction de la première led strip.setPixelColor(0,Color(0,0,0))
strip.show()
Une ligne rouge !
Pour afficher une ligne rouge on pourrait faire un copier-coller sept fois de la fonction strip.setPixelColor(0,Color(0,0,0)) et changer le premier paramètre mais ce n'est pas très esthétique. Pour réduire l'écriture de la solution on utilisera un nouvel objet : la liste ! Pour cela on va se faire la main dans le prompt de python et créer une liste de nombres entiers :

La liste est affectée par les éléments entre crochets séparés par une virgule. On remarque ainsi que pour accéder à un élément n d'une liste de N éléments il suffit de faire liste[n] avec n pouvant varier de 0 à N-1. (Un peu comme les suite en mathématiques).
On peut remplir une liste d'éléments de type complètement différents :

Pour changer un élément d'une liste :

Pour ajouter un élément il faut utiliser la méthode append()

On peut créer une liste vide et y ajouter petit à petit les données :

Une autre manière d'initialiser une liste de 10 éléments à 0 (sans avoir à trop se fatiguer ...)

Pour parcourir toutes ces liste rien de tel que la boucle for. Une manière classique d'utiliser cette instruction et d'utiliser la fonction range(n) en écrivant par exemple :
n = 10
for i in range(n):
Elle se lit ainsi : pour i allant de 0 à n-1. Pour plus de clarté essayez l'exemple suivant sur le prompt :

Le for doit toujours finir par :.
Après ces deux points on commence un nouveau bloc et toutes les lignes qui suivront devront être indentées (on appui sur TAB) . C'est ce bloc indenté qui est répété 10 fois.
On saisit ensuite l'instruction print(i) on appui sur la touche Entrée
On tape à nouveau sur la touche Entrée pour indiquer la fin du bloc
Nous allons créer un nouveau programme python à partir du précédent en insérant d'abord :
leds = 64 * [Color(0,0,0)]
Qui initialise une liste de 64 éléments de couleur noir. Pour affecter le 8 premiers éléments on pourra ensuite insérer :
for i in range(8):
leds[i] = Color(255,0,0)
Pour changer la couleur des 64 pixels du strip on pourra enfin afficher :
# Affichage de l'écranfor i in range(64):
strip.setPixelColor(i,leds[i])
strip.show()
On attend ensuite 10 secondes pour ensuite éteindre la ligne. Il faudra changer la couleur pour les 8 leds en noir et afficher le résultat. Le programme complet (à regarder après s'être vraiment investi dans la recherche de solution).
"""Affichage d'une ligne rougeDate : 29/10/2017"""from vrtneopixel import *
import time
# Variables de configuration de l'ecranLED_COUNT = 64
LED_PIN = 18
LED_FREQ_HZ = 800000
LED_DMA = 5
LED_BRIGHTNESS = 8
LED_INVERT = False
# Creation d'un element permettant de piloter# l'ecran de LEDstrip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS)
# initialisation de l'ecranstrip.begin()
leds = 64 * [Color(0,0,0)]
# Alternative : leds[0:7] = 8*[Color(255,0,0)]for i in range(8):
leds[i] = Color(255,0,0)
# Affichage de l'écranfor i in range(64):
strip.setPixelColor(i,leds[i])
strip.show()
#Attendre 3stime.sleep(3)
leds = 64 * [Color(0,0,0)]
# Affichage de l'écranfor i in range(64):
strip.setPixelColor(i,leds[i])
strip.show()
Un cadre rouge
A partir du programme d'affichage d'une ligne rouge, vous pouvez maintenant créer un nouveau programme permettant l'allumage de tout le cadre.
En résumé ...
Le module vrtneopixel nous a permis de se passer de la matrice de LED RGB tout en gardant les principes de mise en œuvre.
Le caractère # nous permet de commenter un programme (""" Commentaires multi-lignes """)
Après avoir bien configurer et initialiser l'objet du module (begin()) on peut éclairer une led avec setPixelColor(n,Color(red,green, blue)) où n est la position de la led et red, blue et green sont des entiers compris entre 0 et 255 représentant la quantité de rouge de vert et de bleu.
show() met l'écran à jour.
Pour créer une boucle en Python on peut utiliser for
La fonction range(fin) permet de fournir des entier en 0 et fin-1.
la fonction range(debut,fin) permet de fournir des entiers en debut et fin-1.
Un nouveau bloc d'instruction commence par le caractère : puis la ou les lignes du bloc sont indentées d'un niveau plus bas.

