Différences entre versions de « RASP-FT232H-MPSSE-Usage-SPI »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(5 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
 
{{RASP-FT232H-NAV}}
 
{{RASP-FT232H-NAV}}
 
{{traduction}}
 
  
 
== FT232 en mode Bus SPI ==
 
== FT232 en mode Bus SPI ==
Ligne 68 : Ligne 66 :
  
 
== Contrôler des NeoPixels avec SPI ==
 
== Contrôler des NeoPixels avec SPI ==
One interesting use of the SPI protocol is driving the colors of WS2811/WS2812 NeoPixel addressable RGB LEDs. These LEDs don't actually use SPI to communicate, instead they have a [https://learn.adafruit.com/adafruit-neopixel-uberguide/advanced-coding#writing-your-own-library very specific self-clocked signal] for sending pixel color bits. However by using a high speed 6Mhz SPI signal we can 'oversample' the NeoPixel control signal and generate a close approximation of it from the D1 (MOSI) line of the FT232H.
+
Un des intérêt d'utiliser le protocole SPI est qu'il permet de contrôler des {{cl|487|LEDs Neopixels}} (Leds digitales RGB adressable à base de WS2811/WS2812). Ces LEDs n'utilisent pas le bus SPI pour communiquer. A la place, ces LEDs utilisent [[NeoPixel-UserGuide|un signal très spécifique réclament une grande maîtrise des temps d'émission]] pour envoyer les informations de couleur (les différents bits) des différents LEDs du ruban. Cependant, en utilisant un signal SPI à haute vitesse (6Mhz) il est possible de 'sur-échantillonner' le signal de contrôle NeoPixel et de générer une approximation suffisamment proche sur la ligne D1 (MOSI) du FT232H.
 +
 
 +
{{ambox-stop|text=Cette méthode de pilotage parmet de prendre le contrôle d'un nombre limité de pixels (environ 340 pixels).}}
  
Note that this method of driving NeoPixels is limited to lighting about 340 pixels at a time.  This limitation comes from the maximum amount of data that can be sent to the FT232H at one time over the USB bus, about 64 kilobytes of data. Because we're oversampling the NeoPixel control signal each pixel actually takes 24*8 bytes of SPI data (or one byte of SPI data for every bit of pixel data).
+
La limitation du nombre de pixel contrôlable est fixé par la quantité maximale d'information qui peut être envoyer en une fois sur le FT232H via le bus USB. Cette limite est d'environ 64 kilobytes (Kilo Octets). Etant donné que nous faisons du sur-échantillonnage du signal de contrôle NéoPixel, chaque pixel requière 24*8 octets/bytes de donnée SPI (ou un octet/byte de donnée SPI pour chaque bit de donnée NéoPixel).
  
To demonstrate lighting NeoPixels with the FT232H breakout you'll need the following parts:
+
=== Matériel ===
* Assembled FT232H breakout board.
+
Vous aurez besoin des éléments suivants pour tester l'utilisation de NeoPixel avec le breakout FT232H:
* NeoPixel strip, strand, matrix, etc.
+
* Un breakout FT232H assemblé.
** Remember at most you can only light about 340 pixels.
+
* Des NeoPixel (ruban, matrice, anneau, etc).<br />Rappelez vous que vous ne pouvez contrôler qu'environ 340 pixels.
* Strong 5 volt power supply to drive the NeoPixels.   
+
* Une alimentation 5 volts de qualité (bien régulée et capable de fournir le courant demandé).   
** Each pixel can take up to 60mA, so driving more than a handful of pixels can quickly add up to a few amps or more of current. '''Do not try to power more than a couple NeoPixels over the FT232H 5V line!'''
+
** Chaque LED consomme jusqu'à 60mA (100% blanc). Cela représente vite plusieurs ampères (ou plus) si vous accumulez des Pixels. '''N'essayer pas d'alimenter plus de quelques pixels sur la lignes 5V du FT232H !'''
* Level converter chip to convert 3.3 to 5 volts '''OR''' a power diode that can handle the full power of all the NeoPixels.
+
* Une {{pl|1041|puce convertisseur de niveau logique pour convertir le signal 3.3V vers 5 volts}} '''-OU-''' Une diode de puissance capable de supporter le total du courant d'alimentation des pixels.
** The NeoPixel control signal needs to be at least 0.7*Vcc (power supply voltage) which is just a little too high for the 3.3 volt output of the FT232H breakoutJust like [https://learn.adafruit.com/neopixels-on-raspberry-pi/wiring lighting NeoPixels with the Raspberry Pi] (''Adafruit, Anglais'') you need to either convert the control signal to 5 volts using a chip like the {{pl|1041|74AHCT125}}, or drop the NeoPixel power supply down slightly below 5 volts using a {{pl|46|power diode}}.
+
** Le signal de contrôle NeoPixel à besoin d'atteindre au moins 0.7*Vcc (tension d'alimentation), ce qui est juste un peu supérieur au signal de sortie 3.3V  (fourni par le breakout FT232H)Exactement comme dans ce tutoriel [https://learn.adafruit.com/neopixels-on-raspberry-pi/wiring lighting NeoPixels with the Raspberry Pi] (''Adafruit, Anglais'') ou l'on converti le signal de 3.3V en 5V à l'aide d'un {{pl|1041|74AHCT125}}. L'autre option est de faire chuter la tension d'alimentation des néopixel en dessous de 5V en utilisant une {{pl|46|diode de puissance}} de sorte que le signal de commande 3.3v soit suffisant.
* Jumper wires and breadboard.
+
* Des fils de connexion et breadboard.
  
In this example I'm lighting a 16 pixel ring so I'll use a power diode that can handle 1 amp of current. If you're using more than 16 NeoPixels you'll want a larger power diode, or a level converter chip.
+
=== Montage ===
 +
Dans cet exemple, nous allons éclairer un anneau NéoPixe à 16 LEDs et nous allons utiliser une diode de puissance capable de gérer un courant de 1 ampère. Si vous utilisez plus de 16 pixels, il faudra envisager une diode plus puissance (ou un convertisseur de niveau logique {{pl|1041|74AHCT125}} ).
  
Connect the hardware as follows:
+
Connectez le matériel comme suit:
* FT232H GND to power supply ground.
+
* La masse/GND du FT232H '''--vers-->''' la masse/GND de l'alimentation.
* FT232H D1 (MOSI) to NeoPixel signal input.
+
* FT232H D1 (MOSI) '''--vers-->''' le signal d'entrée NeoPixel.
* Power supply positive voltage to diode anode (side without the stripe).
+
* Alimentation Positive '''--vers-->''' Anode de la diode (le côté de la diode SANS la bande blanche).
* NeoPixel positive voltage to diode cathode (side with the stripe).
+
* Cathode de la diode (le côté de la diode AVEC la bande blanche) '''--vers-->''' le (+) des NeoPixels.
* NeoPixel ground to power supply ground.
+
* Le (-)/GND des NéoPixels '''--vers-->''' le (-)/GND de l'alimentation.
  
A picture of the hardware setup is below (note [[NeoPixel-UserGuide|I've added a large capacitor to the power supply as recommended in the NeoPixel Uberguide]]):
+
Voyez ci-dessous une photo du montage en question (note [[NeoPixel-UserGuide|une capacité est ajoutée sur l'alimentation comme recommandé dans le guide NeoPixel]]):
  
 
{{ADFImage|RASP-FT232H-MPSSE-Usage-SPI-00.jpg}}
 
{{ADFImage|RASP-FT232H-MPSSE-Usage-SPI-00.jpg}}
  
Now create a file neopixels.py and fill it with the following code:
+
=== Programmation ===
 +
Nous allons maintenant créer un fichier neopixels.py et y ajouter le code suivant:
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
Ligne 106 : Ligne 108 :
 
class NeoPixel_FT232H(object):
 
class NeoPixel_FT232H(object):
 
def __init__(self, n):
 
def __init__(self, n):
# Create an FT232H object.
+
# Creer l object FT232H.
 
self.ft232h = FT232H.FT232H()
 
self.ft232h = FT232H.FT232H()
# Create a SPI interface for the FT232H object. Set the SPI bus to 6mhz.
+
# Creer l interface SPI sur l objet FT232H. configurer le bus SPI a 6mhz.
 
self.spi    = FT232H.SPI(self.ft232h, max_speed_hz=6000000)
 
self.spi    = FT232H.SPI(self.ft232h, max_speed_hz=6000000)
# Create a pixel data buffer and lookup table.
+
# Creer un buffer de donnee pour les pixels et une table de correspondant (lookup table).
 
self.buffer = bytearray(n*24)
 
self.buffer = bytearray(n*24)
 
self.lookup = self.build_byte_lookup()
 
self.lookup = self.build_byte_lookup()
  
 
def build_byte_lookup(self):
 
def build_byte_lookup(self):
# Create a lookup table to map all byte values to 8 byte values which
+
# Creer une table de correspondance qui map toutes les valeurs en octet/bytes
# represent the 6mhz SPI data to generate the NeoPixel signal for the
+
# --VERS-- des valeurs 8 octet/byte qui represente les donnees SPI 6mhz
# specified byte.
+
# pour le signal neopixel pour l'octet/byte specifie
 +
#  
 
lookup = {}
 
lookup = {}
 
for i in range(256):
 
for i in range(256):
Ligne 130 : Ligne 133 :
  
 
def set_pixel_color(self, n, r, g, b):
 
def set_pixel_color(self, n, r, g, b):
# Set the pixel RGB color for the pixel at position n.
+
# Fixer la couleur RGB d'une pixel pour le Nieme position.
# Assumes GRB NeoPixel color ordering, but it's easy to change below.
+
# Fixe l ordre des couleurs sur GRB (vert rouge bleu) mais
 +
# cela est facilement modifiable ci-dessous.
 
index = n*24
 
index = n*24
 
self.buffer[index  :index+8 ] = self.lookup[int(g)]
 
self.buffer[index  :index+8 ] = self.lookup[int(g)]
Ligne 138 : Ligne 142 :
  
 
def show(self):
 
def show(self):
# Send the pixel buffer out the SPI data output pin (D1) as a NeoPixel
+
# Envoi le buffer de pixel sir la sortie SPI (broche D1) qui sera
# signal.
+
# percu par les Neopixels comme le signal de commande.
 
self.spi.write(self.buffer)
 
self.spi.write(self.buffer)
  
  
# Run this code when the script is called at the command line:
+
# Executer le code lorsque le script est appele en ligne de commande:
 
if __name__ == '__main__':
 
if __name__ == '__main__':
# Define the number of pixels in the NeoPixel strip.
+
# Definir le nombre de pixels utilisé.
# Only up to ~340 pixels can be written using the FT232H.
+
# Seul ~340 pixels peuvent être utilisé avec le FT232H.
 
pixel_count = 16
 
pixel_count = 16
# Create a NeoPixel_FT232H object.
+
# Creer un objet NeoPixel_FT232H.
 
pixels = NeoPixel_FT232H(pixel_count)
 
pixels = NeoPixel_FT232H(pixel_count)
# Animate each pixel turning red.
+
# Animation - allumer chaque pixel en rouge.
# Loop through each pixel.
+
# Passer chaque pixel en revue.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
# Set the pixel color to pure red.
+
# Changer la couleur du pixel en rouge pure.
 
pixels.set_pixel_color(i, 255, 0, 0)
 
pixels.set_pixel_color(i, 255, 0, 0)
# Show the pixel buffer by sending it to the LEDs.
+
# Envoyer le buffer (de pixel) vers les LEDs.
 
pixels.show()
 
pixels.show()
# Delay for a short period of time.
+
# faire une toute petite pause.
 
time.sleep(0.25)
 
time.sleep(0.25)
# Animate each pixel turning pure green.
+
# Animation - allumer chaque pixel en vert pure.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
pixels.set_pixel_color(i, 0, 255, 0)
 
pixels.set_pixel_color(i, 0, 255, 0)
 
pixels.show()
 
pixels.show()
 
time.sleep(0.25)
 
time.sleep(0.25)
# Animate each pixel turning pure blue.
+
# Animation - allumer chaque pixel en bleu pure.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
pixels.set_pixel_color(i, 0, 0, 255)
 
pixels.set_pixel_color(i, 0, 0, 255)
 
pixels.show()
 
pixels.show()
 
time.sleep(0.25)
 
time.sleep(0.25)
# Animate a pattern of colors marching around the pixels.
+
# Un modèle (pattern) de couleur qui se déplace le long des pixels.
# Create a pattern of colors to display.
+
# Creation du modele de couleur.
 
colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255),  
 
colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255),  
 
(0, 0, 255), (255, 0, 255) ]
 
(0, 0, 255), (255, 0, 255) ]
 
offset = 0
 
offset = 0
print 'Press Ctrl-C to quit.'
+
print 'Presser Ctrl-C pour quitter.'
 
while True:
 
while True:
# Loop through all the pixels and set their color based on the pattern.
+
# Passer tous les pixels en revue et fixer leur couleur en fonction du modèle.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
color = colors[(i+offset)%len(colors)]
 
color = colors[(i+offset)%len(colors)]
 
pixels.set_pixel_color(i, color[0], color[1], color[2])
 
pixels.set_pixel_color(i, color[0], color[1], color[2])
 
pixels.show()
 
pixels.show()
# Increase the offset to make the colors change position.
+
# Incrementer le decalage (offset) pour changer la position des differentes couleurs.
 
offset += 1
 
offset += 1
 
time.sleep(0.25)
 
time.sleep(0.25)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Save the file and navigate to the folder with it in a terminal, then execute the following in Windows to run the program:
+
Sauver le fichier. Utilisez un terminal et naviguez dans le répertoire contenant le fichier.
 +
 
 +
Exécutez ensuite la commande suivante dans le terminal:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Ligne 192 : Ligne 198 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Or on Mac OSX or Linux  execute the following to run the program as root:
+
Sur une machine Linux ou Mac OSX, il faut exécuter la commande en tant que root:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Ligne 198 : Ligne 204 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
Vous devriez voir les NeoPixels s'allumer et s'animer avec différentes couleurs.
  
 +
{{underline|note:}} vous pourriez avoir besoin de changer la valeur de la variable pixel_count dans la section "__main__" du programme pour que la valeur corresponde au nombre de pixels que vous avez dans votre montage.
  
You should see the NeoPixels light up and animate with different colors.  Note that you might need to change the pixel_count variable in the main part of the program to match the number of pixels in your NeoPixel strip, circle, matrix, etc.
+
Ce code réalise plusieurs opérations de haut-niveau. Il commence par définir une classe nommée NeoPixel_FT232H. Cette classe contient les méthodes et les états nécessaires à la génération du signal NeoPixelavec la carte FT232H. La seconde partie du code utilise la classe NeoPixel_FT232H pour animer les NéoPixels.
 
 
This code does a couple things at a high level. It first defines a class called NeoPixel_FT232H. This class contains some methods and state which control generating the NeoPixel signal with an FT232H board. The second part of the code uses the NeoPixel_FT232H class to animate the NeoPixels.
 
  
You actually don't need to fully understand the NeoPixel_FT232H class code to use it. This code performs the 'oversampling' by using a lookup table to expand each byte of color data into 8 bytes of SPI data that approximates the NeoPixel control signal. The only important thing to know about the NeoPixel_FT232H class is that it exposes a '''set_pixel_color()''' function which allows you to set the red, green, and blue color value of a pixel.
+
Il n'est pas vraiment nécessaire de comprendre le code de la classe NeoPixel_FT232H pour pouvoir l'utiliser. Le code effectue un 'sur-échantillonnage' en utilisant une table de correspondance qui étend chaque octet/byte de couleur en enchaînement de 8 octets/bytes de donnée SPI (ce qui permet de faire une approximation du signal de contrôle NeoPixel). La seule chose vraiment importante à savoir à propos de de la classe NeoPixel_FT232H c'est qu'elle expose la méthode '''set_pixel_color()''' qui permet d'assigner la couleur (red,green,blue = rouge,vert,bleu) pour chaque pixel.
  
Instead let's walk through a bit of the second half of the code that uses the NeoPixel_FT232H class:
+
Le plus intéressant se trouve dans la seconde partie du code, celle qui utilise la classe NeoPixel_FT232H:
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
# Run this code when the script is called at the command line:
+
# Python exécute le code ci-dessous lorsque le script est appelé en ligne de commande:
 
if __name__ == '__main__':
 
if __name__ == '__main__':
# Define the number of pixels in the NeoPixel strip.
+
# Défini le nombre de pixels utilisé dans le montage.
# Only up to ~340 pixels can be written using the FT232H.
+
# Capable de gérer jusqu'à environ 340 pixels via un FT232H.
 
pixel_count = 16
 
pixel_count = 16
# Create a NeoPixel_FT232H object.
+
# Créer un objet NeoPixel_FT232H.
 
pixels = NeoPixel_FT232H(pixel_count)
 
pixels = NeoPixel_FT232H(pixel_count)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This portion of code has an if statement that checks if the program is being run from the command line before executing.  This is just a standard Python idiom for defining the main entry point of a program.
+
Cette portion de code contient une commande {{fname|if}} qui vérifie si le programme est lancé en ligne de commande (ou inclus dans un autre programme).
  
Inside the if block you can see the number of pixels is defined and set in the pixel_count variable.  Then the NeoPixel_FT232H object is created by telling it that number of pixels as its only parameter.
+
C'est un idiom standard en python qui vérifie le mode de démarrage du script avant de l'exécuter.
  
 +
Dans le bloc {{fname|if}} you pouvez identifier la ligne qui définit le nombre de pixels (la valeur assignée à la variable ''pixel_count''). Ensuite, un objet NeoPixel_FT232H est créé en lui indiquant le nombre de LED disponibles).
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
# Animate each pixel turning red.
+
# Animation - allumer chaque pixel en rouge.
# Loop through each pixel.
+
# Passer chaque pixel en revue.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
# Set the pixel color to pure red.
+
# Changer la couleur du pixel en rouge pure.
 
pixels.set_pixel_color(i, 255, 0, 0)
 
pixels.set_pixel_color(i, 255, 0, 0)
# Show the pixel buffer by sending it to the LEDs.
+
# Envoyer le buffer (de pixel) vers les LEDs.
 
pixels.show()
 
pixels.show()
# Delay for a short period of time.
+
# faire une toute petite pause.
 
time.sleep(0.25)
 
time.sleep(0.25)
# Animate each pixel turning pure green.
+
# Animation - allumer chaque pixel en vert pure.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
pixels.set_pixel_color(i, 0, 255, 0)
 
pixels.set_pixel_color(i, 0, 255, 0)
 
pixels.show()
 
pixels.show()
 
time.sleep(0.25)
 
time.sleep(0.25)
# Animate each pixel turning pure blue.
+
# Animation - allumer chaque pixel en bleu pure.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
pixels.set_pixel_color(i, 0, 0, 255)
 
pixels.set_pixel_color(i, 0, 0, 255)
Ligne 245 : Ligne 252 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The next section performs a few simple animations that turn each pixel on with primary colors. You can see a loop is used to go through each pixel and the '''set_pixel_color()''' function is called to the pixel colorThis function takes 4 parameters, the first is the number of the pixel (start at 0), and the last 3 parameters are the red, green, and blue color components. Each component should be a value from 0 to 255, where 0 is no color and 255 is maximum color intensity.
+
La section suivante réalise quelques animations simples. Elles allument chaque pixel dans une couleur primaire à l'aide de la fonction '''set_pixel_color()'''.   
 +
 
 +
Cette fonction prend 4 paramètres:
 +
* Le premier est le n° du pixel à modifier (démarre à 0),  
 +
* Le deuxième est la quantité de ROUGE (valeur entre 0 et 255. 0 = pas de couleur, 255 = maximum d'intensité)
 +
* Le deuxième est la quantité de VERT
 +
* Le deuxième est la quantité de BLEU
 +
 
 +
Après chaque modification de Pixel, le code appelle la fonction '''show()'''. La fonction '''show()''' envoi l'état du buffer vers les NéoPixels. Nous avons donc une animation progressive du ruban.
  
After changing the pixel color, the '''show()''' function is called to send the colors to the LEDs.  You must call '''show()''' in order to make the NeoPixels light up with the colors you've set previously!
+
Il est impératif d'appeler '''show()''' pour rafraîchir les données de couleur dans le ruban NéoPixel!
  
Finally notice the '''time.sleep()''' function is used to delay for a short period of time (a quarter of a second in this case).  This sleep function is very useful for animating color changes that should go somewhat slowly.
+
Pour finir, notez que la fonction '''time.sleep()''' est utilisé pour créer un délai de 1/4 seconde. Cela permet de réaliser l'allumage progressif du ruban (sous forme d'animation).
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
# Animate a pattern of colors marching around the pixels.
+
# Un modèle (pattern) de couleur qui se déplace le long des pixels.
# Create a pattern of colors to display.
+
# Creation du modele de couleur.
 
colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255),  
 
colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255),  
 
(0, 0, 255), (255, 0, 255) ]
 
(0, 0, 255), (255, 0, 255) ]
 
offset = 0
 
offset = 0
print 'Press Ctrl-C to quit.'
+
print 'Presser Ctrl-C pour quitter.'
 
while True:
 
while True:
# Loop through all the pixels and set their color based on the pattern.
+
# Passer tous les pixels en revue et fixer leur couleur en fonction du modèle.
 
for i in range(pixel_count):
 
for i in range(pixel_count):
 
color = colors[(i+offset)%len(colors)]
 
color = colors[(i+offset)%len(colors)]
 
pixels.set_pixel_color(i, color[0], color[1], color[2])
 
pixels.set_pixel_color(i, color[0], color[1], color[2])
 
pixels.show()
 
pixels.show()
# Increase the offset to make the colors change position.
+
# Incrementer le decalage (offset) pour changer la position des differentes couleurs.
 
offset += 1
 
offset += 1
 
time.sleep(0.25)
 
time.sleep(0.25)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Finally the code enters an infinite loop where it animates a rainbow of colors marching across the pixels. This code uses the same '''set_pixel_color()''' function, but has a little extra logic to pick a color from a list and increase the offset of chosen colors every loop iteration. Also notice the '''show()''' function is again called after updating pixel colors in order to make the LEDs light up with the desired colors.
+
Pour finir, le code entre dans une boucle infinie qui anime un arc en clien progressant le long des pixels. Ce code utilise également la fonction '''set_pixel_color()''' mais avec une logique un peu plus élaborée qui sélectionne une couleur dans une liste de couleurs prédéfinies à chaque itération de la boucle.
 +
 
 +
Vous noterez également que la fonction '''show()''' est appelée pour faire une mise-à-jour du ruban avec la suite de couleur ainsi calculée.
 +
 
 +
La suite de couleur est décalée d'un pixel supplémentaire à chaque itération.
  
That's all there is to controlling NeoPixels with SPI from the FT232H breakout!  Feel free to use the code above in your own NeoPixel projects!
+
Voila, c'est tout ce qu'il est nécessaire de savoir pour contrôler des NéoPixels depuis le bus SPI du breakout FT232H!
  
 
{{RASP-FT232H-TRAILER}}
 
{{RASP-FT232H-TRAILER}}

Version actuelle datée du 19 mars 2017 à 15:15


MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.

FT232 en mode Bus SPI

Le FT232H en mode MPSSE est génial pour générer des signaux pour communiquer en utilisant le protocol SPI. Le MPSSE est capable de générer un signal d'horloge de 450hz (environ) à 30Mhz, et de lire et écrire des octets de données à cette fréquence. La bibliothèque Python GPIO qui a été installé inclus un "wrapper" autour de certaines fonctions MPSSE pour simplifier la lecture et l'écriture de donnée SPI.

En utilisant SPI avec le FT232H, les broches suivantes ont une signification spéciale:

  • D0 - SCK / Clock signal / Signal d'horloge : C'est le signal d'horloge qui indique aux périphériques quand échantilloner et écrire des données.
  • D1 - MOSI / Data Out / Sortie de donnée : ligne de sortie de donnée du FT232H vers le périphérique.
  • D2 - MISO / Data In / Entrée de donnée : ligne pour lire les données en provenance du périphérique connecté sur le FT232H.

Une chose à noter, c'est qu'il n'existe pas de broche chip select / enable explicite. Vous devriez utiliser une des broches GPIO libre comme signal chip select dédicacé. Vous devrez préciser cette broche lors de la création de l'objet SPI.

Vous aurez besoin de créer une instance de la classe Adafruit_GPIO.FT232H.SPI pour utiliser le bus SPI du FT232H sous Python:

import Adafruit_GPIO.FT232H as FT232H

# Désactiver temporairement le pilote FTDI série.
FT232H.use_FT232H()

# Trouver le premier périphérique FT232H.
ft232h = FT232H.FT232H()

# Créer une interface SPI du FT232H en utilisant la broche 8 (C0) comme signal ''chip select''.
# Utiliser une fréquence d'horloge de 3mhz, mode SPI 0 et le bit le plus significatif en premier.
spi = FT232H.SPI(ft232h, cs=8, max_speed_hz=3000000, mode=0, bitorder=FT232H.MSBFIRST)

# Ecrire 3 octets/bytes (0x01, 0x02, 0x03) en utilisant le protocole SPI.
spi.write([0x01, 0x02, 0x03])

Notez que le code commence par importer les éléments FT232H de la bibliothèque GPIO -puis- désactive le pilote FTDI série (comme dans l'exemple GPIO).

Ensuite, le code crée un objet FT232H (comme dans l'exemple GPIO).

La ligne suivante crée une instance de la classe FT232H.SPI qui utilise le périphérique FT232H (l'instance créée juste avant). Un signal chip select/slave select optionnel est défini et assigné au GPIO 8 / broche C0 à l'aide du paramètre "cs" .

Notez également la vitesse (speed), le mode et l'ordre d'envoi des bit (bitorder) du protocol SPI qui sont spécifiés en paramètre lors de l'initialisation. Un mode 0 et un bitorder égal à MSBFIRST sont les valeurs par défaut et ne doivent pas nécessairement être spécifiés (mais il est toujours utile de les indiquer explicitement.

Les autres valeurs possible vont de 0 à 3 et correspondent au valeurs du mode SPI pour les processeurs AVR (wikipedia, anglais).

L'ordre des bits Bitorder peut soit être MSBFIRST (pour envoyer le bit le plus significatif en premier) ou LSBFIRST (pour envoyer le bit le moins significatif d'abord).

Pour finir, la dernière ligne montre comment envoyer 3 octets (3 bytes) sur la ligne D1 (MOSI) en utilisant la fonction write(). La ligne D0 (SCK) générera le signal d'horloge tandis que la ligne D1 (MOSI) émettra les bits (un par un) pour chaque impulsion d'horloge.

Il y a également des fonctions SPI que vous pouvez utiliser pour lire et transférer des données (lire et écrire en même temps):

# Lecture de 3 octets de données en utilisant le protocole SPI.
response = spi.read(3)
print 'Received {0}'.format(response)

# Ecrire 3 octets/bytes et lire simultanément 3 octets/bytes en utilisant le protocole SPI.
response = spi.transfer([0x01, 0x02, 0x03])
print 'Received {0}'.format(response)

La fonction read() lira un nombre prédéfini d'octets/bytes sur la ligne D2 (MISO) (et envoi du signal d'horloge approprié sur D0 (SCK)).

La fonction transfer() revient à un appel des fonctions write() et read() en même temps. Le tableau de d'octets (bytes) sera envoyé sur la ligne D1 (MOSI) tandis que -durant ce même temps- les données seront lues sur la ligne D2 (MISO).

Voila, c'est tout ce que nous avons besoin de savoir pour communiquer avec le protocole/bus SPI du FT232H à l'aide de la bibliothèque Adafruit Python GPIO!

Vous pourriez également être intéressé par la partie de ce tutoriel qui explique comment utiliser le breakout FT232H avec quelques périphériques SPI d'Adafruit (et comment réaliser un portage en utilisant la bibliothèque Adafruit Python GPIO).

Contrôler des NeoPixels avec SPI

Un des intérêt d'utiliser le protocole SPI est qu'il permet de contrôler des LEDs Neopixels (Leds digitales RGB adressable à base de WS2811/WS2812). Ces LEDs n'utilisent pas le bus SPI pour communiquer. A la place, ces LEDs utilisent un signal très spécifique réclament une grande maîtrise des temps d'émission pour envoyer les informations de couleur (les différents bits) des différents LEDs du ruban. Cependant, en utilisant un signal SPI à haute vitesse (6Mhz) il est possible de 'sur-échantillonner' le signal de contrôle NeoPixel et de générer une approximation suffisamment proche sur la ligne D1 (MOSI) du FT232H.

La limitation du nombre de pixel contrôlable est fixé par la quantité maximale d'information qui peut être envoyer en une fois sur le FT232H via le bus USB. Cette limite est d'environ 64 kilobytes (Kilo Octets). Etant donné que nous faisons du sur-échantillonnage du signal de contrôle NéoPixel, chaque pixel requière 24*8 octets/bytes de donnée SPI (ou un octet/byte de donnée SPI pour chaque bit de donnée NéoPixel).

Matériel

Vous aurez besoin des éléments suivants pour tester l'utilisation de NeoPixel avec le breakout FT232H:

  • Un breakout FT232H assemblé.
  • Des NeoPixel (ruban, matrice, anneau, etc).
    Rappelez vous que vous ne pouvez contrôler qu'environ 340 pixels.
  • Une alimentation 5 volts de qualité (bien régulée et capable de fournir le courant demandé).
    • Chaque LED consomme jusqu'à 60mA (100% blanc). Cela représente vite plusieurs ampères (ou plus) si vous accumulez des Pixels. N'essayer pas d'alimenter plus de quelques pixels sur la lignes 5V du FT232H !
  • Une puce convertisseur de niveau logique pour convertir le signal 3.3V vers 5 volts -OU- Une diode de puissance capable de supporter le total du courant d'alimentation des pixels.
    • Le signal de contrôle NeoPixel à besoin d'atteindre au moins 0.7*Vcc (tension d'alimentation), ce qui est juste un peu supérieur au signal de sortie 3.3V (fourni par le breakout FT232H). Exactement comme dans ce tutoriel lighting NeoPixels with the Raspberry Pi (Adafruit, Anglais) ou l'on converti le signal de 3.3V en 5V à l'aide d'un 74AHCT125. L'autre option est de faire chuter la tension d'alimentation des néopixel en dessous de 5V en utilisant une diode de puissance de sorte que le signal de commande 3.3v soit suffisant.
  • Des fils de connexion et breadboard.

Montage

Dans cet exemple, nous allons éclairer un anneau NéoPixe à 16 LEDs et nous allons utiliser une diode de puissance capable de gérer un courant de 1 ampère. Si vous utilisez plus de 16 pixels, il faudra envisager une diode plus puissance (ou un convertisseur de niveau logique 74AHCT125 ).

Connectez le matériel comme suit:

  • La masse/GND du FT232H --vers--> la masse/GND de l'alimentation.
  • FT232H D1 (MOSI) --vers--> le signal d'entrée NeoPixel.
  • Alimentation Positive --vers--> Anode de la diode (le côté de la diode SANS la bande blanche).
  • Cathode de la diode (le côté de la diode AVEC la bande blanche) --vers--> le (+) des NeoPixels.
  • Le (-)/GND des NéoPixels --vers--> le (-)/GND de l'alimentation.

Voyez ci-dessous une photo du montage en question (note une capacité est ajoutée sur l'alimentation comme recommandé dans le guide NeoPixel):

{{{2}}}
Crédit: AdaFruit Industries www.adafruit.com

Programmation

Nous allons maintenant créer un fichier neopixels.py et y ajouter le code suivant:

import time

import Adafruit_GPIO as GPIO
import Adafruit_GPIO.FT232H as FT232H


class NeoPixel_FT232H(object):
	def __init__(self, n):
		# Creer l object FT232H.
		self.ft232h = FT232H.FT232H()
		# Creer l interface SPI sur l objet FT232H. configurer le bus SPI a 6mhz.
		self.spi    = FT232H.SPI(self.ft232h, max_speed_hz=6000000)
		# Creer un buffer de donnee pour les pixels et une table de correspondant (lookup table).
		self.buffer = bytearray(n*24)
		self.lookup = self.build_byte_lookup()

	def build_byte_lookup(self):
		# Creer une table de correspondance qui map toutes les valeurs en octet/bytes 
		# --VERS-- des valeurs 8 octet/byte qui represente les donnees SPI 6mhz 
		# pour le signal neopixel pour l'octet/byte specifie
		# 
		lookup = {}
		for i in range(256):
			value = bytearray()
			for j in range(7, -1, -1):
				if ((i >> j) & 1) == 0:
					value.append(0b11100000)
				else:
					value.append(0b11111000)
			lookup[i] = value
		return lookup

	def set_pixel_color(self, n, r, g, b):
		# Fixer la couleur RGB d'une pixel pour le Nieme position.
		# Fixe l ordre des couleurs sur GRB (vert rouge bleu) mais
		# cela est facilement modifiable ci-dessous.
		index = n*24
		self.buffer[index   :index+8 ] = self.lookup[int(g)]
		self.buffer[index+8 :index+16] = self.lookup[int(r)]
		self.buffer[index+16:index+24] = self.lookup[int(b)]

	def show(self):
		# Envoi le buffer de pixel sir la sortie SPI (broche D1) qui sera
		# percu par les Neopixels comme le signal de commande.
		self.spi.write(self.buffer)


# Executer le code lorsque le script est appele en ligne de commande:
if __name__ == '__main__':
	# Definir le nombre de pixels utilisé.
	# Seul ~340 pixels peuvent être utilisé avec le FT232H.
	pixel_count = 16
	# Creer un objet NeoPixel_FT232H.
	pixels = NeoPixel_FT232H(pixel_count)
	# Animation - allumer chaque pixel en rouge.
	# Passer chaque pixel en revue.
	for i in range(pixel_count):
		# Changer la couleur du pixel en rouge pure.
		pixels.set_pixel_color(i, 255, 0, 0)
		# Envoyer le buffer (de pixel) vers les LEDs.
		pixels.show()
		# faire une toute petite pause.
		time.sleep(0.25)
	# Animation - allumer chaque pixel en vert pure.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 255, 0)
		pixels.show()
		time.sleep(0.25)
	# Animation - allumer chaque pixel en bleu pure.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 0, 255)
		pixels.show()
		time.sleep(0.25)
	# Un modèle (pattern) de couleur qui se déplace le long des pixels.
	# Creation du modele de couleur.
	colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), 
				(0, 0, 255), (255, 0, 255) ]
	offset = 0
	print 'Presser Ctrl-C pour quitter.'
	while True:
		# Passer tous les pixels en revue et fixer leur couleur en fonction du modèle.
		for i in range(pixel_count):
			color = colors[(i+offset)%len(colors)]
			pixels.set_pixel_color(i, color[0], color[1], color[2])
		pixels.show()
		# Incrementer le decalage (offset) pour changer la position des differentes couleurs.
		offset += 1
		time.sleep(0.25)

Sauver le fichier. Utilisez un terminal et naviguez dans le répertoire contenant le fichier.

Exécutez ensuite la commande suivante dans le terminal:

python neopixels.py

Sur une machine Linux ou Mac OSX, il faut exécuter la commande en tant que root:

sudo python neopixels.py

Vous devriez voir les NeoPixels s'allumer et s'animer avec différentes couleurs.

note: vous pourriez avoir besoin de changer la valeur de la variable pixel_count dans la section "__main__" du programme pour que la valeur corresponde au nombre de pixels que vous avez dans votre montage.

Ce code réalise plusieurs opérations de haut-niveau. Il commence par définir une classe nommée NeoPixel_FT232H. Cette classe contient les méthodes et les états nécessaires à la génération du signal NeoPixelavec la carte FT232H. La seconde partie du code utilise la classe NeoPixel_FT232H pour animer les NéoPixels.

Il n'est pas vraiment nécessaire de comprendre le code de la classe NeoPixel_FT232H pour pouvoir l'utiliser. Le code effectue un 'sur-échantillonnage' en utilisant une table de correspondance qui étend chaque octet/byte de couleur en enchaînement de 8 octets/bytes de donnée SPI (ce qui permet de faire une approximation du signal de contrôle NeoPixel). La seule chose vraiment importante à savoir à propos de de la classe NeoPixel_FT232H c'est qu'elle expose la méthode set_pixel_color() qui permet d'assigner la couleur (red,green,blue = rouge,vert,bleu) pour chaque pixel.

Le plus intéressant se trouve dans la seconde partie du code, celle qui utilise la classe NeoPixel_FT232H:

# Python exécute le code ci-dessous lorsque le script est appelé en ligne de commande:
if __name__ == '__main__':
	# Défini le nombre de pixels utilisé dans le montage.
	# Capable de gérer jusqu'à environ 340 pixels via un FT232H.
	pixel_count = 16
	# Créer un objet NeoPixel_FT232H.
	pixels = NeoPixel_FT232H(pixel_count)

Cette portion de code contient une commande if qui vérifie si le programme est lancé en ligne de commande (ou inclus dans un autre programme).

C'est un idiom standard en python qui vérifie le mode de démarrage du script avant de l'exécuter.

Dans le bloc if you pouvez identifier la ligne qui définit le nombre de pixels (la valeur assignée à la variable pixel_count). Ensuite, un objet NeoPixel_FT232H est créé en lui indiquant le nombre de LED disponibles).

	# Animation - allumer chaque pixel en rouge.
	# Passer chaque pixel en revue.
	for i in range(pixel_count):
		# Changer la couleur du pixel en rouge pure.
		pixels.set_pixel_color(i, 255, 0, 0)
		# Envoyer le buffer (de pixel) vers les LEDs.
		pixels.show()
		# faire une toute petite pause.
		time.sleep(0.25)
	# Animation - allumer chaque pixel en vert pure.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 255, 0)
		pixels.show()
		time.sleep(0.25)
	# Animation - allumer chaque pixel en bleu pure.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 0, 255)
		pixels.show()
		time.sleep(0.25)

La section suivante réalise quelques animations simples. Elles allument chaque pixel dans une couleur primaire à l'aide de la fonction set_pixel_color().

Cette fonction prend 4 paramètres:

  • Le premier est le n° du pixel à modifier (démarre à 0),
  • Le deuxième est la quantité de ROUGE (valeur entre 0 et 255. 0 = pas de couleur, 255 = maximum d'intensité)
  • Le deuxième est la quantité de VERT
  • Le deuxième est la quantité de BLEU

Après chaque modification de Pixel, le code appelle la fonction show(). La fonction show() envoi l'état du buffer vers les NéoPixels. Nous avons donc une animation progressive du ruban.

Il est impératif d'appeler show() pour rafraîchir les données de couleur dans le ruban NéoPixel!

Pour finir, notez que la fonction time.sleep() est utilisé pour créer un délai de 1/4 seconde. Cela permet de réaliser l'allumage progressif du ruban (sous forme d'animation).

	# Un modèle (pattern) de couleur qui se déplace le long des pixels.
	# Creation du modele de couleur.
	colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), 
				(0, 0, 255), (255, 0, 255) ]
	offset = 0
	print 'Presser Ctrl-C pour quitter.'
	while True:
		# Passer tous les pixels en revue et fixer leur couleur en fonction du modèle.
		for i in range(pixel_count):
			color = colors[(i+offset)%len(colors)]
			pixels.set_pixel_color(i, color[0], color[1], color[2])
		pixels.show()
		# Incrementer le decalage (offset) pour changer la position des differentes couleurs.
		offset += 1
		time.sleep(0.25)

Pour finir, le code entre dans une boucle infinie qui anime un arc en clien progressant le long des pixels. Ce code utilise également la fonction set_pixel_color() mais avec une logique un peu plus élaborée qui sélectionne une couleur dans une liste de couleurs prédéfinies à chaque itération de la boucle.

Vous noterez également que la fonction show() est appelée pour faire une mise-à-jour du ruban avec la suite de couleur ainsi calculée.

La suite de couleur est décalée d'un pixel supplémentaire à chaque itération.

Voila, c'est tout ce qu'il est nécessaire de savoir pour contrôler des NéoPixels depuis le bus SPI du breakout FT232H!


Source: Adafruit FT232H Breakout Add a serial protocol 'swiss army knife' to your computer and talk directly to devices with SPI, I2C, serial UART, GPIO's, and more!
Créé par Toni DiCola pour AdaFruit Industries.

Traduction réalisée par Meurisse D pour MCHobby.be.

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.

Traduit avec l'autorisation d'AdaFruit Industries - Translated with the permission from Adafruit Industries - www.adafruit.com