Érudit, un savoir à cultiver… librement

Premier diffuseur de ressources francophones en sciences humaines et sociales en Amérique du Nord, Érudit s’est refait une beauté en 2017. Fruit d’un travail d’un an et demi, cette refonte technique et visuelle offre de nouvelles fonctionnalités, auxquelles notre expert Python Morgan Aubert s’est fait un grand plaisir de contribuer.

En accès libre
Avant d’aborder cette refonte, revenons un petit peu en arrière. En 1998, les Presses de l’Université de Montréal lancent Érudit, plateforme de ressources pour les sciences humaines et sociales. Six ans plus tard, en 2004, elle bénéficie du soutien d’un consortium unissant l’Université de Montréal, l’Université Laval et l’Université du Québec à Montréal. Cette union renforce Érudit dans sa mission de diffuser en accès libre du contenu de haut niveau dans plus de 30 disciplines : des revues savantes et culturelles, des livres, des actes, des mémoires, des thèses ainsi que des rapports de recherche.

Ce volume conséquent de plus de 200 000 documents fait de la plateforme un acteur de référence pour la recherche francophone, contribuant au partage du savoir et encourageant par là même la publication scientifique en français sur le territoire nord-américain. En 2016, le compteur des consultations est monté 21 millions !

Par ailleurs, Érudit s’est engagé dès sa création envers l’utilisation des logiciels libres : son environnement de travail, son infrastructure et ses services reposent sur des logiciels libres. Directeur des technologies du consortium, Davin Baragiotta insiste sur le fait d’avoir «la capacité d’utiliser des technologies développées/maintenues par des tiers, d’y contribuer au besoin -comme on a pu le faire- et de mettre à disposition notre propre code en vue d’une réutilisation complète ou partielle par des tiers. C’est une culture technique de partage et de collaboration qui permet d’avoir une meilleure capacité de développement et de maintenance de nos TI. Aussi, d’un point de vue organisationnel, cette approche technique s’inscrit dans une culture plus large d’ouverture, de collaboration et de partenariat. Essentiellement, Érudit met en valeur des contenus scientifiques et culturels que l’on veut voir d’avantage diffusés en Open Access. »

Lors des travaux préliminaires de la refonte, le projet visait à doter Érudit d’une plateforme moderne qui permettra une évolution continue et une extension des fonctionnalités. Il s’agissait donc de réécrire la plateforme en Python/Django en remplacement de Cocoon/Drupal/WordPress, mais en gardant la même couverture fonctionnelle. C’est dans ce contexte que notre expert Morgan Aubert a travaillé en tant consultant développeur Python. Il y a fait du développement back end et front end, en utilisant le framework web Django, alors que les développements front end impliquaient Javascript et Sass.

Bonjour Morgan, quels ont été les défis techniques auxquels tu as confronté pour cette plateforme ?
L’un des principaux défis technologiques était lié au gros volume de données à importer, traiter, présenter et servir sur la plateforme. En effet, la plateforme Érudit met à disposition plus de 200 000 documents savants et culturels. Avant d’être visibles sur la plateforme Erudit.org, ces documents doivent être importés depuis différentes sources de données – ce qui implique plusieurs protocoles sous-jacents (par exemple Fedora Commons, un système de gestion de bibliothèques numériques, ou encore OAI-PMH, Open Archive Initiative Protocol for Metadata Harvesting, un protocole permettant l’échange de métadonnées provenant de sources diverses). Gérer un tel volume de document impliquait également d’anticiper les différents usages de la plateforme afin d’assurer une navigation fluide et performante pour les utilisateur d’ Erudit.org.

Il y avait également d’autres défis : assurer une certaine rétro-compatibilité entre l’ancienne plateforme et la nouvelle, qu’il s’agisse de redirections entres les anciennes URLs et les nouvelles, ou des techniques de conservation de l’indexation des documents Érudit dans Google et Google Scholar (https://scholar.google.ca/). Un autre défi consistait à permettre la collecte de métriques de consultations de documents en vue de produire des statistiques dans divers formats, et ainsi représenter ces statistiques de consultation de documents savants ou culturels avec des outils tel que COUNTER, ou des webservices, qui implémentent plusieurs normes de webservices liés à la récupération de données de consultation de documents savants ou culturels tel que Schemas for the Standardized Usage Statistics Harvesting Initiative (SUSHI).

Et quelle fut la partie de ton travail la plus intéressante ?
L’objectif de la plateforme Erudit.org s’inscrit dans une dynamique très vertueuse; le fait d’effectuer des travaux de conception et de développement sur la nouvelle version de cette plateforme était ainsi très valorisant. Outre les travaux liés à la mise en place de cette nouvelle application avec le cadriciel Django, l’un des aspects les plus intéressants de cette mission de plusieurs mois était lié aux spécificités mêmes de la plateforme : le fait de découvrir les spécificités techniques et exigences du milieu universitaire/bibliothécaire était particulièrement intéressant. Qu’il s’agisse de protocoles d’échange de métadonnées, de technologies de gestion de bibliothèques numériques ou de normes de présentation de citations, c’est un milieu qui vient avec son lot de problématiques techniques, d’enjeux technologiques… et de solutions libres. J’ai d’ailleurs été amené à réaliser plusieurs contributions lors de mon mandat, notamment dans le cadre de l’utilisation d’outils Python proposant des mécanismes d’interactions avec des technologies de gestion de bibliothèques numériques tels que eulfedora pour Fedora Commons .

Christophe Villemer, vice-président de Savoir-faire Linux, rebondit sur ces contributions : «en apportant notre expertise Python/Django à ce projet d’envergure, nous avons pu à la fois participer au développement d’un moteur de recherche important pour la communauté scientifique et offrir de nouvelles ressources à celle des technologies open source destinées à la gestion documentaire. Ce qui correspond parfaitement à la philosophie de notre entreprise».


Une version bêta

Complété à l’interne, le nouvel Érudit est encore en version bêta, et au cours de l’année de nouvelles fonctionnalités seront graduellement intégrées au site. Dans l’esprit des technologies ouvertes, vous pouvez contribuer à l’amélioration de la plateforme en signalant tout bogue à l’adresse bogue@erudit.org, et vous pouvez aller consulter le projet sur github, où Érudit a même son propre dépôt.

En attendant ces améliorations, libre à vous d’aller consulter la plateforme de recherches et trouver une multitude de ressources sur le logiciel libre, entre les thèses, les mémoires de maîtrise, les articles de revue savante ou culturelle, vous aurez l’embarras du choix…

Comment Ring communique avec les appareils connectés #IoT

light-bulb - IoTQuand vous sortez de chez vous, êtes-vous sûr que les lumières sont éteintes? Avec Ring, vous pouvez le vérifier en vidéo et régler votre éclairage simplement en envoyant un message texte. De quoi faire des économies d’énergie!

En moins d’une heure, Adrien Béraud, développeur chez Savoir-faire Linux, a monté un dispositif lui permettant de contrôler l’éclairage de son salon alors qu’il est au bureau. Il a configuré le compte Ring de son ordinateur domestique pour accepter automatiquement chaque appel et peut ainsi l’appeler pour voir en temps réel, en vidéo, son salon à distance. Il peut alors vérifier si les lumières sont allumées et, au besoin, les éteindre en utilisant le module de clavardage de Ring!

Un dispositif simple, monté avec du matériel libre

Arduino - IoTAdrien a d’abord relié les lampes de son salon à Internet, en utilisant un système connecté Particle Core (de type Arduino) et une carte d’extension relais (Relay Shield). Comme son éclairage est associé à un circuit va-et-vient, il peut facilement contrôler les lumières, même en cas de panne Internet ou en cas de problème avec le relais. Il a ensuite ajouté les quelques lignes de code fournies dans la documentation du relais pour connecter le dispositif à Internet.

Avec quelques lignes de commande, vos lampes sont connectées

Une fois la connexion établie, il a inséré une ligne de commande dans le terminal de son ordinateur Linux. Par exemple, pour éteindre (LOW) la première lampe (r1) :

curl https://api.particle.io/v1/devices/0123456789abcdef/relay -d access_token=123412341234 -d params=r1,LOW

Le contrôle des lumières par le clavardage de Ring peut ensuite se faire avec ce script Python :

#!/usr/bin/env python3
import re, json, http.client, urllib.parse
from controler import DRingCtrl

PARTICLE_API_TOKEN = '[your_api_token_here]'
PARTICLE_REQ_URI = '/v1/devices/[your_device_id_here]/relay'
PARTICLE_REQ_RE = re.compile('^(r[0-4],(?:HIGH|LOW))$')

class LightRingController(DRingCtrl):
    def __init__(self):
        super().__init__("LightController")

    def tryParticleReq(self, params):
        try:
            conn = http.client.HTTPSConnection('api.particle.io')
            p = urllib.parse.urlencode({'access_token': PARTICLE_API_TOKEN, 'params': params})
            conn.request("POST", PARTICLE_REQ_URI, p, {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"})
            ret = json.loads(conn.getresponse().read().decode())['return_value']
        finally:
            conn.close()
        return ret

    def onIncomingMessage(self, callid, ufrom, message):
        super().onIncomingMessage(callid, ufrom, message)
        msg = message['text/plain']
        res = re.search(PARTICLE_REQ_RE, msg)
        if res:
            op = res.group(0)
            print('Command:', op)
            ret = self.tryParticleReq(op)
            self.callmanager.sendTextMessage(callid, {'text/plain':'Got: '+str(ret)}, False)

if __name__ == "__main__":
    ctrl = LightRingController()
    ctrl.run()

L’Internet des objets: des possibilités infinies

De nombreux usages sont possibles, du plus simple au plus complexe. Par exemple, un appel Ring peut être directement associé à la mise en marche de votre éclairage, avec ce simple script :

#...

class LightRingController(DRingCtrl):

    #...

    def onCallStateChanged(self, callid, state, statecode):
        super().onCallStateChanged(callid, state, statecode)
        if state == "HUNGUP":
            self.tryParticleReq('r1,LOW')
        elif state == "CURRENT":
            self.tryParticleReq('r1,HIGH')

Imaginez alors ce que vous pourriez faire si votre logiciel Ring était relié à votre chauffage ou à la porte de votre garage… Les perspectives sont infinies!

Vous avez des idées à partager ? Laissez un commentaire!

OCTAS 2015 : votez pour le Centre collégial des services regroupés, Véga, Python… et Savoir-faire Linux!

Prix COUP DE CŒUR TIIl y a quelques jours, le Réseau ACTION TI annonçait que, pour la première fois en 2015, un prix du public serait remis lors du Gala des OCTAS 2015, le 28 mai prochain : le prix COUP DE CŒUR TI. Parmi les 77 organisations nominées figure le Centre collégial des services regroupés (CCSR), qui lançait récemment Véga. Cette application Web de dernière génération permet à ses abonnés de gérer efficacement les données sur les produits dangereux entreposés par leur organisation, conformément aux normes et lois en vigueur.

En tant que fournisseur ayant développé ce projet, Savoir-faire Linux vous suggère fortement — sans aucun parti-pris LOL — de voter pour le Centre collégial des services regroupés avant le 27 mai. Comme vous allez le constater en lisant ce qui suit, ce ne sont pas les bonnes raisons qui manquent, que ce soit pour l’amour du logiciel libre, du langage Python, des applications Web utiles et bien faites, des normes de sécurité publique, de l’éducation supérieure ou de la mutualisation!

Votez maintenant!

Un peu d’histoire*

Centre collégial de services regroupésEn 2001, le CCSR met sur pied une banque de fiches signalétiques de produits contrôlés, Reprofics, pour en centraliser la mise à jour. Reprofics est d’abord accessible aux abonnés par l’entremise d’un logiciel propriétaire. Au tournant de 2008, ce logiciel n’est plus développé, ni supporté. De nombreux établissements continuent néanmoins de l’utiliser.

Des démarches sont entreprises pour l’adoption d’un nouveau logiciel, mais aucun des produits analysés ne convient aux utilisateurs. Le Cégep régional de Lanaudière amorce alors le développement d’un logiciel d’inventaire des produits contrôlés sous la supervision d’un chimiste, en collaboration avec des stagiaires. Au terme de ce développement, le Cégep propose au CCSR d’intégrer la banque de fiches au logiciel d’inventaire : la première version de Véga voit le jour.

Cette première application Web réalisée en .NET par des étudiants permet de répertorier les produits se trouvant dans un local donné et de les relier aux fiches signalétiques de Reprofics. Une autre interface permet de consulter la banque de fiches. Des fonctionnalités s’ajoutent au fil des ans (impression d’étiquettes en quatre formats, intégration de plans en PDF, aide à la préparation de laboratoires).

En 2012, Véga n’est cependant utilisée que par quelques établissements en phase pilote et n’est toujours pas commercialisable. En raison de son développement par des stagiaires sur une courte période, de la multiplication des modules et du manque de cohérence du code, faire évoluer Véga devient difficile, tant en ce qui a trait à l’apparence et à l’adaptabilité (téléphone, tablette) qu’à l’optimisation des fonctionnalités.

Le CCSR, propriétaire de Reprofics, rachète alors les droits de Véga au Cégep régional de Lanaudière et entreprend la refonte de l’application dans le but de la faire évoluer. Il met sur pied un comité d’utilisateurs responsable de proposer et de prioriser les adaptations et les développements.

Véga, la refonte

La refonte de Véga a été réalisée de janvier 2013 à janvier 2015 en collaboration avec Savoir-faire Linux. La nouvelle solution Web, développée en python avec le cadre d’applications Django, maintient et améliore les fonctionnalités existantes, en plus d’en proposer de nouvelles :

  • Banque de fiches – Accès aux fiches sommaires normalisées réalisées à partir des fiches d’origine (PDF), facilitant la tâche des utilisateurs des produits contrôlés en regroupant sur une même feuille toute l’information relative à l’identification du produit, à sa classification SIMDUT, à l’équipement de protection individuelle requis lors de l’utilisation, à sa manutention, à son entreposage et aux premiers soins à donner en cas d’urgence; ◤vidéos◥
  • Étiquettes – Production d’étiquettes conformes à la loi pour chaque produit dans tout format d’étiquette possible; (voir figure 1 plus bas)
  • Inventaire – Gestion, dans un emplacement accessible à tout intervenant autorisé, de l’inventaire des produits dangereux reliés aux fiches signalétiques des produits; ◤vidéos◥
  • Mesures d’urgence – Centralisation des plans de contingence concernant les produits dangereux et des plans détaillés des bâtiments, possibilité de les imprimer à même l’interface Web et de les envoyer sous forme de fichiers PDF aux services d’urgence, possibilité de créer un compte d’accès spécial permettant aux intervenants externes de récupérer en tout temps l’information et les plans les plus récents.
  • Mobilité et consultation multi-plateformes – Prise d’inventaire et gestion des fiches signalétiques et accès facilités par l’usage de tablettes et de téléphones intelligents.
  • Accès en mode consultation – Accès direct à partir de n’importe quel poste informatique d’une organisation membre (filtre par adresses IP), une fonctionnalité appréciée des professeurs et étudiants.

En conclusion, Véga est un projet numérique novateur qui tire parti des technologies de l’information afin d’améliorer l’efficacité et la transparence de la gestion des produits dangereux au sein des organisations. Le recours aux technologies ouvertes python et Django donne au CCSR le contrôle du code et de la propriété intellectuelle et assure le développement futur de l’application en fonction de l’évolution des besoins des utilisateurs, sans frais de licence et sans dépendre d’un fournisseur.

Image
Figure 1 – Exemple de formats d’impression d’étiquettes

Consultant technique Odoo: un engagement qui a du sens

jordi-rieraCela fait maintenant six mois que j’ai rejoint l’équipe des solutions ERP au sein de Savoir-faire Linux. Dirigé par Maxime Chambreuil, notre département a pour mission de fournir des solutions métiers efficaces et personnalisées en s’appuyant sur le logiciel libre de gestion d’entreprises Odoo. Je n’avais alors aucune connaissance de ce framework mais, armé de sept ans d’expérience de Python, Django, PyQt et les cadres d’applications maison des entreprises pour lesquelles j’avais travaillé, j’ai pris le pingouin par le bec sans trop de pression. Après tout, il s’agissait juste d’un environnement logiciel de plus à apprendre. En réalité, le pingouin cachait son jeu et le défi était ailleurs. C’est ainsi que j’ai découvert le sens caché du métier.

Commençons par les fondamentaux. Odoo est une application ERP développée dans ce plat pays qu’est la Belgique, basé sur Python pour la logique, XML pour les vues et d’autres technologies qui lui sont spécifiques. Par exemple, l’ORM et le moteur d’édition des vues sont nouveaux. Même si l’on n’a pas réinventée la roue, quelques améliorations y ont été apportées au passage. On y trouve ainsi un système d’héritage qui évite toute prise de tête avec les importations récursives et un système de vues permettant d’éditer celles-ci en tout point sans avoir à prévoir de point d’entrée en amont.

En plus de ces technologies, Odoo tire sa puissance d’un très grand nombre de modules gravitant autour du cœur de l’application. Ces modules permettent d’y ajouter des fonctions telles que la gestion de la comptabilité et du recrutement, les chaînes de ventes et d’achat, etc. En fait, toutes les fonctions clés d’une solution ERP répondent à l’appel.

En passant d’OpenERP à Odoo, la solution s’est également forgé une nouvelle arme : un gestionnaire de site web hautement personnalisable, prêt à inclure une boutique en ligne, un CRM et un blogue. En bref, c’est une solution complète et solide pour la gestion d’entreprise.

En réalité, le pingouin cachait son jeu et le défi était ailleurs…

Si Odoo était une voiture, notre travail, en tant que consultant technique, ne consisterait pas à la fabriquer. Ça, nos amis de Belgique s’en occupent déjà. Nous nous concentrerions plutôt sur l’installation de phares directionnels pour les clients qui roulent la nuit en montagne, ou sur l’ajout d’un système d’ouverture de coffre automatique pour les familles avec un siège de bébé et des provisions plein les bras.

La complémentarité d'Odoo, Savoir-faire Linux et leurs ses clientsNotre mission première, ef effet, c’est de bien comprendre les besoins des clients et leur fournir toutes les options qu’il faut, là ou il faut. Nous devons faire en sorte que la voiture devienne leur voiture. Mon principal défi, en tant qu’intégrateur et développeur appuyé par mes collègues consultants fonctionnels, c’est d’être à l’écoute et totalement ouvert d’esprit. Ce n’est qu’ensuite que mon expérience sera mobilisée afin d’assembler le mieux possible la solution qui rendra la vie plus facile (et la plus rentable) à mon client.

Certains jugeront peut-être cette finalité triviale, pas assez glamour à leur goût et c’est leur droit. En ce qui me concerne, ma satisfaction de consultant se nourrit avantageusement de celle des clients auxquels je livre un système informatique fonctionnel répondant parfaitement à leurs besoins. Leur reconnaissance est mon ultime récompense, mais cela ne m’empêche pas, au passage, de continuer à développer mon expertise dans de multiples directions. Et puis, il y a le plaisir d’œuvrer dans une communauté ouverte et d’y contribuer. Tout cela est très enrichissant!

Analyseur logique : visualiser la latence entre deux signaux numériques en temps réel avec sigrok et matplotlib

Salae Logic AnalyzerDans mon billet précédent, je décrivais comment manipuler avec Python les données extraites d’un analyseur logique Saleae afin de visualiser la latence entre deux signaux numériques et en déduire la gigue temporelle de l’un d’entre eux. En conclusion, j’émettais l’hypothèse que le SDK de Saleae pourrait nous permettre de récupérer des informations sur les signaux en temps réel et non plus par l’intermédiaire d’un fichier CSV exporté. Mais au final, c’est un logiciel libre plus générique qui nous a fourni la meilleure solution.

La solution de Saleae et son SDK

Saleae propose aux développeurs deux solutions :

  • une API (en bêta à l’heure actuelle) qui permet uniquement de contrôler leur logiciel de visualisation depuis une socket.
  • un SDK qui permet d’étendre leur logiciel et écrire son propre analyseur de protocole.

Nous aurions pu a priori nous intéresser au SDK et écrire un analyseur qui exporte à la volée la latence entre deux signaux définis, mais cette solution est dépendante du logiciel de Saleae et de son évolution, ce qui nous garantit une très faible pérennité. De plus, le logiciel de visualisation de Saleae n’a pas pour vocation d’être utilisé avec un autre analyseur logique que ceux qu’ils produisent. Nous cherchions donc une solution plus générique et permanente.

Sigrok: une suite logicielle open-source pour les analyseurs logiques

C’est lors d’une discussion entre collègues qu’Emeric Vigier m’a mit sur la piste d’un logiciel nommé Sigrok. Ayant pour objectif de fournir une solution libre et générique pour les analyseurs logiques, Sigrok est une suite logicielle permettant d’extraire les données collectées par divers types d’analyseurs et de les afficher, voire de les traiter, à l’aide de décodeurs de protocole.

Cette suite se compose de plusieurs sous-projets :

  • libsigrok : une librairie écrite en C qui standardise l’accès aux pilotes des différents analyseurs.
  • libsigrokdecode : une librairie écrite en C qui fournit une API pour le décodage de protocole. Les décodeurs sont écrits en Python (>= 3).
  • Sigrok-cli : une interface en ligne de commande pour manipuler Sigrok.
  • PulseView : une interface graphique en Qt pour manipuler Sigrok.
  • Fx2lafw : Sigrok fournit également une implémentation open source du firmware des puces Cypress FX2 qui est la puce utilisé entre autre par Saleae dans toutes les déclinaisons de ses analyseurs logiques hormis le Logic Pro 16. Ce firmware permet de programmer le FPGA pour qu’il fonctionne comme un simple analyseur logique matériel.

Sigrok : exemple d’utilisation

Un exemple de cette suite mise bout à bout sera plus parlant qu’un long discours. Nous allons donc utiliser PulseView pour capturer et visualiser les signaux d’un analyseur logique.

À l’ouverture PulseView dans sa version 0.2.0 ressemble à ceci :
[cliquez sur les images pour les agrandir]

pulseview01

Nous allons commencer une capture en laissant le périphérique de démonstration générer des signaux aléatoires :

pulseview02

Nous allons ensuite ajouter un décodeur assez simple qui calcule le rapport cyclique d’un signal numérique :

pulseview03

Chaque décodeur dispose de ses options. Dans notre cas nous allons simplement définir le canal sur lequel nous voulons appliquer le décodeur :

pulseview04

Le calcul du rapport cyclique est appliqué sur le canal et reporté directement dans l’interface de PulseView :

pulseview05

Sigrok : écriture d’un décodeur pour le calcul de la latence entre deux signaux numériques

Ce qui suit est basé sur la libsigrok et la libsigrokdecode dans leurs version 0.3.0.
Chaque décodeur de protocole est un module Python qui possède son propre sous-répertoire dans le répertoire de décodeurs libsigrokdecode.

Un décodeur se compose de deux fichiers :

  • __init__.py : Ce fichier est requis pour l’initialisation du décodeur et contient une simple description du protocole.
  • pd.py : Ce fichier contient des métadonnées sur le décodeur, et son code, la plupart du temps implémenté dans la méthode decode()

Nous allons nous intéresser au fichier pd.py contenant le code de notre décodeur. L’API de la libsigrokdecode nous fournit toutes les informations sur les signaux capturés.

Rappelons nous que pour calculer la latence entre deux signaux numériques, notre logique est de considérer l’un des signaux comme une horloge de référence, et l’autre comme une résultante de ce premier. Les deux étant liés, à chaque transition d’état du signal d’horloge, le signal résultant changera aussi d’état avec une latence plus ou moins variable. Nous parlerons de la fluctuation de cette latence plus loin.

Les options du décodeur

La première chose à faire est donc de permettre à notre décodeur de définir quel canal correspond au signal d’horloge et quel canal correspond au signal résultant. La classe du décodeur permet justement de définir quelques attributs précisant ses options, notamment celle permettant à l’utilisateur de choisir les canaux :

class Decoder(srd.Decoder):
   # ...
   channels = (
      {'id': 'clk', 'name': 'Clock', 'desc': 'Clock reference channel'},
      {'id': 'sig', 'name': 'Resulting signal', 'desc': 'Resulting signal controlled by the clock'},
   )
   ...

La méthode decode()

La seconde étape va être d’implémenter le contenu de la méthode decode(). Cette méthode est appelé par la libsigrokdecode chaque fois qu’un nouveau bloc de données à traiter est disponible.

Chaque bloc est en fait un échantillon dépendant de la fréquence d’échantillonnage de nos signaux. Par exemple pour une valeur d’échantillonnage de 100 Hz, nous obtiendrons 100 blocs de données par seconde. Ces blocs de données contiennent le numéro de l’échantillon actuel, ainsi que l’état des différents signaux à cet instant.

À partir de ces informations, il est ainsi très facile d’implémenter une machine à état qui va noter à quel échantillon à eu lieu la transition du signal d’horloge et celle du signal résultant. Le nombre d’échantillons écoulés entre les deux, multiplié par la valeur de la fréquence d’échantillonnage, va nous donner la latence exprimée en secondes.

Dans sa version simplifiée, notre machine à état ressemble à cela :

def decode(self, ss, es, data):

    self.oldpin, (clk, sig) = pins, pins

    # State machine:
    # For each sample we can move 2 steps forward in the state machine.
    while True:
        # Clock state has the lead.
        if self.state == 'CLK':
            if self.clk_start == self.samplenum:
                # Clock transition already treated.
                # We have done everything we can with this sample.
                break
            else:
                if self.clk_edge(self.oldclk, clk) is True:
                    # Clock edge found.
                    # We note the sample and move to the next state.
                    self.clk_start = self.samplenum
                    self.state = 'SIG'

        if self.state == 'SIG':
            if self.sig_start == self.samplenum:
                # Signal transition already treated.
                # We have done everything we can with this sample.
                break
            else:
                if self.sig_edge(self.oldsig, sig) is True:
                    # Signal edge found.
                    # We note the sample, calculate the latency
                    # and move to the next state.
                    self.sig_start = self.samplenum
                    self.state = 'CLK'
                    # Calculate and report the latency.
                    self.putx((self.sig_start - self.clk_start) / self.samplerate)

    # Save current CLK/SIG values for the next round.
    self.oldclk, self.oldsig = clk, sig

Les sorties de notre décodeur

La libsigrokdecode propose différentes façons de remonter les informations de notre décodeur. Une méthode register() permet d’enregistrer les sorties que notre décodeur génère. Chaque sortie a un type défini; par exemple, le type OUTPUT_ANN est utilisé pour définir une sortie de type annotation qui sera représentée dans PulseView par les boîtes graphiques que nous avons vues précédemment avec le décodeur de rapport cyclique.

Pour notre décodeur, nous voulons principalement deux types de sorties:

  • une sortie de type annotation (OUTPUT_ANN) pour visualiser la latence mise en forme dans PulseView,
  • et une sortie de type binaire (OUTPUT_BINARY) pour sortir les valeurs de latence brute sans mise en forme afin d’être analysé.

La version finale de notre décodeur inclut également une sortie de type métadonnée (OUTPUT_META) rapportant des statistiques sur les signaux manqués, mais ce n’est pas important ici.

Nos deux sorties donc sont définies dans notre décodeur comme suit :

self.out_ann = self.register(srd.OUTPUT_ANN)
self.out_bin = self.register(srd.OUTPUT_BINARY)

Pour reporter des informations sur ces sorties nous utilisons la méthode put() qui a pour prototype :

put(debut_echantillon, fin_echantillon, type_de_sortie, donnees)

type_de_sortie est une de nos deux méthodes enregistrées au préalable (out_ann, out_bin).

Pour reporter la latence entre deux signaux en utilisant le type annotation nous pourrons par exemple écrire :

put(clk_start, sig_start, out_ann, [0, [ma_latence]])

Les résultats obtenus avec notre décodeur de latence

Voici un exemple des résultats obtenus avec notre décodeur dans PulseView :
pulseview06

Et les résultats obtenus avec sigrok-cli dans sa version 0.5.0 et la sortie binaire pour avoir les valeurs de latence brute :
sigrok-cli

Visualisation des données en temps réel pour en déduire la gigue temporelle

Comme nous venons de le voir, sigrok-cli nous permet de sortir les valeurs de latence brute sur la console en temps réel. Nous allons maintenant nous intéresser aux variations de cette latence. En effet, rien ne nous garantit que la latence entre ces deux signaux sera constante.

Considérant que le signal d’horloge est périodique et sans fluctuation, en théorie, le signal résultant devrait l’être aussi et la latence entre ces deux signaux devraient être constante. Si ce n’est pas le cas, c’est qu’il y a une fluctuation de cette latence que nous avions décrite dans le précédent article comme la gigue temporelle d’un signal, et c’est ce que nous voulons visualiser maintenant.

Nous pouvons donc imaginer récupérer ces valeurs à la volée et les mettre en forme dans un graphique. Pour cela, nous allons encore une fois écrire un script en Python.

Je me suis intéressé à la librairie matplotlib et son module d’animation, qui propose une méthode FuncAnimation() permettant de définir une fonction à appeler pour mettre à jour le graphique à chaque fois que de nouvelles données sont disponibles. Cette fonction prend en paramètre la figure sur laquelle nous travaillons, la fonction d’animation à appeler et l’ensemble de données à traiter.

anim = animation.FuncAnimation(fig, animate, frames=data_gen)

Ces données peuvent être de la forme d’un générateur Python qui va très bien de paire avec la lecture d’un flux de données (merci à Guillaume Roguez pour m’avoir présenté ce type d’objet).

Ainsi à chaque fois qu’une nouvelle latence sera écrite dans le flux, notre générateur récupérera une nouvelle donnée et la fonction d’animation sera appelée.

Voici à quoi ressemble le code du générateur :

# The data generator take its
# input from file or stdin
def data_gen():
    while True:
        line = fd.readline().strip()
        if line:
            yield line

Notre fonction d’animation va, si besoin est, mettre à jour l’abscisse pour visualiser toutes les latences, et ajouter la nouvelle valeur fournie par le générateur.

# The update graph function
def animate(data):
    global x_max, x_min, x, y

    try:
        # we must recalculate the abscissa range
        x_new = float(data)
        if x_max is None or x_new > x_max:
            x_max = x_new
        if x_min is None or x_new < x_min:
            x_min = x_new
        ax.set_xlim(x_min, x_max)

        # add the new plot coordinate
        x.append(x_new)
        y.append(0)
        line.set_data(x, y)

        return line,

    except KeyboardInterrupt:
        print("leaving...")
&#91;/code&#93;

Finalement, il nous reste plus qu'à éxécuter <code>sigrok-cli</code> avec notre décodeur de latence et à récupérer ces valeurs dans notre script de visualisation.


sigrok-cli -d fx2lafw --config samplerate=24MHz --samples 2M -C 1,2 -P jitter:clk=1:sig=2 -B jitter | rt-draw.py

Ce qui nous donne le résultat final suivant et qui nous permet de visualiser la gigue temporelle du signal résultant :

rt_draw