Comment parler à votre portée

Auparavant, il s’agissait uniquement d’équipements de test haut de gamme dotés d’une sorte de port de télécommande. Mais de nos jours, ils sont assez courants. Historiquement, les équipements de test utilisaient IEEE-488 (également connu sous le nom de GPIB ou, de l’auteur, HPIB). Mais aujourd’hui, votre appareil communiquera probablement via un port USB, un port série ou une connexion LAN. On pourrait penser que chaque instrument a des particularités uniques, et le contrôler ne serait en rien comme contrôler un autre équipement, en particulier celui d’une autre entreprise. Ce serait à moitié vrai. Chaque fournisseur et même modèle possède en effet son langage de commande unique. Des efforts importants ont été déployés pour standardiser certains aspects du contrôle des instruments de test, et vous pouvez rapidement écrire du code pour contrôler des éléments sur n’importe quelle plate-forme en utilisant de nombreux langages de programmation différents. Dans quelques articles, je vais vous montrer à quel point cela peut être simple.

La clé est d’utiliser VISA. Ce protocole est défini par la Fondation IVI qui vous permet de parler aux instruments quelle que soit la manière dont ils communiquent. Vous devez créer une adresse indiquant à la bibliothèque VISA comment trouver votre appareil. Par exemple : « TCPIP ::192.168.1.92 ::INSTR ». Mais une fois que vous avez cela, il est facile de parler à n’importe quel instrument, n’importe où.

Je dis que penser qu’il s’agit d’un problème est à moitié vrai, car parler à la boîte est une tâche parmi les deux que vous devez accomplir. L’autre est quoi dire à la boîte et ce qu’elle vous répondra. Il existe quelques normes dans ce domaine, mais c’est là que l’on rencontre des problèmes.

Rigol

L’interface Web de Rigol n’est qu’une copie de l’écran tactile

En 2015, j’ai acheté un Rigol DS1052E et je voulais jouer avec la télécommande via USB. Le code résultant (sur GitHub) utilise Qt et s’attend à ouvrir un port USB. Le langage de commande est simple et, utilement, comprend des commandes qui simulent l’appui sur des touches du panneau avant. Je découvrirais que mon dernier oscilloscope Rigol, un DHO924S, ne fournit pas ces commandes KEY, pas plus que mon DS1154z.

Ainsi, pour une version 2023, je voulais éliminer une partie de la complexité pour simplifier un futur basculement entre différentes portées. Je regardais une revue vidéo d’un oscilloscope de la série DHO900, et le critique s’est plaint que même si l’oscilloscope afficherait son écran via une interface Web (et que vous pouvez le faire fonctionner via cet écran tactile virtuel), il n’avait pas accès aux boutons à côté de l’écran lors de l’utilisation de l’oscilloscope à distance. J’ai réalisé qu’il serait possible d’écrire un petit programme pour contrôler l’oscillateur et fournir les contrôles « manquants » sous la forme d’un panneau qui pourrait être placé à côté de l’interface Web de l’oscillateur.

Python

Comme je voulais également l’utiliser dans des scripts et que je venais de sortir du badge Hackaday Supercon, qui utilisait MicroPython, j’ai décidé de faire tout cela en Python. Mon plan général d’attaque était simple :

  • Utilisez VISA pour vous connecter à l’oscilloscope
  • Résumez les commandes SCPI directes à l’aide de méthodes ou de propriétés Python dans une classe qui représente la portée
  • Créer une interface graphique à utiliser à côté de l’interface Web

Cet article concerne les deux premiers éléments. Je couvrirai l’interface graphique la prochaine fois. Cependant, je n’ai pas totalement intégré l’intégralité du jeu de commandes SCPI dans la classe Python. Au lieu de cela, j’ai simplement fourni ce dont j’avais besoin pour la tâche à accomplir. Comme vous le verrez, il est facile d’ajouter ce que vous voulez.

PyVisa

La première chose à faire était d’installer PyVisa. Cela semble être tout ce dont vous avez besoin, mais ce n’est pas le cas. Au lieu de cela, il s’agit d’un wrapper autour d’un « vrai » backend VISA. Deux choix populaires sont NI-VISA de National Instruments (gratuit, bien que vous deviez probablement vous inscrire) ou le pyvisa-py open source. Essaye ça:

pip3 install pyvisa pyvisa-py

Notez que, désormais, pyvisa-py prend en charge TCP/IP, GPIB, USB et série. Cela couvre la plupart des bases, mais si vous avez besoin de quelque chose de différent, vous devrez peut-être essayer un autre backend.

Lorsque vous installez pyvisa, il devrait laisser un binaire (dans ~/.local/bin pour moi) appelé pyvisa-info. Exécutez-le, et il vous dira s’il trouve des backends et vous indiquera également d’autres éléments que vous devrez peut-être installer. Par exemple, je n’ai pas d’instruments de bus GPIB et je n’ai pas installé ce pilote. Il m’avertit donc que je dois l’installer si je souhaite communiquer avec des périphériques GPIB. Je ne le fais pas, donc ça va. Si vous recevez de mauvais messages d’erreur de pyvisa-info, vous devez les corriger avant d’essayer d’aller plus loin.

Bien que SCPI définisse certaines commandes, il s’agit principalement de hasards. Par exemple, un oscilloscope Tektronix peut utiliser CURVe? pour obtenir des données de forme d’onde, alors qu’un Rigol pourrait utiliser WAV:DATA? et d’autres marques n’auront peut-être besoin que de DATA?. Il y a cependant certaines choses sur lesquelles vous pouvez généralement compter.

Lorsque vous voyez un point d’interrogation (comme :WAV:DATA?) vous attendez que la portée (ou quoi que ce soit) vous réponde. Lorsque vous ne voyez pas de point d’interrogation, vous envoyez simplement des données. De plus, quand vous voyez quelque chose comme CURVe? écrit, cela signifie que vous êtes autorisé à omettre le « e », ce qui permet d’économiser un peu de temps et de bande passante de communication. Donc CURV? et CURVE? c’est la même chose.

Utiliser PyVISA

Pour ouvrir une connexion à un scope en Python, vous devrez d’abord importer pyvisa. Après cela, vous créerez un gestionnaire de ressources et lui transmettrez une chaîne ouverte spéciale. Voici un extrait de ma classe d’abstraction de portée (trouvez tout sur GitHub) :

# do the connect
def connect(self,usb,cxstring):
   if usb==0:
      cxstr="TCPIP::"+cxstring+"::INSTR"
   else:
      cxstr="USB0::0x1AB1::0x044C::"+cxstring+"::INSTR"
   self.visa=pyvisa.ResourceManager('@py')
   self.scope=self.visa.open_resource(cxstr)
   self.connected=True

Dans ce cas, j’utilise un oscilloscope connu, donc je suppose que les identifiants USB seront les mêmes. Si vous utilisez un autre instrument, cela changera. Utilement, si vous ouvrez l’interface Web de Rigol, vous trouverez les deux chaînes de connexion écrites pour que vous puissiez les copier.

L’écran d’informations affiche les chaînes de connexion pour USB et TCP/IP

Le connect La fonction membre prend uniquement l’adresse IP ou le nom de la portée et remplit le reste. L’indicateur USB détermine s’il traite l’entrée comme une adresse IP ou un nom. L’argument du gestionnaire de ressources indique à la bibliothèque quel « backend » utiliser. Dans ce cas, j’utilise pyvisa-py (@py). Si vous omettez le @py chaîne, la bibliothèque utilisera la bibliothèque IVI qui fonctionnera avec des backends comme NI-VISA et d’autres bibliothèques spécifiques au fournisseur. S’il ne trouve pas de bibliothèque IVI, il utilisera pyvisa-py. Vous pouvez également transmettre un nom de chemin complet à la bibliothèque que vous souhaitez utiliser. Si vous préférez, vous pouvez définir le PYVISA_LIBRARY variable d’environnement à la place. Il existe également un fichier .pyvisarc que vous pouvez utiliser pour la configuration.

Puis-je voir une pièce d’identité ?

Presque tous les instruments prennent en charge la requête *IDN? pour renvoyer une chaîne d’identification. Le code définit deux méthodes pour envoyer des données à l’instrument. Le write La méthode envoie des données sans retour. Le query La méthode obtient un retour et coupe la nouvelle ligne de fin :

# send a query and return a response
def query(self,string):
   s=self.scope.query(string)
   if isinstance(s,str):
      return s[0:len(s)-1]
   else:
      return s

# just send
def write(self,string):
   return self.scope.write(string)

# get ID
def id(self):
   return self.query("*IDN?")

Une fois que vous avez cela, le reste consiste simplement à écrire de petites fonctions wrapper. Le seul vrai problème est que l’oscilloscope n’offre – comme j’ai pu le trouver – aucun moyen de simuler une touche du panneau avant. Cependant, certaines touches du panneau avant se comportent différemment selon les autres modes. Par exemple, chaque clic sur un bouton peut représenter une valeur différente lorsque l’oscilloscope est réglé sur un balayage lent ou rapide. Ou, pour un autre exemple, le bouton de niveau de déclenchement n’a pas de commande SCPI correspondante. Au lieu de cela, vous devez définir le niveau du déclencheur spécifique que vous souhaitez utiliser. Cela signifie que vous devez savoir quel mode de déclenchement est défini puisque chacun utilise une commande différente pour définir le niveau.

Si vous écrivez un script, ce n’est pas un gros problème car vous pouvez simplement définir le mode de déclenchement sur une valeur connue avant de définir correctement le niveau. Mais pour une interface utilisateur, c’est un problème car il faut écrire du code pour émuler le comportement de la portée. Ou vous pouvez simplement faire ce que j’ai fait. Faites une hypothèse raisonnable et vivez avec.

Le résultat jusqu’à présent

Juste à titre de test, j’ai écrit un petit script au bas de rigol_scope.py pour me connecter à une adresse IP fixe (puisqu’il ne s’agit que d’un test) et mettre le scope en mode unique toutes les 10 secondes.

if __name__=="__main__":
   import time
# test script
   scope=Scope()
   scope.connect(0,"192.168.1.92")
   while True:
      print("here we go again...")
      scope.single()
      time.sleep(10)
      print(scope.trig_status())

La prochaine étape est une interface graphique, mais cela attendra la prochaine fois. Cependant, écrire le code sous forme de classe comme celle-ci présente au moins trois avantages :

  1. Il serait facile de prendre en charge plusieurs étendues ; instanciez simplement plus d’objets
  2. Il est également facile de fournir la même interface abstraite à une portée différente
  3. Vous pouvez utiliser l’objet dans d’autres scripts ou programmes sans avoir à emporter de code GUI

En plus de cela, vous pouvez même prendre en charge plusieurs interfaces graphiques avec le même objet. Tout ce que vous améliorez ou corrigez dans l’objet scope profite à tous les programmes.

Ce n’est pas la première fois que nous examinons PyVISA. Ou, d’ailleurs, SCPI.

Image en vedette : Le joli nom « Onde sinusoïdale 10 kHz affichée sur un oscilloscope analogique » par [Pittigrilli].

François Zipponi
Je suis François Zipponi, éditorialiste pour le site 10-raisons.fr. J'ai commencé ma carrière de journaliste en 2004, et j'ai travaillé pour plusieurs médias français, dont le Monde et Libération. En 2016, j'ai rejoint 10-raisons.fr, un site innovant proposant des articles sous la forme « 10 raisons de... ». En tant qu'éditorialiste, je me suis engagé à fournir un contenu original et pertinent, abordant des sujets variés tels que la politique, l'économie, les sciences, l'histoire, etc. Je m'efforce de toujours traiter les sujets de façon objective et impartiale. Mes articles sont régulièrement partagés sur les réseaux sociaux et j'interviens dans des conférences et des tables rondes autour des thèmes abordés sur 10-raisons.fr.