Jusqu'à présent, nous n'avions pas grand-chose à proposer pour interfacer un PC avec un système externe à l'aide d'entrée/sorties digitales. Cette lacune est désormais comblée par le nouveau Yocto-Maxi-IO, que nous vous présentons aujourd'hui. Il ne s'agit pas d'un succédané de port GPIO, mais d'une interface isolée, qui vous permettra d'interfacer sans risque et sans électronique supplémentaire 8 lignes digitales bidirectionnelles à la tension que vous désirez.
Le Yocto-Maxi-IO a été conçu pour être un produit flexible, qui s'adapte à de nombreux cas d'utilisation. Chaque ligne digitale peut être configurée dynamiquement comme:
- Une entrée digitale simple, dont la valeur est 0 ou 1 selon que la tension est inférieure ou supérieure à 2 V. Contrairement au port GPIO qu'on trouve sur les boards de développement, en général limité à 3.3V, le Yocto-Maxi-IO accepte des tensions jusqu'à 25V, ce qui permet d'interfacer directement un appareil fonctionnant en CMOS ou TTL 5V, ou un même un signal 24V provenant d'un tableau électrique. Une Led témoin indique en permanence la valeur lue sur l'entrée.
- Une entrée digitale avec pull-up, destinée à être pilotée par une sortie à collecteur ouvert (drain ouvert). On peut naturellement y brancher aussi n'importe quel interrupteur ou capteur à sortie transistor. La logique de l'entrée peut naturellement aussi être inversée.
- Une sortie digitale simple, permettant de piloter des interfaces CMOS ou TTL. A nouveau, contrairement aux ports GPIO habituels, la tension de sortie pour le niveau haut est configurable: 3V ou 5V (tirés du bus USB), ou alors une tension arbitraire (jusqu'à 25V) fournie sur un bornier ad-hoc. Une seule contrainte, la tension de sortie est la même pour toutes les lignes. La sortie a une impédance de 180Ω, elle permet même de fournir quelques milliampères pour piloter une Led par exemple.
- Une sortie digitale open-drain, tolérant elle-aussi les tensions jusqu'à 25V.
Les 8 entrées/sorties peuvent être lues ou écrites simultanément comme un seul octet, ou accédées une par une à l'aide d'opérations atomiques.
Le Yocto-Maxi-IO
Petit exemple d'utilisation: un affichage numérique
Il existe une quantité innombrable d'applications utiles pour ce module, spécifiques à un appareil particulier à interfacer à l'aide de quelques lignes digitales. En guise d'exemple, nous avons choisi une application générique à priori toute simple, mais dont la réalisation sans Yocto-Maxi-IO serait passablement plus compliquée.
Le but est de piloter un grand affichage numérique à 7 segments, tel qu'on en voit souvent pour guider les clients qui attendent vers un guichet. Pour rendre la chose plus ludique, nous allons en faire une machine à sizings roulette numérique, pilotée en Java: l'utilisateur presse sur un gros bouton, et le chiffre se met à tourner pour finalement se stabiliser à une valeur plus ou moins aléatoire.
L'exemple du jour
A priori cela parait très simple: une entrée pour le bouton, 7 sorties pour les segments de l'affichage. Sauf qu'en y regardant d'un peu plus près, on se rend compte qu'un affichage à Led de cette taille ne se pilote pas avec un simple GPIO: comme il comporte de nombreuses Leds en série, il faut une tension de 18 à 25V pour les allumer, ce qui exigerait tout un circuit électronique à base de transistors pour le piloter depuis un port GPIO, avec en plus des problèmes de masse si la source de tension des Leds n'est pas en terre commune avec le PC.
Bien heureusement, tout cela est géré de manière transparente par le Yocto-Maxi-IO. On va simplement récupérer un convertisseur DC/DC de 5V vers +/-12V pour créer une source "24V" depuis le 5V du bus USB, et le fournir comme tension externe au Yocto-Maxi-IO. Notre affichage travaillant en anode commune, le 24V est fourni sur l'anode de l'affichage, et le Yocto-Maxi-IO mettra la cathode des Leds à allumer à 0V pour les allumer (sortie inversée).
L'entrée pour le bouton se fait naturellement avec une entrée avec pull-up (open collector). Notre interrupteur disposant d'un éclairage 12V intégré, nous le branchons en parallèle, de sorte à ce que le pull-up, pilotable lui-aussi, allume en même temps le bouton. Voici donc le schéma de branchement (nous avons ajouté quelques résistances en série sur les fils électriques pour limiter le courant par mesure de précaution):
Le schéma de branchement
Le programme
Le code de pilotage se contente de configurer le Yocto-Maxi-IO comme décrit ci-dessus (le bit 0 est affecté au bouton, les autres à l'affichage), d'attendre une pression et de faire tourner les chiffres. La conversion du chiffre à afficher en segments à allumer est faite simplement par une table. Nous sommes partis de l'exemple fourni dans la librairie Yoctopuce dans le répertoire Doc-GettingStarted-Yocto-Maxi-IO, et nous remplaçons le code principal par celui-ci:
int sevenSeg[] = {
0xde,0x88,0xe6,0xea,0xb8,0x7a,0x7e,0xc8,0xff,0xfa
};
// enable external power source
io.set_outputVoltage(YDigitalIO.OUTPUTVOLTAGE_EXT_V);
// configure bit 0 as input, bits 1..7 as regular output
io.set_portDirection(0xFE);
// reverse polarity for all bits
io.set_portPolarity(0xff);
// repeat until disconnected
while(io.isOnline()) {
// turn on button, wait for press
io.set_portOpenDrain(0x01);
do {
YAPI.Sleep(10);
} while(io.get_bitState(0) == 0);
io.set_portOpenDrain(0x00);
// roll the dice for a random duration
double frameDuration = 3.0; // [ms]
do {
digit = (digit+1) % 10;
frameDuration *= 1.1+Math.random()/10;
io.set_portState(sevenSeg[digit]);
YAPI.Sleep((int)frameDuration);
} while(frameDuration < 800);
// flash the number 5 times
for(int i = 0; i < 6; i++) {
io.set_portState(0);
YAPI.Sleep(100);
io.set_portState(sevenSeg[digit]);
YAPI.Sleep(100);
}
}
Le résultat
Et voilà ce que cela donne: