pygpibtoolkit/plotter/gpib_plotter.py

Mon, 04 Jun 2018 22:28:05 +0200

author
David Douard <david.douard@logilab.fr>
date
Mon, 04 Jun 2018 22:28:05 +0200
changeset 109
c2d93abebab3
parent 108
dadf7c8d43ad
permissions
-rw-r--r--

[plotter] add a --mockup option to the demo main function

# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
""" Copyright (c) 2007-2008 David Douard (Paris, FRANCE).
https://bitbucket.org/dddouard/pygpibtoolkit -- mailto:david.douard@sdfa3.org
"""

import sys
import os
from pygpibtoolkit import pygpib as gpib
from pygpibtoolkit.prologix import GPIB


class GPIBplotter(GPIB):
    _replies = {
        "OE": "0",
        "OH": "0,0,10000,7500",
        "OI": "7470A",
        "OP": "0,0,10000,7500",
        "OO": "0,1,0,0,0,0,0,0",
        "OF": "40,40",
        "OS": "24",
        }

    def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1,
                 address=5, started_cb=None):
        super().__init__(device, baudrate, timeout, address, mode=0)
        self.plot_started_cb = started_cb

    def plot_started(self):
        if callable(self.plot_started_cb):
            self.plot_started_cb()

    def load_plot(self, wait_timeout=0):
        """
        Make a full plot process.

        'wait_timeout' is the first timeout. Same semantic as the
        'timeout' property of a serial connection (if set to None, it
        will block until the GPIB device actually perform a plot
        command.)
        """
        res = ""
        i = 0
        # replies dict is modified in some cases, so make a copy
        replies = self._replies.copy()

        if wait_timeout is not None and not isinstance(
                wait_timeout, (float, int)):
            raise TypeError("wait_timeout (%s:%s) has wrong type" % (
                repr(wait_timeout), type(wait_timeout)))
        if wait_timeout < 0:
            raise ValueError

        self._cnx.timeout = wait_timeout
        firstloop = True
        while i < self._retries:
            l = self._cnx.readline().strip().decode()
            if l and firstloop:
                self._cnx.timeout = self._timeout
                firstloop = False
                self.plot_started()
            if not l:
                if i == 0:  # > (self._retries/2):
                    # we just received new stuffs (i is reset in the else blk)
                    for k, v in replies.items():
                        # check wether we should reply smthg
                        eres = res.replace('\n', '').strip()
                        shouldreply = any(eres.endswith(k + sfx)
                                          for sfx in ('', ';', ';OE'))
                        if shouldreply:
                            self._cnx.write(("%s" % v).encode())
                            if k == "OS":
                                # don't remember why we need this...
                                replies[k] = "16"
                            break
                    self._cnx.write(b'\r')
                    # time.sleep(0.1)
                i += 1
            else:
                # if not res:
                #     print "Plotting..."
                res += l + '\n'
                i = 0
                # time.sleep(0.1)
        if res:
            print("DONE (received %d characters)" % len(res))
        return res


def main():
    global GPIBplotter

    import optparse
    opt = optparse.OptionParser(
        'A simple HP7470A GPIB plotter emulator for '
        'USB-GPIB bundle (ProLogix)')
    opt.add_option(
        '-f', '--filename', default=None,
        dest='filename',
        help='Output filename. If not set, write to stdout')
    opt.add_option(
        '-d', '--device', default='/dev/ttyUSB0',
        dest='device',
        help='Device of the RS232 connection (default: /dev/ttyUSB0)')
    opt.add_option(
        '-a', '--address', default=0,
        dest='address',
        help='GPIB address of the device')
    opt.add_option(
        '-l', '--loop', default=False,
        action="store_true",
        dest="loop",
        help=("Continuously wait for new plots. If set, filename must be "
              "set and files will be created with _n at the end"))
    opt.add_option(
        '-v', '--verbose', default=False,
        action="store_true",
        dest="verbose",
        help="Verbose mode")
    opt.add_option(
        '-m', '--mockup', default=False,
        action="store_true",
        dest='mockup',
        help='Use a pseudo GPIB connection (for test purpose)')

    options, argv = opt.parse_args(sys.argv)

    if options.loop and not options.filename:
        opt.error('If loop is set, you *must* provide a filename')

    if options.filename:
        outf = open(options.filename, "w")
    else:
        outf = sys.stdout

    if options.mockup:
        from pygpibtoolkit.plotter.gpib_plotter_mockup import GPIBplotter

    try:
        plotter = GPIBplotter(
            device=options.device, address=int(options.address),
            timeout=0.06)
    except (OSError, gpib.ConnectionError) as e:
        sys.stderr.write('Connection error:\n\t' + '\n\t'.join(
            [str(x) for x in e.args]) + '\n')
        sys.stderr.write('Check your parameters\n')
        sys.exit(1)
    if options.verbose:
        sys.stderr.write('connection established\n')

    loop = True
    nloop = 0
    while loop:
        plot = plotter.load_plot(wait_timeout=0.1)
        if options.verbose:
            sys.stderr.write('.')
        if plot:
            outf.write(plot)
            if options.verbose:
                sys.stderr.write('\n')
            sys.stderr.write(
                'Received a new plot (written to %s)\n' % outf.name)
            if not options.loop:
                loop = False
            else:
                nloop += 1
                fname, ext = os.path.splitext(options.filename)
                outf = open(fname + "_%d" % nloop + ext, 'w')


if __name__ == '__main__':
    main()

mercurial