# HG changeset patch # User Daniel O'Connor # Date 1610077012 -37800 # Node ID ffc9292eb00bf2ea953ca4bc6e319eff65d3777e # Parent b6dc43e6f6f06773eadb3ce8cb9e44228c6bdf91 Use edge detection to log time differences between edges diff -r b6dc43e6f6f0 -r ffc9292eb00b logpps.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/logpps.py Fri Jan 08 14:06:52 2021 +1030 @@ -0,0 +1,125 @@ +#!/usr/bin/env python + +# Copyright (c) 2021 +# Daniel O'Connor . 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, +# delta NUMERIC(15, 12) +# ); + +import datetime +import matplotlib.pylab as pylab +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) + + #dbh = sqlite3.connect('logpps.db') + dbh = psycopg2.connect('host=vm11 user=ppslog dbname=ppslog') + test(u, dbh, 'ncu-iono2-tx') + +def test(u, 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 + + vscale1 = float(u.ask('CH1:SCALE?').split()[1]) + print(('Channel 1 scale is %.2f volts/div' % (vscale1))) + + vscale2 = float(u.ask('CH2:SCALE?').split()[1]) + print(('Channel 2 scale is %.2f volts/div' % (vscale2))) + + 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: + ary1, ary2 = acquire(u, vscale1, vscale2) + #pylab.plot(ary1) + #pylab.plot(ary2) + #pylab.show() + sampletime = acqwindow / len(ary1) + d = getpdiffedge(ary1, ary2) * sampletime + + print('Delta is %.1f nsec' % (d * 1e9)) + if dbh != None: + now = datetime.datetime.now() + cur.execute('INSERT INTO ppslog(name, time, delta) VALUES(%s, %s, %s)', (name, now, d)) + 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 = 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, vscale1, vscale2): + u.write('ACQ:STATE 1') # Do a single acquisition + u.write('*OPC?') + u.read(2.0) # Wait for it to complete + + ary1 = getchannel(u, 1, vscale1) + ary2 = getchannel(u, 2, vscale2) + + return ary1, ary2 + +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()