Controlling a HP75000 VXI Mainframes with HTML5 and Java technology

This home project shows how an old but still powerful VXI mainframe and its integrated measurement devices can be accessed with todays tools and technology.

I have described the wonderful HP75000 here: http://spurtikus.de/basteln/devs/hp75000/index.html

Overall architecture approach

The HP75000 and technologies around it are a complex scenario. After having created several island-like solutions for different GPIB-controlled devices, I tried a new and integrated approach based on the following ideas:

  • A standard web browser as the only front end to control and access VXI devices. No platform specific code on the front end side. Use of HTML5, JavaScript and WebSockets for client side functionality.
  • The „Delegate“ which accesses the VXI mainframe is implemented as a platform independent Java application. My name for the delegate is „VXI Server“.
  • Communication between browser (front end) and VXI Server with standard Web technologies, namely REST, HTTP and WebSocket protocol. So the VXI Server can be seen as a Webserver offering access to VXI devices via a REST and a WebSocket interface.
  • Implementation of the VXI Server for a USB-based GPIB-Controller. This allows the software to run on any platform which has a USB-Connector. E.g. Notebooks and the Raspberry mini computer.
  • By using Standard Web technologies for the server, access to VXI devices is LAN/WLAN based. So every client capable of running a browser can access all VXI devices. This includes also tablets and even smart phones.
  • The VXI Server can execute JavaScript files

The picture below show the overall system architecture.


Architectural overview

The picture below shows the software architecture overview. On top there is a standard web browser, running e.g. on a tablet. The tablet is connected via WLAN to a bigger LAN structure where also the VXI Server process runs. The VXI Server looks like a standard web server and serves REST and WebSocket requests. It accesses a GPIB controller using USB.


Software architecture

 

Some pictures from the ongoing work

 

HP E1326 Multimeter; Voltage measurement on 2 channels
The two channels are displayed in a graph (graph2d from vis.js) and as seven-segment digits. The channels are coming from two E1345 relay mux cards and can also be selected.

 

HP E1340 Arbitrary Function generator control interface.

This small movie shows how to interact with the Multimeter user interface.

Scripting

Because Java contains the feature to execute scripting languages, I added JavaScript executing to the VXI server. This means that a client can create a JavaScript program and let the server execute it.

As an example, the following two lines make a voltage measurement and return it to the client (the browser).

var result = voltmeter.measureSingle();
se.Print.printMessage("Value: " + result);

The VXI Server binds the devices found in the HP75000 (later: the devices found on the GPIB bus) to variables like „voltmeter“. All methods defined for those Java objects can be executed from JavaScript. In the example, a method „measureSingle()“ is called. This method does a simple measurement, returned as a float value. The script prints out this value just for demonstrational purpose. Values from a script can be returned to the client by simply assigning them to the „result“ variable. This variable is bound to the result value and is used by the VXI Server to return the result value. A result can be anything e.g. a map of value lists or whatever. Using this machanism,  the client (usually the browser) can get the result of even complex measurements and display them.

Executing a script means that everything can be done, even without any client (after the script has arrived at the VXI Server). So this is a very powerful feature and can replace somehow the „IBASIC“ execution in the HP E1300.

Unordered things

Ohms mode

2 wire nur mit scanning mode
CONF:RES 20000 (@100)
MEAS:RES? (@100)
An HI/LO von Eingang 100 den R anschliessen.
Gewählten Range anzeigen mit:
CONF?

Voltage range change

CONF:VOLT:DC 58.1,(@100) oder CONF:VOLT:DC 50,(@100)
CONF:VOLT:DC:RANGE 100 (@100) <== ob man das braucht?
CONF? zeigt nun den Range an
MEAS:VOLT? (@100)
MEAS:VOLT:DC? man kann „:DC“ weglassen weil DC ist der Default
Es geht auch: MEAS:VOLT:DC? 100,MAX,(@100)

HP E1345 Connector

This is a standardized DIN41612 3×32 pin connector where the pins 33..64 are not used (i.e. only outer pin rows are used).

For the 15 channels, three terminals H, L, G (for High, Low, Ground) are present.

Usually, a terminal block plugs into this connector. These terminal blocks are very rare. So their prices are today often higher than those of the cards itself.

HP E1345 Connector

HP E1330 Connector

These are 2 Standard PC/104 connectors with 2×30 pins.

HP E1330 Connector view

HP E1330 Connector, Pins

 

GPIB Controller UI

 

Prologix GPIB-to-USB Controller

kermit: ok
minicom: failed!

kermrc

set line /dev/ttyUSB0
set speed 115200
set carrier-watch off
set handshake none
set flow-control /direct-serial rts/cts
set terminal echo local
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5

++ver
Prologix GPIB-USB Controller version 6.107
++addr 9 99  <– See note regarding addr command

*idn?
HEWLETT-PACKARD,E1326B,0,A.05.00
MEAS:VOLT:DC? (@100,101,102,103,104,105,106)
-2.447281E+000,-1.878159E+000,-1.407097E+000,-1.090889E+000,-8.490524E-001,-6.606951E-001,-5.015745E-001

Note to addr command: for secondary, enter (secondary address + 96). E.g. for address 3, enter 96+3 = 99.

Spurtikus.de GPIB Controller

GPIB Controller (Rev.0.8) (c) spurtikus.de 2008-2015
Internal commands:
.a – set prim./second. address of remote device.
.e – dump error queue.
.f – find partners.
.h – print help.
.i – dump info about controller state.
.r – toggle SRQ enablement.
.s secondary – set secondary address of remote device.
.x – toggle Xon/Xoff flow control.
.+ primary secondary – add partner device address to list of known devices.
.- primary secondary – remove partner device address from list of known devices.

Measurement Server

Measurement Client

Weiterführende Informationen

 

Von mir genutzte Linux Anwendungen/Software

Die Zahl der Freeware- oder Open Source Tools für Linux ist riesengroß. Um sich für ein bestimmtes Tool zu entscheiden, muss man oft lange Tests lesen oder viel probieren. Diese Arbeit will ich etwas erleichtern. Dazu liste ich von mir genutzte und gute Tools hier auf. Nicht dass es sehr viele sind. Da ich aber komplett auf Linux umgestiegen bin, müssen die Tools gewisse Qualitätsanforderungen erfüllen.

Geniale Software

In dieser Rubrik führe ich Software, die quasi Wunder wirkt:

  • testdisk: Das Tool mit dem unscheinbaren Namen ist in der Lage, aus einem zerstörten FAT-Volume durch Binärdatenanalyse noch sehr viel von dem als verlorengegangen geglaubten Inhalt zu kopieren. Ich habe damit von einer defekten SD-Karte aus einer Digitalkamera, die mit keinem anderen Programm auch nur irgendein Byte freiwillig abgegeben hat, noch ALLE Bilder extrahieren können. Unglaubliche Leistung. Link zum Hersteller: http://www.cgsecurity.org/wiki/TestDisk.
  • pdftk: PDF Toolkit. Erlaubt Operationen auf PDF Dateien. Es können z.B. mehrere PDFs zu einem neuen Gesamt-PDF zusammengefügt werden. Wunderbare Software.
  • hugin: Tool, mit dem aus mehreren Fotos ein Panorama-Bild erzeugt werden kann. Sehr schönes, intuitives Tool.
  • Firefox: DER Webbrowser.

Office Programme, Webeditoren

  • OpenOffice 2.0 oder neuer: komplettes Office Paket, stabil, flott und viele Funktionen. Vergleichbar zu Word, Excel und Powerpoint. Kann MS Office-Formate lesen und schreiben. Auch HTML-Editing ist möglich.
  • Kompozer: Mächtiger HTML-Editor mit WYSIWYG.
  • Seamonkey ist 2017 eine Art Nachfolger des kompozers.

Software-Entwicklung

  • Eclipse: Komplette Java Entwicklungsumgebung

Graphik

  • Gimp: Bildbearbeitungsprogramm
  • Inkscape: Vektororientiertes Zeichenprogramm

Multimedia

  • mplayer: Player für verschiedene Video-Formate, kann auch vom TV-Tuner das TV-Programm abspielen. Graphisches Frontend smplayer oder gmplayer.
  • mencoder: mächtiger Video Encoder
  • kdenlive: Video Editor zum Schneiden eigener Filme
  • ffmpeg: ähnlich mencoder.
  • audacious und xmms2: zusammen eine xmms-ähnliche Audio-Player-Umgebung. xmms2 ist ein mächtiges Sound-System und audacious eine simple Player-Oberfläche, ähnlich xmms.
  • timidity+: Software Sequencer; wird benötigt, wenn man Midi-Dateien abspielen will und keine Audiokarte mit HW-Sequenzer besitzt
  • avidemux: Videoschnitt Editor
  • audacity und wired: Multi Track Audio Aufnahme mit beiden Tools gut möglich
  • rosegarden: Kompositionsprogramm mit MIDI Ansteuerung. Muss ab Source compiliert werden.
  • GoogleEarth: „Weltatlas“ in 3D
  • mp3tag: Bearbeiten der Tags von MP3-Dateien. Zwar ein Windows-Programm, läuft aber prima mit wine.

Kommunikation

  • Firefox: Schneller, exzellenter Web Browser.
  • Thunderbird: Schnelles, exzellentes Mail-Programm
  • Skype: Audio/Video Kommunikation via Internet
  • vncviewer: Remote Zugriff auf X Window Systeme

Sonstiges

  • VirtualBox („Oracle VM Virtual Box“): Virtuelle PCs unter Linux
  • eagle – Elektrische Schaltpläne bearbeiten und Leiterplattenvorlagen erstellen.

Spiele

    • dopewars: Ein angeblicher „Klassiker“. Rein textbasiert.

Software, die mir nicht gefällt

Manche Sachen haben mich bei diesen Tools schon sehr gestört 🙂

  • acroread: Acrobat Reader für PDF. Die riesige und unverständliche Größe des Installs ist absurd – über 100MB für einen trivialen Fileviewer!. Warum muss das sein?
  • amarok: Audio Player. Ich habe lange probiert diesen Player zu nutzen. Ich kann nicht zählen, wie oft ich schon hunderte CD-Cover zum X-ten Mal heruntergeladen habe, weil ich die korrupte Datenbank von amarok löschen musste. Playlist lies sich nicht speichern, lastFM-Support funktionierte lange nicht. Dieses Tool macht dem Nutzer graue Haare…
  • ms windows

SoftTek – Eclipse-based control and visualization for measurement equipment

Note: this is work in progress. The software described is in development and not finished.

SoftTek is an Eclipse based application that is able to communicate via GPIB with some (vintage) measurement equipment of the Company Tektronix for control of the device and for visualization of measurement data.

Supported devices

The following devices are supported:

  • Tektronix 1241 Logic Analzer (tested)
  • Tektronix 1240 Logic Analyzer (not tested)

As far as I know, the 1240 and the 1241 are identical except that 1241 offers a color screen, 1240 is monochrome only. So in the following text, I will always use „1241“ because I own that one, but the text is also valid for the 1240.
To be more precise here, the EPROMs on the analyzer pcbs have mostly identical stickers for 1240 and 1241. The only difference known by me is that the character set of the 1240 and the 1241 are slightly different. The colors are coded into the byte value for a character, I do not know what a 1240 will display if it shall display a e.g. green ‚A‘. Maybe even this makes no difference, if e.g. the color coding is interpreted as „highlighting“ on the 1240. This would need further reading in the documentation…

Implemented features, missing features

SoftTek can…

  • Load memory images from Tek device (setup images, acquisition images, reference memory images, rampack data)
  • Display loaded data in a nice way (scaling, color coding, selection of groups to display). All 72 channels in all groups can be displayed in one big canvas (as apposed to the monitor view of the Tek 1241)
    • Non-glichted and glitched data
    • Chained data
  • Display up to two time cursors to analyze displayed data
  • Load and save device data to PCs harddisk

The implementation does not contain (why) …

  • Ability to download memory images to the device (GPIB module is not yet capable of doing this, needs update of the AVR firmware used in my GPIB module, this is not related to the software SoftTek)
  • No two timebase support and thus no multiplexing support (too complicated, needs more reading in the manuals)
  • Not tested:
    • synchronous mode,
    • chained 18 bit channels (never needed),
    • Chains with more than two cards (have only 2 9 channel and 2 18 channel cards, so my maximum is 2 card chains)

Requirements to run the software

  • Java JRE 1.6 or higher. Tested with 1.6.
  • Currently only Linux support, no Windows-plattform incarnation of the Eclipse RCP (I have no windows PC to test with)
  • Some GPIB controller attached to the device and attached to the PC where this software is running on. I used for my purposes my own Implementation of a GPIB-Controller running on an AVR board. This board is attached to the PC via RS232. A description of this device can be found here [3]

The Tek 1241

Some information on the device to enable understanding of the software. A more general intro to the 1241 is given in [2].

The analyzer supports up to 72 channels. It is able to view signals in state diagrams and in timing diagrams.

It supports frequencies up to 50 Mhz (synchronous) and 100Mhz asynchronous. The device has 2 time bases and offers 15 levels of trigger conditions. The two time bases allow e.g. a slow clock on the first time base to get some first trigger close to the area that shall be analyzed and then a high frequency clock for the second time base to get a much finer view into the area to be analyzed.

The organization of the input side of the device is as follows:

  • There are 4 lines for slots at the right side of the device. For each line,  two slots are possible. These slots are numbered 0,1 for first line, 2,3 for second line, 4,5 for third line and 6,7 for fouth line.
  • There are 9 channel and 18 channel acquisition memory cards. A 9 channel card uses a single slot (e.g. 0 or 2), an 18 channel card uses two slots (e.g. 4+5 or 6+7). These cards are located inside the device.
  • A Pod is a probe with 9 data input lines (and one clock/qualifier input line for e.g. synchronous mode). The Pod is external to the device and is attached via a cable and a connector into a acquisition memory card.
  • Between a Pod and the device under test, a lead set needs to be used. The lead set can be attached to the pod and offers e.g. micro clamps to attach the data input line to the device under test.Each Pod also has an „Id-Button“ that produces a screen read out of the pod id.

For my device:

Slot Card
0 9 channel
1
2 9 channel
3
4 18 channel (card 1)
5 18 channel (card 1)
6 18 Channel (card 2)
7 18 Channel (card 2)

My device has two 9 channel cards and two 18 channel cards. The two 9 channel cards are located in slots 0 and 2. The two 18 channel cards are located in slots 4+5 and 6+7.
I have in total 6 pods of type 6460 which allow together with 9 channel acquisition cards to control the logic threshold (signal level threshold for separating HI and LO on a line). 18 channel acquisition cards have always fixed TTL level threshold.

In the analyzer, a Test Pattern Generator TPG is built in. This generator creates well defined sequences of patterns. There are two 9 channel wide pattern sequences. To easily use the TPG, a test lead set was provided by Tektronix.

Display Groups

Display groups are used to do a grouping of input data lines for display. E.g. one group can contain data bus lines called e.g. „D0-D8“ and another group can contain some lines to monitoring an SPI communication. Grouping is done by the user and includes naming the group, assigning a timebase and other things.

The Analyzer has a default grouping at startup. This depends on the aquisition cards inserted. For my device:

GRPA
Pod 0, Bits 0..7
GRPB
Pod 2, Bits 0..7
CTL1
Pod 0, Bit 8
Pod 2, Bit 8
GRPC
Pod 4, Bits 0..7
Pod 5, Bits 0..7
GRPD
Pod 6, Bits 0..7
Pod 7, Bits 0..7
CTL2
Pod 4, Bit 8
Pod 5, Bit 8
Pod 6, Bit 8
Pod 7, Bit 8

Grouping is part of the setup. Setups can be stored in a ROMPACK if available or in a NVRAM area of the analyzer.

There is much more to say on the 1241, see e.g. the user manual.

Theory of Operation of SoftTek

The 1241 can communicate with a controlling PC via a GPIB controller (if equipped with a GPIB interface module) or via RS232 (if equipped with a RS232 module). My description is based on the GPIB module approach.

For short pieces of textual information, the information is exchanged between a Controller/PC and the 1241 in human readable strings.

Some of the data is large, of binary type and transfered in a data block-oriented format. This data include:

  • Setup information
  • Aquisition and Reference Memory content
  • RAM- and ROM-Pack content.

The GPIB-Implementation of Tektronix for the devices is documented in [1]. The implementation defines „Data Blocks“ and „Memory Images“.

A data block is a container with some header and trailer information surrounding a number of payload bytes. Seen from today, a data block is quite small (maximum payload 61 bytes). The payload bytes are encodings of binary data bytes. The 1241 is able to use three different data formats for the bytes:

  • ASCII HEX: Each Byte is coded in two bytes, representing the hex value of the original byte. E.g. byte 0xa2 will be encoded as two ASCII chars ‚A“2‘.
  • TEK Binary: Each byte stands for itself. E.g. byte 0xa2 will be transfered „as is“, namely as byte 0xa2.
  • IEEE728 Binary: Close to TEK Binary, but this is an IEEE standard for transfering binary data. The definition of IEE728 can be found somewhere in the Internet

Both binary encodings require a transport way that is able to transfer binary data, i.e. bytes with values >0x7f.

My implementation uses RS232 to connect the GPIB controller to the PC. The controller is homebrew, described in [3] and supports only XON/XOFF software handshake, so only ASCII (non-binary) data can be transfered via my implementation. So I am using the ASCII HEX type for the data blocks (which is the default for the Tek 124* device). My implementation also include some code for binary formats, but this hasn’t been tested. Because the data size per memory image is not very large (some KBytes) it is ok to use ASCII encoding despite it needs nearly the double amount of bytes compared to a binary encoding.

A memory image is a sequence of binary data bytes. If the user requests the transmission of e.g. the aquisition memory via GPIB, the Tek device creates a memory image from its internal hardware memory. This memory image is then converted to a sequence of data blocks and sent to the controller. The controller transfers the data to the PC and there some software converts the data blocks back to the binary payload. By putting together the small binary payloads from the data blocks, the large memory image can be reconstructed in the PC.

The structure of the memory images is documented by Tektronix in [1], all values inside the image are defined by their offset in the memory image, their size and, of course, their meaning.

Implementation

The application is an Eclipse Rich Client. It uses a navigation view (left side of application) to display/modify configuration of the client and of the data from the 1241. It also has a big canvas that is used to display the timeline data.

My implementation offers at the bottom classes for data blocks and for memory images. The data block classes implement a reader interface. This interface encapsulates the reading method (ASCII HEX, binary). The memory image class defines methods to use a list of datablocks or a large sequence of ascii bytes to build up the binary content of the image.

There are two implementations of the reader interface, to read data from the tek device, and to read data from files.

The communication to the Tek device uses a nice java implementation for serial connectivity, called RXTX from http://rxtx.qbang.org .

A class „Tek1241RawDevice“ encapsulates all useful methods for the device and uses the memory images coming from the Tek device. Another class „Tek1241Device“ uses a raw object (from class Tek1241RawDevice) to implement own logic above the raw calls.
Both of these classes extend a class „AbstractRawDevice“ resp. „AbstractDevice“. If the software will be extended to other devices, these abstract classes are the point to extend from.
To separate Raw classes from „Not-Raw“ (cooked) classes: raw classes know about offsets in memory images and do access memory images to extract data from.
Cooked classes are implemented on raw methods only and should not know about memory memory images.

The class „DisplayGroup“ encapsulated all information about the „Group“ objects from Tektronix that can be found in the setup memory image. The class „Channel“ encapsulates information about a channel (to which pod and which bit inside the pod is this channel assigned etc.).

To have some interaction with the displayed data, I added a class „TimeCursor“ which allows to create a set of cursors that can be moved on the data time lines to get the hex and binary values of the group data at a certain cursor position, like the screen cursor of the 1241.

The class NavigationView defines all UI elements at the left side and the menues.

The class View contains all methods to create, modify and display data in the big canvas area.

File format used

To store uploaded data on the disk of the PC, I „invented“ a file format capable to store the acquisition data together with its setup data. Note that the acquisition memory image does NOT contain all the data to rebuild the complete information needed to load later on the device data, so we need the setup data valid during acquisition too. Example are all information about groups, which are stored in the setup image and not in the acquisition image.
Because I had all the data available in the format that was sent by the device I decided to use that format. The data is in ASCII HEX format as described in the GPIB manual of Tektronix. Logically, the setup and the acquisitionn memory is each a (large) single line of ASCII characters. So my file format consists of fixed two lines:
Line 1: Setup Information as raw ASCII HEX characters ending with a CR
Line 2: Acquisition memory data as raw ASCII HEX characters ending with a CR

Because the data stored in the file is identical to the data read in by the device, it will be simple to download this data to the Tek 1241.

Screenshots

Below are some random screenshots showing the state of the work.

Early version (03/2012)

 

Early version; moved view to trigger event (red line at position 0)

 

Improved version with color coded timelines, extraction of more information from memory images (April 9th 2012)

Further improved version 04/2012

 

Closeiup: the time cursors. They display in numerical value the bit position and the hexadecimal and dual value of the Group value (here it is a byte).

Look at the trigger position (red vertical line, t=0)

 

UI Elements for device access

 

Info on aquisition capability of the device

 

Somer more info elements

 

Display of data with glitches

 

Closeup: display of data with glitches. A glitch (the red area) means that there was at least one undisplayed transition between the acquisitions before and after the glitch.

Examples for data files from a Tektronix 1241

Here are some examples of binary data coming from the 1241. All files are in ASCII HEX format:

Further information

[1] GPIB COMM Pack 1200C02, Tektronix, revised printing November 1986, downloadadble via Internet
[2] Der Logik-Analysator Tekronix 1241, http://www.spurtikus.de/basteln/tek1241.html

[3] Communication via GPIB with AVR, Description of my software-only implementation of a simple GPIB controller:  http://www.spurtikus.de/basteln/gpib_en.html

[4] RXTX library for serial communication with Java. http://rxtx.qbang.org

Kommunikation via GPIB mit dem AVR

This Article in english: 

Im folgenden sind meine Experimente zum Thema Nutzung des GPIB-Busses mit AVR Mikrocontrollern beschrieben.

Hinweis: Beschrieben ist -wie immer auf meinen Seiten- ein Versuchsaufbau im Experimentallabor. Es handelt sich keinesfalls um produktiv nutzbare Hard- oder Software. Der Versuchsaufbau kann allerhöchstens Basis für eigene Versuche dienen. Ich schreibe dies, weil GPIB-fähige Geräte typischerweise sehr teuer in der Anschaffung sind. Man kann sich beim Experimentieren durchaus den GPIB-Anschluss kaputt machen, daher diese ausdrückliche Warnung. Sagen Sie nicht ich hätte Sie nicht gewarnt 🙂

Der GPIB (General Purpose Interface Bus) ist ein von HP in den sechziger Jahren entwickeltes Bus-System. Es wurde vorrangig für die Vernetzung komplexer Messgeräte entwickelt, um z.B. automatisiertes Testen zu ermöglichen. Das Bus-System wurde durch HP und andere Hersteller weiter entwickelt und ausgebaut und unter dem Namen IEEE 488 standardisiert. Der Bus ist auch unter den Namen HPIB und IEC 625 bekannt.

Im Bereich hoch entwickelter Messgeräte ist der GPIB-Bus auch über 40 Jahre nach seiner Entwicklung noch weit verbreitet. Insbesondere Gebrauchtgeräte aus den 80ger und 90er Jahren haben oft ein GPIB-Interface.

Mein bei eBay erstandenes digitales Speicheroszilloskop Tektronix 2432A von 1989 besitzt ein GPIB-Interface. Das Oszilloskop lässt sich mittels GPIB komplett fernsteuern, es lassen sich alle Einstellungen abfragen und die momentan gespeicherten/dargestellten Wellenformen auslesen. Die Idee war daher, vom PC aus auf diese Daten zuzugreifen.

Tektronix 2432a Cursor

Es gibt für PCI, USB, ISA und RS232 Karten und Geräte, welche mit dem Rechner verbunden werden können und die eine GPIB-Schnittstellen besitzen. Diese Karten und Geräte sind sehr teuer, ich habe keine Lösung -auch nicht gebraucht- für unter 100 Euro gesehen. Ich habe daher versucht, mit einem AVR Mikrocontroller die Funktion eines GPIB-Geräts nachzubilden.

Der GPIB-Bus ist ein paralleler Bus. Geräte können mit speziellen Kabeln, die an den Enden sowohl eine Buchse als auch einen Stecker besitzen, in einer „Daisy Chain“ verbunden werden. Jedes Gerät am Bus hat typischerweise zwei Adressen (eine Listener und eine Talker-Adresse). An einem Bus können maximal 15 Geräte adressiert werden. Eines der Geräte fungiert als Controller in Charge. Der Controller steuert den Datenfluss zwischen allen anderen Geräten mittels Bus-Kommandos. Es kann auf einem Bus immer nur einen Talker gleichzeitig geben, es kann aber immer mehrere Listener geben. Typischerweise kann man bei einem GPIB-Gerät dessen Adresse und dessen Verhalten einstellen. Man kann z.B. ein Gerät als Listener, als Talker oder als Listener+Talker einstellen.

Trivialansatz: Talker/Listener Szenario

Falls man genau einen Talker und einen Listener hat, benötigt man keinen Controller. Der Talker gibt seine Daten auf den Bus aus, ohne einen speziellen Listener zu adressieren und der Listener liest die Daten vom Bus herunter. Dieser Fall tritt auf, wenn man an ein Oszilloskop einen Drucker oder Plotter anschließt. Diesen Fall habe ich zuerst aufgebaut.

Hardware

Ich habe einen ATMega32 genommen und diesen auf übliche Weise mittels RS232 mit meinem PC verbunden. Der AVR wird dann direkt mit dem GPIB-Bus verbunden. Hierbei sind einige Dinge zu beachten, die im weiteren erwähnt werden.

Die Leitungen des GPIB-Busses

Der GPIB-Bus wird auf eine 24-polige Centronics-Buchse geführt. 8 Leitungen (DIO1..8) transportieren das Datenbyte. Drei Leitungen (DAV, NRFD und NDAC) sind für den Handshake auf dem Bus verantwortlich. 5 Leitungen (ATN, SRQ, EOI, REN, IFC) sind für das Management des Busses verantwortlich. Somit benötigt man für eine Vollbelegung 16 Leitungen. Die restlichen Pins der Buchse sind Masse-Leitungen.

Tektronix 2432a GPIB Buchse

Die Leitungen des Busses sind „Open Collector“ beschaltet, und „Active Low“. D.h. eine logische „0“ bedeutet, dass die Leitung HIGH, also „1“ ist. Eine logische „1“ bedeutet, dass die Leitung LOW, also „0“ ist. Die Open Collector-Beschaltung sorgt dafür dass mehrere Listener gleichzeitig an einer Leitung hängen können und unabhängig voneinander die Leitung auf LOW schalten können, ohne das dabei eine Ausgangsstufe eines der Geräte kaputt geht.
Solange nur eine Konfiguration Talker->Listener vorhanden ist und kein weiterer Listener im Spiel, braucht man auf das Thema Open Collector nicht zu achten.

Ich habe die 8 Datenleitungen auf ein Port (Port A) des AVR geführt. Die Management-Leitungen habe ich erstmal ignoriert und die drei Handshake-Leitungen auf weitere freie Pins des AVR geführt. Somit habe ich 11 Leitungen verwendet.

Software

Das spezielle Drei-Draht-Handshake des GPIB-Busses ist an verschiedenen Stellen im Internet beschrieben (z.B. hier). Der Handshake läuft wie folgt ab:

  1. Listener signalisieren mit NRFD (Not Ready For Data), wenn sie Daten empfangen können (sie setzen NRFD auf HIGH). Wenn der letzte Listener HIGH setzt, geht NRFD auf HIGH.
  2. Talker bemerkt dies und setzt Daten auf die Datenleitungen und zieht DAV (Data Valid) auf LOW.
  3. Listener bemerken dies und setzen für die Zeit des Lesens der Daten NRFD auf LOW. Wenn ein Listener mit dem Lesen fertig ist, setzt er NDAC auf HIGH. Wenn der letzte Listener fertig ist, geht dadurch NDAC auf HIGH. Dies bemerkt der Talker und setzt DAV auf HIGH. Daten sind nicht mehr gültig.
  4. Nach einer gewissen Zeit setzen die Listener NDAC wieder auf LOW, und NRFD auf HIGH so dass der Zyklus für das nächste Byte beginnen kann.

Dieses Protokoll habe ich zunächst in einer Schleife mittels Polling implementiert. Es wurden zwar Daten gelesen, aber dasselbe Datum gleich mehrfach, ich habe den Übergang DAV nach HIGH im Schritt 3 einfach nicht mitbekommen, egal was ich probiert habe. Es ging soweit, dass ich glaubte, dass in der TALKER/Listener-Konfiguration DAV immer LOW bleibt. Nachmessen mit dem Oszilloskop hat aber gezeigt, dass DAV sehr wohl zwischen HIGH und LOW wechselt, und zwar mit etwa 3300Hz. Das Oszilloskop sendete im Versuch den Bildschirminhalt, etwa 3000 Bytes. Möglicherweise ist Polling hier zu langsam (siehe Bemerkung weiter unten, es war ein Programmierfehler, Polling ist nicht zu langsam).

Ich habe die Software daher verändert, und zwar so, dass auf der fallenden und steigenden Flanke des DAV-Signals (das an INT0 anliegt) ein Interrupt ausgelöst wurde. Diese Interrupts habe ich zunächst einfach gezählt. Es waren etwa 6000 Interrupts, was gut zu den etwa 3000 Zeichen passte. Ich habe dann die Implementierung ganz auf Interrupts umgestellt, so dass die Zeichen in der Interrupt-Service-Routine gelesen werden. Danach wurden alle Zeichen sauber übertragen.

Im folgenden ist die zentrale Interrupt-Routine dargestellt. Da die Daten in negativer Logik ankommen, werden sie mit 0xff per XOR verknüpft, um das echte Zeichen zu erhalten. Die „dav“-Variable verwende ich außerhalb der ISR, um festzustellen ob ein neues Zeichen eingetroffen ist. Dort wird sie auch zurückgesetzt:

ISR(INT0_vect) {
   if (irq_falling_edge==1) {
         
      // handshake: clear NRFD, means i am busy now to read data
      PORTD &= ~_BV(G_NRFD);         
      // read data
      byte = PINA ^ 0xff;
      // handshake: set ndac, means i have completed/accepted the read
      PORTD |= _BV(G_NDAC); 
      // set data valid flag
      dav=1;
   
      irq_falling_edge=0; // wait for next raise
      MCUCR = (1<<ISC00)|(1<<ISC01); // raise int0 on rising edge
   } else {
      // handshake: clear ndac (this is a prerequisite for receive next byte)
      PORTD &= ~_BV(G_NDAC);
   
      irq_falling_edge=1; // wait for next fall
      MCUCR = (1<<ISC00); // raise int0 on falling edge
   }
}

Ein weiteres Problem ist, dass ich das Ende der Übertragung zunächst nicht erkannte. Der GPIB-Bus nutzt hierfür die EOI-Leitung, die der Talker beim Übertragen des letzten Bytes auf LOW zieht. Diese Leitung hatte ich aber nicht verwendet. Das Oszilloskop kann jedoch zusätzlich am Ende einer Übertragung ein CR schicken. Dies habe ich am Oszilloskop eingestellt, danach konnte ich auch das Ende der Übertragung feststellen. Für Binärübertragung muss man allerdings den Weg über die EOI-Leitung gehen.

Im folgenden ist die so gewonnene Ausgabe eine WAVEFORM dargestellt. Es handelt sich um ein Rechtecksignal. Die momentane Einstellung der Y-Achse von Kanal 1 und der Zeitachse sowie weitere Einstellungen werden als Präambel (WFRMPRE) vorangeschickt. Danach folgt ab „CURVE“ die Waveform-Beschreibung. Werte um 50 sind das HIGH, Werte um 0 sind das LOW des Signals. Die Ausgabe wird als eine lange Zeile geschickt, ganz am Ende kommt ein CR-Zeichen. Der Übersichtlichkeit halber habe ich die Ausgabe in mehrere Zeilen aufgeteilt.

WFMPRE WFID:"CH1 DC  20mV  10ms NORMAL",NR.PT:1024,PT.OFF:512,PT.FMT:Y,XUNIT:SEC,XINCR:2.000E-4,YMULT:
8.000E-4,YOFF:0,YUNIT:V,BN.FMT:RI,ENCDG:ASCII;
CURVE 0,0,-1,0,0,1,-1,0,0,0,1,1,49,50,50,50,49,49,50,51,49,50,50,50,50,51,50,50,50,50,50,50,
50,51,50,50,50,52,50,52,50,49,51,51,50,50,50,49,50,50,51,52,50,52,49,50,50,51,50,50,51,50,0,
0,1,1,-1,0,0,0,-1,0,-1,-1,-1,0,0,-2,0,0,0,0,0,-1,-1,1,0,0,-1,0,1,0,1,0,1,-1,1,1,-1,0,1,0,0,1,1,0,1,
0,-1,1,-2,0,50,51,50,50,49,51,52,50,51,51,50,50,51,50,52,49,51,52,51,50,51,50,52,50,51,52,50,
50,49,51,50,51,50,50,51,50,52,49,51,51,51,51,49,50,52,51,50,50,51,51,2,0,1,-2,0,-1,1,-1,0,1,0,
0,0,-1,-1,1,0,-1,1,0,0,-1,0,-2,1,0,0,-2,0,0,-1,-1,0,1,-1,-1,-1,0,0,-1,-2,-1,-1,1,-1,1,0,1,-2,-1,49,49,
48,51,50,50,50,50,49,52,51,51,52,50,50,51,49,49,51,50,51,50,50,49,50,51,51,51,51,51,51,50,50,
50,52,51,51,50,50,50,51,50,51,52,52,51,51,52,50,50,1,-1,0,0,1,0,-1,-1,1,-1,1,-1,-1,0,0,1,0,0,-1,
-1,-2,-1,1,0,0,-1,1,-1,1,-2,-1,-1,-1,-1,0,1,1,1,-1,1,-1,1,-1,-2,0,-1,-1,-2,1,0,50,50,50,50,50,50,50,
51,51,50,51,50,50,50,49,51,51,50,50,51,51,50,51,50,52,52,50,51,50,50,51,50,50,51,50,50,51,50,
51,51,51,50,50,51,49,49,51,49,49,50,0,0,0,-1,0,-1,1,0,0,-1,0,0,-1,0,0,1,-1,0,-2,0,0,0,-1,-1,-1,-1,
0,0,0,-1,-1,0,-2,0,-1,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-2,-1,0,49,50,49,50,49,51,50,50,51,50,51,50,50,49,
50,52,52,49,48,51,51,50,50,51,51,51,50,50,51,52,50,50,51,51,50,51,51,50,49,51,50,50,52,50,52,
50,49,50,50,50,0,0,0,0,0,0,-1,0,0,0,0,0,0,-1,-1,-1,0,1,1,-1,-1,0,0,0,-1,-2,0,0,1,0,-1,1,1,0,0,1,-1,-1,
0,-1,0,-1,2,0,0,0,-3,0,1,0,50,50,51,49,51,52,50,49,50,51,50,50,50,51,51,50,51,51,51,52,49,50,49,
50,50,49,51,53,49,51,50,48,51,51,51,50,49,51,51,49,51,50,52,51,50,50,50,51,52,50,-1,-1,0,0,-2,-1,
-1,-1,0,-2,-1,-1,-1,0,0,-2,0,-1,0,-1,-1,-1,0,-1,-1,0,0,-2,0,0,-1,1,0,-3,0,0,-2,0,-1,-1,0,0,-1,0,0,0,-2,-1,
0,-1,50,50,51,49,51,49,50,51,50,50,50,50,49,51,51,50,51,51,50,51,50,49,50,51,50,50,49,50,52,50,51,
50,49,50,51,51,50,51,50,52,50,51,52,50,50,50,50,51,51,51,-1,0,0,-1,0,0,0,0,-1,0,0,1,-2,0,0,-1,0,0,0,0,
-1,0,-1,-1,-1,0,0,0,1,-1,0,0,-1,0,-1,0,-1,-1,1,1,0,0,-1,0,-1,-1,-1,-1,1,0,50,51,50,51,51,50,50,51,50,51,49,
52,50,50,50,51,50,51,49,51,52,50,51,50,51,50,51,52,48,49,49,50,48,49,50,51,50,50,50,50,50,50,51,49,
50,51,48,50,51,52,0,0,0,0,0,0,-2,0,0,0,0,-1,-1,0,-1,0,0,-1,0,1,0,-1,-1,-2,0,0,0,0,0,-1,1,0,0,-1,0,-1,-1,1,
0,0,0,-1,0,-1,0,0,0,-1,-1,-2,49,50,50,52,50,49,50,50,49,50,52,50,49,50,51,52,49,49,49,51,51,50,50,50,50,
49,51,50,50,50,51,52,50,50,50,50,50,50,49,52,51,50,50,50,51,52,50,50,52,49,0,-1,0,-1,0,1,2,-1,-1,-1,0,1,
0,-1,0,0,1,0,0,-1,0,1,0,0,-2,0,-1,-1,0,-1,-1,-1,0,-1,0,-1,0,-1,0,0,1,-1,-2,-1,-2,1,-1,-1,1,1,50,48,49,49,49,
50,50,51,50,51,50,50,52,50,51,52,51,51,52,50,52,49,50,49,51,49,52,50,50,50,48,51,50,50,49,51,51,50,51,
50,50,48,50,52,51,49,50,50,49,51,0,-2,-1,-1,1,0,0,0,0,1,-1,-2,0,1,0,-2,-1,0,0,0,-1,-1,0,0,0,0,-2,1,0,-1,-1,-1,
-1,0,-2,-1,-1,0,-1,-1,-1,-1,0,-1,0,-2,0,0,1,-2,49,50,51,51,49,50,52,51,50,51,52,51

Im Ergebnis kann man mit dieser Konstellation Daten, die das Oszilloskop schickt, sauber zum PC übertragen. Man kann aber leider keine Kommandos zum Oszilloskop schicken. Dies würde die Erweiterung des Beispielcodes um Controller-Funktionen und die Verwendung zusätzlicher Leitungen erfordern. Außerdem muss man dann das Thema „Open Collector“ lösen, sonst geht entweder der ATMega32 oder aber das GPIB-Interface des Oszilloskops kaputt.

Ein Versuch mit HPGL-Ausgabe, die das Oszilloskop auch beherrscht, zeigt ein neues Problem: Statt in einer langen Zeile kommen die HPGL-Daten zeilenweise. Meine Erkennung des Übertragungsendes funktioniert damit nicht mehr.

Hier beispielhaft die HPGL-Ausgabe (nicht komplett):

in;sc-690,689,-512,511;
sp1;
pa-500,-400;pd;pr1000,0,0,800,-1000,0,0,-800;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl1;xt;pr100,0;
tl0,1;yt;pr0,100;
tl0,1;yt;pr0,100;
tl0,1;yt;pr0,100;
tl0,1;yt;pr0,100;
tl0,1;yt;pr0,100;
tl0,1;yt;pr0,100;

Ich habe eine HPGL-Ausgabe mit dem Tool „hp2xx“ in ein JPEG überführt. Die Ausgabe kann man in kermit mittels „log session <datei>“ in eine Datei umleiten. Das hpxx-Kommando konvertiert mit folgender Abfolge:

rm -f tmp.eps out.pdf
./hp2xx -p 22222222 -C -o 20 -O 150 -h 100 -a 2  -m eps -d 600 $1 -f tmp.eps
ps2pdf tmp.eps out.pdf
acroread out.pdf

Die Kurve und die Skala ist ok, die Beschriftung kommt viel zu klein heraus. Mit der Option „-d xxx“ kann man die DPI-Auflösung des Ergebnisbildes beeinflussen, ab 300 dpi kann man den Text lesen.

Versuche mit dem Tool hpgl2ps waren schlechter als die mit hp2xx.

hp2xx Output

Elaborierterer Ansatz: Talker/Listener Szenario

Als nächstes habe ich zusätzlich die Leitungen EOI, ATN, SRQ, IFC und REN an den AVR geführt. Die Beschaltung sieht dann tabellarisch wie folgt aus:

GPIB Pin Name  GPIB-Buchse Pin Nummer  ATMega32 Pin Name  AVR Board Buchse Pin Nummer
DIO1..8 (Datenpins) 1..4 und 13..16 PortA0..PortA7  1..8
EOI 5 PD4 30
DAV 6 PD2 28
NRFD 7 PD3 29
NDAC 8 PD5 31
SRQ 10 PD6 32
ATN 11 PD7 33
IFC 9 PB0 9
REN 17 PB1 10
GND 23 GND 39

Nutzung des EOI-Signals

Eine Untersuchung des EOI-Signals mit einem zweiten Oszilloskop ergab, dass das Signal ohne Übertragung LOW ist, während der kompletten Übertragung auf HIGH gehalten wird und nach dem letzten Zeichen wieder auf LOW geht. Dies unterscheidet sich von der GPIB-Dokumentation, die ich im Internet gefunden habe. Dort wird beschrieben, dass das EOI-Signal nur genau für das letzte Zeichen einer Übertragung  LOW gezogen wird. Entweder funktioniert mein Oszilloskop anders als der Standard oder ich lese die Beschreibungen nicht richtig.

Beschaltung der Pins des AVRs für Open Collector

Die AVR Controller sind zwar extrem flexibel, man kann aber die Port-Pins nicht direkt in eine Open Collector Modus schalten. Man könnte nun Open-Collector-fähige Bustreiber zwischenschalten, aber dafür bin ich zu faul. Eine Suche im Internet ergibt, dass man scheinbar die Open-Collector-Schaltung simulieren kann, indem man auf den Pin ein LOW schreibt und dann mittels des DDRx-Registers den Pin umschaltet. Die Idee bedeutet im einzelnen(am Beispiel PORTD und Pin PD4):

Funktion „normale“ Beschaltung Open Collector Simulation
Initialisierung des Pins DDRD |= _BV(PD4) // als Ausgang
DDRD &= ~BV(PD4) // als Eingang
PORTD &= ~_BV(PD4)
DDRD &= ~_BV(PD4)
Pin auf HIGH setzen PORTD |= _BV(PD4) DDRD &= ~_BV(PD4)
Pin auf LOW setzen PORTD &= ~_BV(PD4) PORTD &= ~_BV(PD4)
DDRD |= _BV(PD4)
Pin lesen unsigned char p = PIND & _BV(PD4) DDRD &= ~_BV(PD4)
unsigned char p = PIND & _BV(PD4)

Nach Umstellung funktioniert mein Code noch, die Simulation scheint also zu funktionieren. Als nächstes steht die Implementierung der Talker und Controller-Funktionalität an.

Nach einigem Hin- und Her bin ich völlig von der Interrupt-gesteuerten Leseroutine abgekommen. Die Probleme, die ich beim Pollen hatte, waren auf einen Fehler meinerseits (Lesen von PORTx statt von PINx, was nicht funktioniert) zurückzuführen. Nach der Implementierung der Lesefunktion gpib_read() und der Schreibfunktion gpib_write() stand die Implementierung der Controllerfunktionalität an.

Das Experimentierboard von Pollin. An die 40-polige Buchse (IDE-Buchse) ist ein altes IDE-Kabel angeschlossen, an den der GPIB-Stecker angelötet wurde.

GPIB Controller Implementierung

Der Controller übernimmt am Anfang den Bus  und steuert alle Geräte am Bus, d.h. er definiert sie als Listener, Talker oder „Taub“, also nicht am Bus partizipierend. Dazu nutzt er Kommandoleitungen (wie IFC und REN) und Bus-Kommandos (wie DCL, UNL, UNT). Ein Kommandobyte auf dem Bus unterscheidet sich von einem Datenbyte dadurch, dass der Controller die ATN-Leitung während des Sendens von Kommandobytes auf logisch 0 zieht.

Geräte werden durch das Ansprechen über ihre Listener-Adresse (=Geräteadresse + 0x20) zu Listenern und durch das Ansprechen über ihre Talker-Adresse (=Geräteadresse +0x40) zu Talkern. Es darf immer nur einen Talker geben, aber mehrere Listener. Der Controller hat üblicherweise, aber nicht zwingend, die Geräteadresse 0x00. Kommandos setzt der Controller mit der Funktion gpib_cmd() ab.

Meine simple Implementierung des Controllers sieht wie folgt aus:

  1. Übernahme des Busses durch REN und IFC (Funktion gpib_init() und gpib_controller_assign()), dann Senden von DCL (Funktion gpib_cmd()). Alle Geräte gehen dadurch in einen definierten Anfangszustand.
  2. Ausführen einer Endlosschleife:
    1. Kommandos werden von STDIN gelesen. Ein CR zeigt das Kommandoende an. Der Controller schaltet sich als Talker und und ein weiteres Gerät als Listener (z.B. mein Oszilloskop mit Geräte-Adresse 0x01). Das Kommando wird auf den Bus gelegt (gpib_cmd() + gpib_write()). Das Kommandoende wird über die Leitung EOI angezeigt (ein reale Controller würde sicher komplexer vorgehen…).
    2. Die Listener lesen das Kommando und führen es aus. Bei Kommandos ohne Antwort geht der Controller wieder in die Schleife, um neue Kommandos zu lesen. Bei Kommandos mit Antwort schaltet der Controller sich als Listener und ein weiteres Gerät (mein Oszilloskop) als Talker. Die Antwort wird vom Gerät gelesen (gpib_read()). Das Gerät zeigt das Ende der Antwort über die Leitung EOI an. Der Controller gibt jedes gelesene Zeichen auf STDOUT aus. Nach Ausgabe der Antwort geht der Controller wieder in die Schleife, um neue Kommandos zu lesen.
      Der Controller unterscheidet Kommandos mit und ohne Antwort anhand des Zeichens „?“ am Ende des Kommandos (stimmt nicht immer…).
  3. Asynchron Verarbeitung neben der Endlosschleife in Punkt 2.: Falls ein Gerät von sich aus, also ohne Einladung durch den Controller, am Bus aktiv werden will, erzeugt es einen Service Request SRQ (Ziehen der SRQ-Leitung auf logisch 0). Der Controller bekommt dies mit, ermittelt mittels eines Serial Polling genannten Vorgehens den Erzeuger des SRQs und liest dessen Status ein. Der Status wird auf STDOUT ausgegeben (Funktion gpib_serial_poll()). Serial Polling bedeutet, dass der Controller mit dem Kommando SPE (Serial Polling Enabled) das Polling einleitet. Alle Geräte werden dann hintereinander als Talker definiert, der Controller definiert sich als Listener und liest Daten vom Talker ein. Beim seriellen Polling gibt jeder Talker nur genau 1 Byte, sein Status Byte aus. Das SRQ-erzeugende Gerät hat das Bit 6 im Statusbyte gesetzt. Damit weiß der Controller, welches Gerät den Request erzeugt hat. Der Controller beendet mit SPD (Serial Polling Disable) das Polling, alle Geräte verhalten sich von da ab wieder „normal“. Das Behandeln des SRQs ist gerätespezifisch. Mein Oszilloskop teilt mit dreistelligen Errorcodes, wie z.B. „157“ Fehler bei der Kommandoerkennung („vertippt“) und ähnliches mit.
  4. Theoretisch gibt der Controller am Ende den Bus wieder frei (Funktion gpib_controller_release()).

Beim Handshake kann man den Controller mittels busy waiting auf das Ändern einer Handshake-Leitung warten lassen. Falls die Änderung nie kommt, weil z.B. das Gerät abgeschaltet wurde oder das Gerät den Handshake nicht richtig mitmacht, wartet der Controller dann ewig. Ich habe daher diese busy-waiting-Schleifen daher durch Schleifen ersetzt, die nach einem Timeout (5s) abbrechen. Damit bleibt der Controller auch in diesen Fällen benutzbar.

Im folgenden ist eine Session dargestellt. Wenn das Oszilloskop eingeschaltet wird und bereit ist, generiert es einen SRQ. Der Controller fragt bei der SRQ-Behandlung mittels „EVENT?“ den SRQ-Grund ab, es kommt die Antwort „401“. 401 bedeutet laut Oszi-Handbuch „2432A was just powered on.“. Danach folgt die User Eingabe „id?“ auf die das Gerät mit der Ausgabe seiner Typenbezeichnung antwortet. Danach werden ein paar Kommandos abgesetzt, die keine Antwort liefern:

INIT
MEASUREMENT WINDOW:ON
CURSOR FUNCTION: TIME,TARGET:CH1,UNITS:BASE
CURSOR TPOS:ONE:200,TPOS:TWO:500

Zum Schluss wird mittels „CH1?“ die aktuelle Konfiguration des Kanals 1 abgefragt.

dennis@soc:~> kermit -c
Connecting to /dev/ttyS2, speed 19200
 Escape character: Ctrl- (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
 
SRQ detected.
status byte from device 0x41 = 0x41 (char=A)
SRQ emitter is device = 0x41
 
command: EVENT?
Query. Will check for answer.
EVENT 401
> id?
command: id?
Query. Will check for answer.
ID TEK/2432A,V81.1,"24-DEC-89  V2.30 /2.5"
> INIT
command: INIT
Command only.
> MEASUREMENT WINDOW:ON
command: MEASUREMENT WINDOW:ON
Command only.
> CURSOR FUNCTION: TIME,TARGET:CH1,UNITS:BASE
command: CURSOR FUNCTION: TIME,TARGET:CH1,UNITS:BASE
Command only.
> CURSOR TPOS:ONE:200,TPOS:TWO:500
command: CURSOR TPOS:ONE:200,TPOS:TWO:500
Command only.
> CH1?
command: CH1?
Query. Will check for answer.
CH1 VOLTS:1E-1,VARIABLE:0,POSITION:0,COUPLING:DC,FIFTY:OFF,INVERT:OFF
>

Fazit: Insgesamt funktioniert somit die Implementierung eines Controllers mit dem AVR komplett in Software recht gut. Für einen echten Praxis-Einsatz müsste man die Software noch stark erweitern und vor allen auch mit anderen Geräten testen.

Hier die Software unter GNU General Public Licence als ZIP-Datei. Die ZIP-Datei enthält auch die Dateien uart.h/uart.c von Peter Fleury für die RS232 Kommunikation, die ebenfalls unter der GNU GPL steht.

ZIP-File mit allen Dateien:  gpib-0.66.zip

Versionshistorie:
0.1: Kommunikation mit einem Gerät (Tek 2432 getestet) ok.
0.63: Kommunikation mit 2 Geräten (und vermutlich auch mit mehr als 2) möglich. Fehler in Lesefunktion entfernt.
0.66: doxygen Dokumentation hinzugefügt

Eine Aufzeichnung einer kompletten Session mit 2 Geräten ist hier zu finden: Session mit 2 Geräten mit Code Version 0.63. Die verwendeten Geräte waren ein Oszilloskop Tektronix 2432A und ein Logik Analysator Tektronix 1241. Bei den Geräten wird die ID? abgefragt, beim Oszilloskop die momentane Konfigurationen der beiden Kanäle CH1? und CH2?, die Konfiguration für die Darstellung der aktuellen angezeigten Kurve WFMPRE? und dann die Kurve selbst (CURVE?). Das Datenformat wird dabei von Binary nach ASCII verändert. Danach wird der Logic Analysator angesprochen und mit REFMEM? der momentane Inhalt des Referenzspeichers ausgelesen.

Aufbau des Geräts

Im folgenden ein paar Bilder zum aufgebauten Gerät.

 

Weiterführende Links