Après avoir vu la semaine dernière comment interroger un capteur SPI en gérant explicitement les communications SPI à l'aide de la librairie Yoctopuce, nous allons maintenant montrer comment le Yocto-SPI peut encore nous simplifier la tâche, et surtout simplifier le code de l'application.
Nous allons donc continuer avec le même inclinomètre de précision Murata SCL3300, et montrer comment le protocole de communication que nous avons implémenté en C# peut être intégré directement à l'intérieur du Yocto-SPI, de sorte à ce que le PC de contrôle en soit déchargé.
Etape 1: Configurer le Yocto-SPI
Les paramètres que nous avons configuré en logiciel peuvent facilement être configurés dans l'interface web du VirtualHub, c'est comme vous préférez. Voici l'interface de configuration telle que désirée:
Configuration du Yocto-SPI pour le SCL3300
Si vous vous posez des questions sur le choix de ces paramètres, vous pouvez revenir à notre article de la semaine dernière où nous avons indiqué où les trouver dans la datasheet du capteur.
Etape 2: Intégrer le protocole au Yocto-SPI
Le but de cette étape est que le Yocto-SPI effectue spontanément toutes les transmissions que nous avons précédemment implémentées en C#. Nous allons donc définir un Job dans l'interface de configuration du module, qui comportera plusieurs tâches, chacune responsable d'une facette du protocole: initialisation, configuration, vérification, mesures. Pour vous donner d'emblée la vue d'ensemble, voici les 7 tâches que nous allons définir. Elles vous seront expliquées ci-dessous.
Les 7 tâches pour gérer la communication avec le SCL3300
Notez que nous aurions pu prendre quelques raccourcis pour faire une solution plus simple pour notre cas particulier, mais nous avons choisi de vous montrer une solution plus générale, adaptable à la plupart des capteurs, en particulier par l'utilisation d'une variable d'état.
La tâche Reset
Au lancement de Job, on commence par vider le tampon de communication et définir une variable d'état $st qui nous permettra de savoir quelle autre tâche peut être lancée en fonction de l'état du capteur.
La tâche d'initialisation
Cette tâche ne s'exécute qu'une seule fois, lorsque la variable d'état n'est pas encore définie.
La tâche SetMode4
Cette tâche est celle qui effectue la configuration du SCL3300, telle que décrite dans la table 10 du datasheet. Vous y reconnaîtrez la commande qui bascule le capteur dans le mode 4, puis les temporisations et les commandes pour lire le status. Notez que, comme pour l'approche en C#, nous avons choisi la sérialisation des commandes: tous les envois sont faits d'un coup, en respectant les timings spécifiés, mais le résultat des commandes sera traité dans une tâche séparée.
La tâche de configuration
Cette tâche est définie comme périodique car elle pourrait devoir se réactiver si pour une raison ou une autre le capteur devait être réinitialisé. Il suffirait pour cela qu'une autre tâche remette l'état $st à zéro et la tâche s'exécuterait à nouveau.
La tâche CheckID
Le but de cette tâche est de vérifier que l'initialisation a bien fonctionné. Il s'agit cette fois d'une tâche réactive, c'est à dire qui sera déclenchée spontanément en réponse à l'apparition d'un message donné envoyé par le SCL3300. La première commande est donc un expect, qui reconnaît la réponse du message READ_ID avec l'identifiant attendu C1. Si c'est le cas, on met un message Sensor ready dans les logs du module et on passe dans l'état où l'on va pouvoir lancer les interrogations du capteur:
La tâche de vérification
La tâche QueryAngles
Voici finalement la tâche qui déclenchera automatiquement la lecture des mesures, de manière sérialisée comme en C#. La tâche est périodique chaque 100ms, ce qui nous permet une lecture à 10Hz comme prévu par le SCL3300 pour le mode 4:
La tâche d'interrogation
Vous aurez noté qu'il n'y a dans cette tâche aucune lecture des résultats. Comme pour la tâche CheckID précédemment, on va utiliser des tâches réactives pour décoder les messages reçus. Ainsi, il n'est même pas nécessaire de prévoir une temporisation, c'est le module qui appellera automatiquement notre tâche dès que la réponse arrivera.
Remarquez aussi que nous devons effectuer une requêtes supplémentaire après la demande de l'angle Z pour en recevoir la réponse, puisque les réponses dans un protocole SPI ne sont toujours transmises qu'avec l'envoi du message suivant.
Les tâches ReadAngleX/Y/Z
On aurait pu faire une seule tâche qui lit les trois réponses consécutives, mais comme il s'agit de trois messages différents, on a opté pour un comportement plus général avec trois tâches distinctes, sans dépendance avec l'ordre d'interrogation des axes et l'ordre d'arrivée des réponses.
Les tâches de lecture des résultats
Le calcul qui reprend littéralement la définition donnée dans le datasheet du module et l'affecte aux fonctions genericSensor1/2/3 via les variables $1, $2 et $3.
Etape 3: Tester en direct
Une fois le job défini, il suffit de le lancer pour voir apparaître en direct les mesures dans l'interface Web du VirtualHub (à l'aide du bouton Show device functions). La LED verte du Yocto clignote à 10Hz, à chaque interrogation.
Si l'on veut récupérer les valeurs du capteur depuis un logiciel, il n'est plus nécessaire de communiquer explicitement avec le capteur via des messages SPI. Il suffit d'une simple lecture comme pour n'importe quel capteur Yoctopuce:
double angle_x = sensorX.get_currentValue()
On peut aussi utiliser la lecture par callbacks de changement de valeur, ou les callbacks périodiques:
sensorX.registerTimedReportCallback(updateAngleX);
public void updateAngleX(YFunction f, YMeasure m)
{
angle_x = m.get_averageValue();
}
Et bien sûr, on va aussi pouvoir enregistrer les mesures automatiquement sur la mémoire flash du module, et les afficher avec Yocto-Visualization. D'ailleurs, on va en profiter pour comparer les performances de ce capteur à d'autres... Mais ce sera pour la semaine prochaine !