Nouveau: le Yocto-SPI

Nouveau: le Yocto-SPI

Voici un nouveau venu dans la famille de nos modules d'interface: le Yocto-SPI. Ce petit module peut communiquer avec des capteurs ou autre périphérique utilisant un protocole de communication SPI.






SPI est un standard pour transférer des données entre un processeur et des périphériques. Un bus SPI compte normalement cinq fils:

  1. la terre (GND)
  2. la ligne d'horloge (SCK), qui utilisée pour cadencer la transmission de chaque bit
  3. la ligne de données sortantes (SDO), pour transmettre les bits au périphérique
  4. la ligne de données entrantes (SDI), pour recevoir les bits du périphérique
  5. la ligne slave select (SS), pour signaler le début et la fin des messages

Un sixième fil est souvent présent pour alimenter le périphérique. Le principal champ d'application de SPI est la communication entre les circuits à l'intérieur d'une carte électronique, mais certains capteurs et périphériques utilisent aussi ce standard, en particulier parce qu'il permet facilement de chaîner plusieurs périphériques sur le même bus.

Le Yocto-SPI est une solution pratique pour interfacer un périphérique SPI depuis un portable, une tablette ou un ordinateur. Il fournit les six contacts décrits ci-dessus. Il peut être configuré pour travailler en niveaux électriques 3.3V ou 5V, et pour fournir une alimentation en 3.3V ou 5V indépendamment. Comme tout module Yoctopuce, il ne requiert pas l'installation d'un driver et ne crée pas de port COM virtuel. A la place, vous pouvez simplement appeler nos fonctions d'API de haut niveau, fournies dans la librairie Yoctopuce, pour communiquer avec le périphérique depuis votre programme.

Le nouveau Yocto-SPI
Le nouveau Yocto-SPI


Bonus


En plus de travailler comme simple interface, le Yocto-SPI peut aussi être configuré pour envoyer automatiquement des commandes spécifiques sur le bus SPI et lire les données reçues. Ceci peut être utilisé par exemple pour interroger un capteur de manière autonome, et publier les mesures obtenues selon avec une interface GenericSensor. Il est donc possible de sauvegarder ces mesures dans l'enregistreur de données intégré au module, et de les envoyer sur le réseau. Par exemple, si vous connecter le Yocto-SPI à un YoctoHub-GSM-3G-EU, vous pourrez automatiquement envoyer les mesures sur le serveur Cloud de votre choix, depuis n'importe quel endroit avec une couverture GSM.

Démonstration


Voici une petite démonstration du Yocto-SPI, utilisé pour piloter un petit périphérique SPI. Nous avons trouvé des sympathiques petits afficheurs 7 segments très abordables sur embedded-lab.com. Ils sont disponibles en 4 couleurs et peuvent être chaînés. Voyons donc comment les piloter depuis une application existante, à l'aide d'un Yocto-SPI.

Les afficheurs 7 segments trouvés sur embedded-lab.com
Les afficheurs 7 segments trouvés sur embedded-lab.com



Comme point de départ, nous avons pris l'application d'exemple de notre librairie C# appelée YSensorGraph, qui lit un capteur de température et affiche un graphique en direct avec les valeurs mesurées. Dans la méthode newSensorValue(), qui est appelée à chaque nouvelle température mesurée, nous avons ajouté un appel à une nouvelle méthode qui affiche la valeur sur l'afficheur 7 segments.

La première chose à faire dans cette méthode est de voir si il y a une interface SPI connectée, et sortir sinon. On pourrait vérifier qu'elle porte un nom spécifique si nous en utilisions plusieurs, mais nous en resterons là pour cette fois.

YSpiPort spiPort = YSpiPort.FirstSpiPort();
if (spiPort == null) return;


Ensuite on configure les paramètres SPI: vitesse d'horloge, mode SPI, ordre de transmission des bits, etc. Ces paramètres sont documentés dans les spécifications du périphérique que vous devez interfacer.

spiPort.set_spiMode("250000,3,msb");
spiPort.set_ssPolarity(YSpiPort.SSPOLARITY_ACTIVE_LOW);
spiPort.set_protocol("Frame:2ms");


Ensuite, il faut envoyer quelques commandes SPI à l'écran pour qu'il se mette à afficher comme on le désire. En particulier, on peut configurer pour chaque digit si les données doivent être interprétées comme des nombres (et converties automatiquement pour allumer les segments adéquats), ou si elles représentent un bitmap décrivant l'état ON/OFF de chaque segment. Chaque commande envoyée à l'afficheur est composée de deux octets: la commande, et l'argument. Par exemple, la commande 0a sert à définir la luminosité, et la valeur 05 est le niveau de luminosité désiré.

// Configure l'afficheur
spiPort.writeHex("0c01"); // Désactivation du mode "shutdown"
spiPort.writeHex("09f8"); // Mode BCD pour les positions 4 à 8
spiPort.writeHex("0b07"); // Active les positions 0-7 (=8 en tout)
spiPort.writeHex("0a05"); // Configure la luminosité


Voici l'affichage que nous voulons obtenir
Voici l'affichage que nous voulons obtenir


Sur les trois positions les plus à droite, nous affichons un espace, suivi de l'unité °C. Pour ces trois positions, nous utilisons la valeur est un bitmap où chaque bit indique si un segment doit être allumé ou éteint. Par exemple, pour afficher un espace on met tous les bits à zéro, donc on envoie la valeur 00.

spiPort.writeHex("014e"); // Position 1: Affiche 'C'
spiPort.writeHex("0263"); // Position 2: Affiche le signe degré
spiPort.writeHex("0300"); // Position 3: Affiche un espace


Pour afficher la mesure sur les 5 positions restantes, on doit calculer la représentation décimale. C'est fait en divisant successivement la valeur par 10, pour extraire les chiffres un à un. Le signe doit être géré séparément, puisqu'il doit être montré just devant le nombre le plus à gauche. Le point décimal est ajouté en activant le bit de poids fort sur le chiffre correspondant.

// Affiche la mesure sur les positions 4 à 8
int rounded = (int)Math.Round(Math.Abs(value) * 100);
int decPoint = 2;
bool needSign = (value < 0);
for (int i = 4; i <= 8; i++)
{
    int digit = rounded % 10;           // prend le chiffre suivant
    if (decPoint == 0) digit |= 0x80;   // ajoute le point décimal
    if (decPoint < 0 && digit == 0) {
        if (needSign) {
            digit = 0xa;        // le signe '-'
            needSign = false;   // affiché une fois seulement
        } else {
            digit = 0xf;        // un espace
        }
    }
    spiPort.writeArray(new List<int> { i, digit });
    decPoint--;
    rounded /= 10;
}



Et voilà, c'est tout. Comme d'habitude, la complexité réside dans la logique de l'application, et non dans l'interfaçage des modules Yoctopuce...

  

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.