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

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
Ligne 41 : Ligne 41 :
 
{{traduction}}
 
{{traduction}}
  
Notice too the speed, mode, and bit order of the SPI protocol are specified as parameters of the initializer. Mode 0 and bit order of ''MSBFIRST'' are actually the default values and do not necessarily need to be specified here, but it's helpful to show them for clarity.
+
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.
  
Possible mode values are 0 through 3 and they correspond to [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers SPI mode values for AVR processors] (''wikipedia, anglais'').
+
Les autres valeurs possible vont de 0 à 3 et correspondent au [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers valeurs du mode SPI pour les processeurs AVR] (''wikipedia, anglais'').
  
Bitorder can be either '''MSBFIRST''' for most significant bits to be clocked out first, or '''LSBFIRST''' for the least significant bits to be clocked out first.
+
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).
  
Finally the last line shows how to send 3 bytes of data out the '''D1 (MOSI)''' line using the '''write()''' function. The '''D0 (SCK)''' line will generate a clock signal, and the '''D1 (MOSI)''' line will clock out bits of data with every clock pulse.
+
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.
  
There are also SPI functions you can use to read and transfer (read and write at the same time) data:
+
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):
  
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
# Read 3 bytes of data using the SPI protocol.
+
# Lecture de 3 octets de données en utilisant le protocole SPI.
 
response = spi.read(3)
 
response = spi.read(3)
 
print 'Received {0}'.format(response)
 
print 'Received {0}'.format(response)
  
# Write 3 bytes and simultaneously read 3 bytes using the SPI protocl.
+
# Ecrire 3 octets/bytes et lire simultanément 3 octets/bytes en utilisant le protocole SPI.
 
response = spi.transfer([0x01, 0x02, 0x03])
 
response = spi.transfer([0x01, 0x02, 0x03])
 
print 'Received {0}'.format(response)
 
print 'Received {0}'.format(response)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The '''read()''' function will read the specified number of bytes on the '''D2 (MISO)''' line (sending clock pulses out '''D0 (SCK)''' as necessary).
+
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)''').
  
The '''transfer()''' function is like calling '''write()''' and '''read()''' at the same time. The specified array of bytes will be sent out '''D1 (MOSI)''' while at the same time data will be read from '''D2 (MISO)'''.
+
La fonction '''transfer()''' revient à un appel des fonctions '''write()''' et '''read()''' {{underline|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)'''.
  
That's all there is to using the SPI protocol with the FT232H and the Adafruit Python GPIO library!
+
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!
  
You might also be interested in this tutorial which shows how to use the FT232H breakout with some Adafruit SPI  devices that have been ported to use Adafruit's Python GPIO library.
+
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 ==
 
== Contrôler des NeoPixels avec SPI ==

Version du 19 mars 2017 à 11:56


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

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 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.

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).

To demonstrate lighting NeoPixels with the FT232H breakout you'll need the following parts:

  • Assembled FT232H breakout board.
  • NeoPixel strip, strand, matrix, etc.
    • Remember at most you can only light about 340 pixels.
  • Strong 5 volt power supply to drive the NeoPixels.
    • 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!
  • Level converter chip to convert 3.3 to 5 volts OR a power diode that can handle the full power of all the NeoPixels.
    • 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 breakout. Just like lighting NeoPixels with the Raspberry Pi (Adafruit, Anglais) you need to either convert the control signal to 5 volts using a chip like the 74AHCT125, or drop the NeoPixel power supply down slightly below 5 volts using a power diode.
  • Jumper wires and 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.

Connect the hardware as follows:

  • FT232H GND to power supply ground.
  • FT232H D1 (MOSI) to NeoPixel signal input.
  • Power supply positive voltage to diode anode (side without the stripe).
  • NeoPixel positive voltage to diode cathode (side with the stripe).
  • NeoPixel ground to power supply ground.

A picture of the hardware setup is below (note I've added a large capacitor to the power supply as recommended in the NeoPixel Uberguide):

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

Now create a file neopixels.py and fill it with the following code:

import time

import Adafruit_GPIO as GPIO
import Adafruit_GPIO.FT232H as FT232H


class NeoPixel_FT232H(object):
	def __init__(self, n):
		# Create an FT232H object.
		self.ft232h = FT232H.FT232H()
		# Create a SPI interface for the FT232H object.  Set the SPI bus to 6mhz.
		self.spi    = FT232H.SPI(self.ft232h, max_speed_hz=6000000)
		# Create a pixel data buffer and lookup table.
		self.buffer = bytearray(n*24)
		self.lookup = self.build_byte_lookup()

	def build_byte_lookup(self):
		# Create a lookup table to map all byte values to 8 byte values which
		# represent the 6mhz SPI data to generate the NeoPixel signal for the
		# specified byte.
		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):
		# Set the pixel RGB color for the pixel at position n.
		# Assumes GRB NeoPixel color ordering, but it's easy to change below.
		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):
		# Send the pixel buffer out the SPI data output pin (D1) as a NeoPixel
		# signal.
		self.spi.write(self.buffer)


# Run this code when the script is called at the command line:
if __name__ == '__main__':
	# Define the number of pixels in the NeoPixel strip.
	# Only up to ~340 pixels can be written using the FT232H.
	pixel_count = 16
	# Create a NeoPixel_FT232H object.
	pixels = NeoPixel_FT232H(pixel_count)
	# Animate each pixel turning red.
	# Loop through each pixel.
	for i in range(pixel_count):
		# Set the pixel color to pure red.
		pixels.set_pixel_color(i, 255, 0, 0)
		# Show the pixel buffer by sending it to the LEDs.
		pixels.show()
		# Delay for a short period of time.
		time.sleep(0.25)
	# Animate each pixel turning pure green.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 255, 0)
		pixels.show()
		time.sleep(0.25)
	# Animate each pixel turning pure blue.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 0, 255)
		pixels.show()
		time.sleep(0.25)
	# Animate a pattern of colors marching around the pixels.
	# Create a pattern of colors to display.
	colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), 
				(0, 0, 255), (255, 0, 255) ]
	offset = 0
	print 'Press Ctrl-C to quit.'
	while True:
		# Loop through all the pixels and set their color based on the pattern.
		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()
		# Increase the offset to make the colors change position.
		offset += 1
		time.sleep(0.25)

Save the file and navigate to the folder with it in a terminal, then execute the following in Windows to run the program:

python neopixels.py

Or on Mac OSX or Linux execute the following to run the program as root:

sudo python neopixels.py


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.

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.

Instead let's walk through a bit of the second half of the code that uses the NeoPixel_FT232H class:

# Run this code when the script is called at the command line:
if __name__ == '__main__':
	# Define the number of pixels in the NeoPixel strip.
	# Only up to ~340 pixels can be written using the FT232H.
	pixel_count = 16
	# Create a NeoPixel_FT232H object.
	pixels = NeoPixel_FT232H(pixel_count)

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.

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.


	# Animate each pixel turning red.
	# Loop through each pixel.
	for i in range(pixel_count):
		# Set the pixel color to pure red.
		pixels.set_pixel_color(i, 255, 0, 0)
		# Show the pixel buffer by sending it to the LEDs.
		pixels.show()
		# Delay for a short period of time.
		time.sleep(0.25)
	# Animate each pixel turning pure green.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 255, 0)
		pixels.show()
		time.sleep(0.25)
	# Animate each pixel turning pure blue.
	for i in range(pixel_count):
		pixels.set_pixel_color(i, 0, 0, 255)
		pixels.show()
		time.sleep(0.25)

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 color. This 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.

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!

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.

	# Animate a pattern of colors marching around the pixels.
	# Create a pattern of colors to display.
	colors = [ (255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 255, 255), 
				(0, 0, 255), (255, 0, 255) ]
	offset = 0
	print 'Press Ctrl-C to quit.'
	while True:
		# Loop through all the pixels and set their color based on the pattern.
		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()
		# Increase the offset to make the colors change position.
		offset += 1
		time.sleep(0.25)

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.

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!


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