Cours:Oscillogbf : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
(Signal/Slot avec PySide2)
(exemple pour différents widgets)
Ligne 85 : Ligne 85 :
 
==exemple pour différents widgets==
 
==exemple pour différents widgets==
 
*'''<big>QPushButton</big>'''
 
*'''<big>QPushButton</big>'''
**window.leBouton = window.findChild(QPushButton, "monWidgetBouton")
+
**window.monWidgetBouton.clicked.connect(maFonction)
**window.leBouton.clicked.connect(maFonction)
 
 
*'''<big>QDial/QScrollBar/QSlider</big>''' (hérite de QAbstractSlider)
 
*'''<big>QDial/QScrollBar/QSlider</big>''' (hérite de QAbstractSlider)
**window.leSlider = window.findChild(QAbstractSlider, "monWidgetDial")
+
**window.monWidgetDial.valueChanged.connect(getValue)<source lang=python>
**window.leSlider.valueChanged.connect(getValue)<source lang=python>
 
 
def getValue(value):
 
def getValue(value):
 
     print(f"position du slider : {value}")
 
     print(f"position du slider : {value}")
 
</source>
 
</source>
**window.leSlider.setSliderPosition(0)
+
**window.monWidgetDial.setSliderPosition(0)
 
*'''<big>QLabel</big>'''
 
*'''<big>QLabel</big>'''
 
**window.monLabel = window.findChild(QLabel, "monWidgetLabel")
 
**window.monLabel = window.findChild(QLabel, "monWidgetLabel")

Version du 11 février 2025 à 15:09

Voici un principe pour réaliser une interface graphique en python avec la librairie Qt pour dialoguer avec différents équipements (oscilloscope/gbf/...)


python et Qt

Mise en place avec QtCreator

  • créer un nouveau projet :
    • Application (Qt for Python) Window UI
    • pas d'importance pour PySide2 ou PySide6, on va remplacer après
    • choisir la version Python 3.x.x sans Virtual Environnement
  • ouvrir le fichier widget.py
  • remplacer par :
import sys
# communication avec le matériel de mesure
import pyvisa
# modules QT que l'on souhaite utiliser
# à compléter en fonction des besoins
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import QApplication, QWidget, QFileDialog, QPushButton, QDial, QAbstractSlider
from PySide2.QtUiTools import QUiLoader


if __name__ == "__main__":
    # chargement du fichier form.ui
    # qui correspond à l'interface graphique
    loader = QUiLoader()
    app = QtWidgets.QApplication(sys.argv)
    window = loader.load("form.ui", None)
    window.show()

    # initialisation de la librairie pyVisa
    materiel=pyvisa.ResourceManager()
    # print(materiel.list_resources())

    # exemple pour se connecter sur un appareil par IP
    # gbf=materiel.open_resource('TCPIP::192.168.0.236::INSTR')

    sys.exit(app.exec_())

Signal/Slot avec PySide2

  • dans un 1er temps il faut créer un objet dans l'interface graphique, par exemple "monWidgetBouton" de type QPushButton
  • ensuite on connect le signal du widget sur la fonction que l'on souhaite :
    window.monWidgetBouton.clicked.connect(maFonction)
    
  • Ce qui donne :
    import sys
    # communication avec le matériel de mesure
    import pyvisa
    # modules QT que l'on souhaite utiliser
    # à compléter en fonction des besoins
    from PySide2 import QtCore, QtGui, QtWidgets
    from PySide2.QtWidgets import QApplication, QWidget, QFileDialog, QPushButton, QDial, QAbstractSlider
    from PySide2.QtUiTools import QUiLoader
    
    # fonction qui sera exécutée lors d'un clic
    def maFonction():
        print("clic !")
    
    if __name__ == "__main__":
        # chargement du fichier form.ui
        # qui correspond à l'interface graphique
        loader = QUiLoader()
        app = QtWidgets.QApplication(sys.argv)
        window = loader.load("form.ui", None)
        window.show()
    
        # associer une action à un QPushButton
        window.monWidgetBouton.clicked.connect(maFonction)
    
        # initialisation de la librairie pyVisa
        materiel=pyvisa.ResourceManager()
        # print(materiel.list_resources())
    
        # exemple pour se connecter sur un appareil par IP
        # gbf=materiel.open_resource('TCPIP::192.168.0.236::INSTR')
    
        sys.exit(app.exec_())
    

exemple pour différents widgets

  • QPushButton
    • window.monWidgetBouton.clicked.connect(maFonction)
  • QDial/QScrollBar/QSlider (hérite de QAbstractSlider)
    • window.monWidgetDial.valueChanged.connect(getValue)
      def getValue(value):
          print(f"position du slider : {value}")
      
    • window.monWidgetDial.setSliderPosition(0)
  • QLabel
    • window.monLabel = window.findChild(QLabel, "monWidgetLabel")
    • window.monLabel.setText("message")

réaliser une action périodique

https://doc.qt.io/qtforpython-5/PySide2/QtCore/QTimer.html

from PySide2 import QtCore
from PySide2.QtCore import QTimer

def actionPeriodique():
    print("tic")

if __name__ == "__main__":
    timer = QTimer()
    timer.timeout.connect(actionPeriodique)
    timer.start(500)

dialoguer avec les appareils

initialisation

  • il faut initialiser la librairie
    materiel=pyvisa.ResourceManager()
    
  • se connecter sur un équipement
    gbf=materiel.open_resource('TCPIP::192.168.0.236::INSTR')
    
  • on peut ensuite :
    • envoyer des commandes à l'équipement :
      gbf.write(":OUTP1 ON")
      
    • demander une valeur à l'équipement :
      gbf.query("*IDN?")
      
  • Exemple :
    materiel=pyvisa.ResourceManager()
    gbf     =materiel.open_resource('TCPIP::192.168.0.236::INSTR')
    gbf2    =materiel.open_resource('USB0::6833::1603::DG8A231301537::0::INSTR')
    oscillo =materiel.open_resource('TCPIP::192.168.0.73::INSTR')
    print(gbf.query("*IDN?"))
    print(oscillo.query("*IDN?"))
    

commandes génériques

Les commandes suivantes devraient être valables pour tous les équipements :

commande paramètre description
*CLS clear : initialise la communication
*IDN? retourne l'identifiant de l'appareil
*OPC? operation complete : indique si l'opération précédente est terminée (1) ou non (0)

gbf DG822

Le fichier suivant contient l'ensemble des commandes pour le Rigol DG822 : dg822.pdf

Voici quelques commandes dont vous pourrez avoir besoin :

commande description exemple
 :OUTPx ON/1/OFF/0 activer la sortie gbf.write(":OUTP1 ON")
 :SOURx:FREQ value modifier la fréquence de la sortie gbf.write(":SOUR1:FREQ")
 :SOURx:APPL:SIN freq,amp,offset,phase générer un sinus à l'amplitude, offset, déphasage et fréquence souhaitée gbf.write(":SOUR1:APPL:SIN 100,3,2,1")
 :SOURx:APPL:PULS freq,amp,offset,phase générer un signal carré à l'amplitude, offset, déphasage et fréquence souhaitée gbf.write(":SOUR1:APPL:SIN 100,3,2,0")
 :SOURx:APPL:SQU freq,amp,offset,phase générer un signal PWM à l'amplitude, offset, déphasage et fréquence souhaitée gbf.write(":SOUR1:APPL:PULS 100,5,2.5,0")
 :SOURx:PULS:DCYC duty modifie le rapport cyclique d'un signal PWM gbf.write(":SOUR1:PULS:DCYC 45")


Exemple :

import sys
# communication avec le matériel de mesure
import pyvisa
# modules QT que l'on souhaite utiliser
# à compléter en fonction des besoins
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import QApplication, QWidget, QFileDialog, QPushButton, QDial, QAbstractSlider
from PySide2.QtUiTools import QUiLoader

# fonction qui sera exécutée lors d'un clic
def maFonction():
    print("clic !")
    gbf.write(":OUTP1 ON")
    gbf.write(":SOUR1:APPL:PULS 1000,5,2.5,0")

# fonction qui sera exécutée lors de la modification du slider
def getValue(value):
    print(f"position du slider : {value}")
    gbf.write(f":SOUR1:PULS:DCYC {value}")


if __name__ == "__main__":
    # chargement du fichier form.ui
    # qui correspond à l'interface graphique
    loader = QUiLoader()
    app = QtWidgets.QApplication(sys.argv)
    window = loader.load("form.ui", None)
    window.show()

    # associer une action à un QPushButton
    window.leBouton = window.findChild(QPushButton, "monWidgetBouton")
    window.leBouton.clicked.connect(maFonction)

    # associer une action à un QDial (hérite de QAbstractSlider)
    window.leSlider = window.findChild(QAbstractSlider, "monWidgetDial")
    window.leSlider.valueChanged.connect(getValue)

    # initialisation de la librairie pyVisa
    materiel=pyvisa.ResourceManager()
    # print(materiel.list_resources())

    # exemple pour se connecter sur un appareil par IP
    gbf    =materiel.open_resource('TCPIP::192.168.0.236::INSTR')
    #oscillo=materiel.open_resource('TCPIP::192.168.0.73::INSTR')
    print(gbf.query("*IDN?"))
    #print(oscillo.query("*IDN?"))

    sys.exit(app.exec_())

oscillo DS1104Z

Media:MSO_DS1000Z_ProgrammingGuide_EN.pdf

Voici quelques commandes dont vous pourrez avoir besoin :

commande description exemple
 :RUN
 :STOP
 :AUT
 :SING
run / stop / autoset / single oscillo.write(":STOP")
 :CHANnelx:DISPlay ON/1/OFF/0 enable/disable channel oscillo.write(":CHAN1:DISP ON")
 :CHANnel<n>:COUPling AC/DC/GND oscillo.write("")
 :CHANnel<n>:PROBe gain réglage du gain de la sonde (à modifier avant scale et offset) oscillo.write("")
 :CHANnel<n>:SCALe calibre de tension (à modifier avant l'offset) oscillo.write("")
 :CHANnel<n>:OFFSet oscillo.write("")
 :TIMebase[:MAIN]:SCALe base de temps en s oscillo.write(":TIMebase:MAIN:SCALe 0.001")
NORMal|SINGle oscillo.write("")
 :TRIGger:EDGe:SOURce CHANx oscillo.write("")
 :MEASure:ITEM? PDUTy,CHANnel1 oscillo.write("")
oscillo.write("")


Exemple :

oscillo.write(":CHANnel1:DISPlay ON")
oscillo.write(":CHANnel2:DISPlay OFF")
oscillo.write(":CHANnel3:DISPlay OFF")
oscillo.write(":CHANnel4:DISPlay OFF")
oscillo.write(":CHANnel1:COUPling DC")
oscillo.write(":CHANnel1:PROBe 1")
oscillo.write(":CHANnel1:SCALe 1")
oscillo.write(":CHANnel1:OFFSet -2")
oscillo.write(":TIMebase:MAIN:SCALe 0.001")
oscillo.write(":TRIGger:SWEep NORMal")
oscillo.write(":TRIGger:EDGe:SOURce CHAN1")
duty=int(float(oscillo.query(":MEASure:ITEM? PDUTy,CHANnel1"))*100)
print(duty)

multimètre DM3058

liens

Tests

banc de mesure  : 1 scope DS1074 + 1 gbf DG822


le script (basique ...) qui gère le tout :


#!/bin/bash

IPSCOPE=192.168.1.111

freq=100

while true; do
      # 1 sinus ampl=5V, offset nul, dephasage nul
      ./dg822_write.py ":sour1:appl:harm $freq,5,0,0"
      sleep 2
      # demande un AUTo mode au scope
      lxi scpi -a $IPSCOPE "AUT"
      sleep 5
      let "freq += 100"
      done

les commandes python :


#!/usr/bin/python3

import sys
import pyvisa
rm=pyvisa.ResourceManager()
inst=rm.open_resource('USB0::6833::1603::DG8A231301537::0::INSTR')

print("commande = ",sys.argv[1])
commande=sys.argv[1]

inst.write(commande)