view logpps.py @ 79:84f96c5fe791

Use different message ID that does not result in "Query UNTERMINATE" messages in the error log. Fix testsrq. Rename queryrsb to querystb as that matches the operating manual.
author Daniel O'Connor <doconnor@gsoft.com.au>
date Fri, 27 Sep 2024 16:53:43 +0930
parents 6ffa6fcf278e
children
line wrap: on
line source

#!/usr/bin/env python

# Copyright (c) 2021
#      Daniel O'Connor <darius@dons.net.au>.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Expected DB schema
# CREATE TABLE ppslog (
#   name TEXT,
#   time TIMESTAMP WITH TIME ZONE,
#   delta12 NUMERIC(15, 12),
#   delta13 NUMERIC(15, 12)
# );

import datetime
import numpy
import psycopg2
#import sqlite3
import sys
import time
# Should try this code instead: https://github.com/python-ivi/python-usbtmc
import usb488

def main():
    u = usb488.USB488Device()
    print('Found device')

    # See "TDS2000 Programmer.pdf"
    res = u.ask('*IDN?')
    print('IDN reports ' + res)

    hostname = 'radartest1'
    nchan = 2
    #dbh = sqlite3.connect('logpps.db')
    dbh = psycopg2.connect('host=vm11 user=ppslog dbname=ppslog')
    #dbh = None
    test(u, nchan, dbh, hostname)

def test(u, nchan, dbh = None, name = None):
    if dbh != None:
        cur = dbh.cursor()

    u.write('ACQ:MODE SAMPLE')
    u.write('ACQ:STATE STOP')

    #u.write('DATA:ENC RIB')		# Big endian signed
    #u.write('DATA:WIDTH 2')		# 2 bytes wide

    vscales = []
    for i in range(nchan):
        tmp = float(u.ask('CH%d:SCALE?' % (i + 1)).split()[1])
        vscales.append(tmp)
        print(('Channel %d scale is %.2f volts/div' % (i + 1, tmp)))

    hscale = float(u.ask('HOR:MAIN:SCALE?').split()[1])
    print(('Horizontal scale is %.5f nsec/div' % (hscale * 1e9)))
    # TEK2024B doesn't grok HOR:DIV? so hard code 10 (has 8 vertically)
    acqwindow = hscale * 10.0

    while True:
        arys = acquire(u, vscales)
        #import matplotlib.pylab as pylab
        #for a in arys:
        #    pylab.plot(a)
        #pylab.show()
        sampletime = acqwindow / len(arys[0])
        deltas = []
        for i in range(nchan - 1):
            delta = getpdiffedge(arys[0], arys[i + 1]) * sampletime
            deltas.append(delta)
            print('Delta 1-%d is %.1f nsec' % (i + 2, delta * 1e9))

        if dbh != None:
            now = datetime.datetime.now()
            d12 = deltas[0]
            d13 = None
            if nchan > 2:
                d13 = deltas[1]
            cur.execute('INSERT INTO ppslog(name, time, delta12, delta13) VALUES(%s, %s, %s, %s)', (name, now, d12, d13))
            dbh.commit()

def getchannel(u, ch, vscale):
        u.write('DAT:SOU CH%d' % (ch))	# Set the curve source to desired channel
        result = u.ask('CURVE?', 1.0)	# Ask for the curve data
        data1 = buffer(result[13:])		# Chop off the header (should verify this really..)
        ary = numpy.frombuffer(data1, dtype = '>h')
        ary = ary / 32768.0 * vscale # Scale to volts
        return ary

def acquire(u, vscales):
        u.write('ACQ:STATE 1')	# Do a single acquisition
        u.write('*OPC?')
        u.read(2.0)	# Wait for it to complete

        arys = []
        for i in range(len(vscales)):
            arys.append(getchannel(u, i + 1, vscales[i]))

        return arys

def getpdiffedge(ary1, ary2):
    '''Return phase difference in samples between two signals by edge detection'''

    # Rescale to 0-1
    ary1 = ary1 - ary1.min()
    ary1 = ary1 / ary1.max()
    ary2 = ary2 - ary2.min()
    ary2 = ary2 / ary2.max()

    # Find rising edge of each
    ary1pos = numpy.argmax(ary1 > 0.2)
    ary2pos = numpy.argmax(ary2 > 0.2)

    return ary1pos - ary2pos

if __name__ == '__main__':
    main()