{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Automatisiert Messen mit Python und dem IVI (VISA)-Standard\n", "Version 7.11.2020, S. Mack\n", "## Einleitung\n", "In der Automatisierung ist öft nötig, ein Messgerät mit einem Computer zu verbinden. Dabei soll der Computer erstens das Messgerät konfigurieren, also aus der Ferne „bedienen“ können. Zweitens soll das Messgerät dem Computer die Messdaten oder andere Zustandsdaten wie z.B. den aktuellen Messbereich senden. Das Messgerät kann hierbei beispielsweise ein Digitalmultimeter, ein Funktionsgenerator oder ein Oszilloskop sein. \n", " \n", "Oft befinden sich an einer Automatisierungseinrichtung, beispielsweise eine Endprüfanlage, viele verschiedene Messgeräte, die von ein und dem selben Computer bedient werden müssen. Hat nun jedes dieser Messgeräte eine andere Schnittstelle und kommuniziert über andere Protokolle, so wird ein solches Messsystem nicht mehr handhabbar. Manchmal gibt es für das eine Gerät Programmierschnittstellen (APIs) nur für C und für das andere Gerät nur für Java, was einen gemeinsamen Einsatz beider Geräte unmöglich macht. Oder für ein und das selbe Gerät gibt es für die gewählte Programmiersprache zwar das Kommunikationsprotokoll jedoch keine API für die Schnittstelle als fertige Bibliothek. \n", "Dieses Dilemma hat man schon 1962 erkannt, als der RS-232-Standard für die Gerätekommunikation eingeführt wurde, welcher erstaunlicherweise bis heute überlebt hat. \n", " \n", "Mitte der 1990er Jahre wurde der **VISA-Standard (Virtual Instrument Software Achitecture) eingeführt, der es erlaubt, Messgeräte unabhängig von deren Schnittstellen zu konfigurieren, programmieren und zu warten**. VISA kann für die Schnittstellen GPIB, VXI, PXI, Serial, Ethernet, und USB verwendet werden. VISA besteht aus einer API-Spezifikation für C, Visual Basic und G (LabVIEW). Unter Windows wird meistens als Standard-API die Laufzeitbibliothek `visa32.dll` bzw. `visa64.dll` verwendet (ist auch bei pyVISA der Fall). \n", "\n", "Zusätzlich zu den Schnittstellen hat man mit dem **SCPI-Standard (Standard Command for Programmable Instruments) die Protokolle, also die Messbefehle für unterschiedliche Messgeräte standardisiert. Er definiert Syntax, Befehlsstruktur und das Datenformat der Messbefehle**, die der PC an das Messgerät sendet. Die Messbefehle werden als ASCII-Zeichen übertragen. \n", "SCPI definiert folgende acht verschiedene Geräteklassen: \"Chassis Dynamometers, Digital Meters, Digitizers, Emissions Benches, Emission Test Cell, Power Supplies, RF & Microwave Sources, Signal Switchers\". Oszilloskope fallen unter die Geräteklasse „Digitizers\". \n", " \n", "Inzwischen sind **VISA und SCPI im IVI-Standard (Interchangeable Virtual Instrument) vereint** worden: \n", "Schlussendlich **beinhaltet IVI somit einen Satz von Standardmessbefehlen für das Messgerät und eine API für unterschiedliche Schnittstellen**. \n", "Schließt man ein Oszilloskop via USB an einen PC an, dann wird ähnlich wie bei einer Coputertastatur ein generischer IVI-Treiber geladen. Im Windows-Gerätemanager erscheint dann ein „USB Test and Measurement Device (IVI)“, Gerätetyp: „USB Test and Measurement Devices“. Hersteller: „IVI Foundation, Inc.“. Ein gerätespezifischer Treiber für das spezielle Oszilloskop wird also nicht benötigt. \n", "Möchte man von diesem Oszilloskop nun Hersteller, Modell, Seriennummer und Firmwarestand wissen, so muss der ensprechende SCPI-Befehl `*IDN?` als ASCII-Zeichen über die USB-Schnittstelle an das Oszilloskop gesendet werden. \n", "SCPI beinhaltet eine Vielzahl standardisierter Messbefehle (z.B. `MEAS:FREQ?` für die Anforderung der gemessenen Frequenz). SCPI-Befehle sind baumartig aufgebaut: In diesem Beispiel ist ` MEAS` der Root-Befehl und `FREQ` ist ein Parameter. Es reicht, bei den Messbefehlen immer nur den großgeschriebenen Teil zu senden, also `MEAS:FREQ?` statt ausgeschrieben `MEASure:FREQuency?`. \n", "Leider implementieren nicht alle Messgerätehersteller diese Befehle in gleichem Umfang oder gleichem Wortlaut. Daher muss man **vorher immer im Programmierhandbuch des Messgeräts den tatsächlichen Befehl nachschlagen**. \n", "Soll das Messgerät nach dem Befehl Daten zurückliefern, dann wird der Befehl mit einem Fragezeichen `?` abgeschlossen. Ein Konfigurationsbefehl benötigt kein Fragezeichen. \n", " \n", "Python kann grundsätzlich C-Laufzeitbibliotheken - also auch die oben erwähnte VISA Dlls verwenden. Darüber hinaus gibt es unter Python die Bibliothek `pyVISA`, um in einfacher Weise auf diese DLLs zuzugreifen. In den nachfolgenden Beispielen werden diese beiden Softwarekomponenten verwendet, um via USB ein Oszilloskop zu konfigurieren, Messungen zu intialisieren und die Messdaten auszulesen. \n", "Darüberhinaus wird der gemessene Spannungsverlauf mit den Python-Bibliotheken `Numpy` und `Matplotllib` grafisch visualisiert." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Verwendung von Python für die Messtechnik\n", "Grundsätzlich gibt es verschiedene Möglichkeiten, über Python mit einem Messgerät zu kommunizieren: \n", "* Man kann im Kommandofenster mit dem Pythoninterpreter interaktiv arbeiten bzw. eine Skriptdatei als Ganzes darin ausführen lassen.\n", "* Wesentlich bequemer ist eine Python-IDE wie z.B. \"Spyder\", die einen Editor enthält, in dem das Skript mit Codervervollständigung usw. erstellt wird. Ähnlich wie die MATLAB-IDE enthält Spyder auch einen Variable-Explorer und andere nützliche Features für das Debuggen. Zusätzlich gibt es in Spyder auch eine IPython-Konsole, mit der interaktiv Codeschnipsel aus dem Editor im Python-Interpreter getestet werden können. Diese Vorgehensweise wird im Praktikum Messtechnik verfolgt.\n", "* Der hier in diesem Jupyter Notebook verwendete Python-Interpreter basiert ebenfalls auf IPython. Hier liegt aber der Schwerpunkt auf der Dokumentation des Quelltextes und nicht auf dessen Ausführung. Wenn Sie dieses Jupyter Notebook durcharbeiten, dann werden Sie vermutlich nicht ein Oszilloskop am PC angeschlossen haben, um mit Codesequenzen zu spielen. Daher reicht es, wenn Sie dieses Notebook über einen Viewer durcharbeiten.\n", "\n", "Später im Praktikum erstellen Sie unter der IDE Spyder die Messsoftware im Editor und können die einzelnen Befehlszeilen getrennt in der IPython Konsole testen (dafür die Befehlszeile im Editor markieren, rechte Maustaste > \"Run Cell\"). \n", "**Die nachfolgenden Codebeispiele setzen Grundkenntnisse in Python sowie in den beiden Bibliotheken Numpy und Matplotlib voraus. Bitte arbeiten Sie vorher das Grundlagenkapitel des Jupyter Notebooks für die Bildverarbeitung durch.**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Beispiel Python Code für Oszilloskop Rigol DS1054Z\n", "Nachfolgend ist beispielhaft für ein Rigol DS1054Z gezeigt, wie nach IVI-Geräten gesucht wird, die Kommunikation mit einem gefundenen Gerät aufgebaut wird, dieses Gerät konfiguriert wird und wie die Messdaten ausgelesen werden. \n", "Die hierfür verwendeten Befehle sind leider nur teils \"echte\" SCPI-Befehle. Sie werden im Praktikum ein anderes Oszilloskop verwenden, das für einige Funktionen teils andere Befehle verwendet. \n", "Die korrekten Befehle finden Sie im Programmierhandbuch des jeweiligen Oszilloskops.\n", "\n", "### Import der nötigen Pythonbibliotheken\n", "Für die Kommunikation mit dem Oszilloskop werden die Bibliothek `pyVISA`, für die spätere Datenauswertung und -visualisierung die Bibliotheken `Numpy` und `Matplotlib` importiert. Die Funktion `sleep()` aus der Bibliothek `time` wird für nur für Wartebefehle verwendet, da das Oszilloskop manchmal wie bei dem Befehl `:AUToset`eine gewisse Zeit benötigt, bis ein Befehl ausgeführt wurde." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pyvisa as visa\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from time import sleep" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Suche nach IVI-Geräten und Verbindungsaufbau mit dem Oszilloskop\n", "Wenn im Windows Gerätemanager das Oszilloskop als \"USB Test and Measurement Device (IVI)\" erscheint, wird es durch folgende Befehle ausfindig gemacht und identifiziert:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('USB0::0x1AB1::0x04CE::DS1ZA181004388::INSTR', 'ASRL10::INSTR')\n" ] } ], "source": [ "# visa.ResourceManager('@py') # nur ToGo-Praktikum auf **Ubuntu** wenn Modul pyvisa-py statt NI-VISA als Backend\n", "# Bei ToGo-Praktikum auf Windows 10 zuerst NI-VISA **Runtime** Vers. 18.5 installieren\n", "# Download siehe ni.com/de-de/support/downloads/drivers/download.ni-visa.html\n", "rm=visa.ResourceManager() # ToGo oder Präsenz auf Windows 10\n", "inst_found=rm.list_resources() # IVI Geräte finden, Identifikationdaten in Liste abspeichern\n", "print(inst_found)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Das erste Element (Index Null) der Liste `inst_found` enthält (hier in dieser speziellen Konfiguration!) das via USB angeschlossene Oszilloskop. Anschließend wird eine Verbindung aufgebaut. Damit erhält man das Objekt `inst` über dessen Methoden und Attribute auf das Messgerät zugegriffen wird. \n", "Wenn Sie in der Spyder IPython-Konsole nun `inst. + ` eingeben, erscheint eine Auswahl an Methoden und Attribute für diese Klasse." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "inst=rm.open_resource(inst_found[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Konfigurieren des Oszilloskops\n", "Mit dem folgenden Befehlen wird das Oszilloskop konfiguriert und Einstellungswerte werden abgefragt. Siehe Kommentare hinter den jeweiligen Befehlen. Für Befehle mit Rückgabewert - zu erkennen am abschließenden Fragezeichen im Befehlsstring - wird `query()` verwendet, für reine Schreibbefehle `write()`." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'RIGOL TECHNOLOGIES,DS1054Z,DS1ZA181004388,00.04.03.SP2\\n'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inst.query('*IDN?') # Hersteller, Gerätetyp, Seriennummer und Firmwarestand abfragen" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "inst.write('*CLS') # Befehls- und Fehlerspeicher löschen\n", "inst.write(':AUT') # Autoset durchführen\n", "sleep(5) # 5 Sekunden warten, nötig da sonst Programmabsturz, falls Oszi noch nicht fertig bei nächstem Befehl" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'CHAN1\\n'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inst.query(':WAV:SOUR?') # Aktiver Kanal abfragen" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'DC\\n'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inst.query(':CHAN1:COUP?') # Kopplungsarte des Oszilloskopeingangs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Messwerte und gesampelten Spannungsverlauf auslesen\n", "Am Oszilloskop ist am Kanal 1 ein Tastkopf angeschlossen, der vom Rechteckgenerator für die Tastkopfkalibrierung des Oszilloskops ein Signal erhält. \n", "Als Beispiel wird nachfolgend eine Frequenzmessung ausgeführt." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'9.999999e+02\\n'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inst.query('MEAS:FREQ? CHAN1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Im nächsten Codebeispiel wird zuerst das Oszilloskop so konfiguriert, dass es später für den gesampelten Spannungsverlauf als ASCII-String ausgibt. Anschließend werden diese Messdaten vom Oszilloskop angegefordert und in eine Stringvariable kopiert. \n", "In diesem String sind die einzelnen Spannungswerte mit Kommata getrennt. Die ersten 30 Zeichen des Srtrings mit den Messwerten werden testweise ausgegeben." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "#90000156631.999961e-02,3.999961e-02,1.999961e-02,\n" ] } ], "source": [ "inst.write(':WAV:FORM ASC') # Messkurvenausgabe als ASCII-Werte anfordern\n", "values_raw = inst.query(':WAV:DATA?') # Messkurve als einen durchgehenden String ausgeben\n", "print(values_raw[:50]) # Erste 50 Zeichen testweise ausgeben" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Die ersten 11 Zeichen des Messwertestrings sind offensichtlich keine Spannungsmesswerte und werden daher ignoriert. Über die Stringfunktion `.split()` wird aus dem langen String ab dem 12. Zeichen eine Liste mit Strings erzeugt mit je einem Spannungswert pro Element." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "values_string_sep = values_raw[11:].split(',') # Lise mit Strings für jeden Messpunkt ab Zeichen 12" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Um im folgenden Kapitel diese Messwerte grafisch darstellen zu können, müssen diese zuerst in eine Liste mit Floats umgewandelt werden. \n", "Außerdem muss noch das Samplingintervall (Zeit zwischen den einzelnen Messwerten) vom Oszillokop ausgelesen werden, um später die x-Achse skalieren zu können." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.000000e-06\n" ] } ], "source": [ "values_float = [] # Umwandlung Stringliste in Floatliste\n", "for item in values_string_sep:\n", " values_float.append(float(item))\n", "delta_t = inst.query(':WAV:XINC?')[:-1] # Samplingintervall ausgeben\n", "print(delta_t)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Darstellung der gesampelten Spannungsverlaufs in einem Plot\n", "Zuerst wird die Liste mit den Spannungsmesswerten in ein Numpy-Array umgewandelt. \n", "Neu in diesem Codebeispiel ist die anschließende Numpy-Funktion `arange()`, die das Array für die Samplingzeiten der Messpunkte berechnet, welches später im Plot als Array für die x-Werte dient. \n", "Anschließend werden mit dem Modul `pyplot` von Matplotlib die Messwerte grafisch ausgeben." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "y_val = np.array(values_float)\n", "dt=float(delta_t)\n", "x_val = np.arange(0.0, len(values_float)*dt, dt) # x-Werte berechnen\n", "\n", "plt.plot(x_val,y_val,linewidth=2)\n", "plt.xlabel('Zeit in Sekunden')\n", "plt.ylabel('Spannung in Volt')\n", "plt.grid(True)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ ">" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inst.close # Beenden der Kommunikation mit dem Oszilloskop" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 2 }