Skip to content

Commit

Permalink
hil_plot : hardware in the loop with plotting
Browse files Browse the repository at this point in the history
needs numpy and matplotlib
	modified:   awg_data.py
	new file:   hil_plot.py
  • Loading branch information
petermilne committed Aug 13, 2017
1 parent e5be258 commit bf3158e
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 17 deletions.
39 changes: 22 additions & 17 deletions awg_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
import numpy as np

class RunsFiles:
def __init__(self, uut, files):
def __init__(self, uut, files, run_forever=False):
self.uut = uut
self.files = files
self.run_forever = run_forever

def load(self):
for f in self.files:
with open(f, mode='r') as fp:
self.uut.load_awg(fp.read())
yield f
for ii in range(99999 if self.run_forever else 1):
for f in self.files:
with open(f, mode='r') as fp:
self.uut.load_awg(fp.read())
yield f




class RainbowGen:
Expand All @@ -30,25 +34,26 @@ def sinc(self, ch):
nsam = self.nsam
nchan = self.nchan
NCYCLES = self.NCYCLES
xoff = ch*nsam/NCYCLES/10
xoff = ch*100
xx = np.array(range(-nsam/2-xoff,nsam/2-xoff))*NCYCLES*2*np.pi/nsam
return [ np.sin(x)/x if x != 0 else 1 for x in xx ]

def __init__(self, uut, nchan, nsam):
def __init__(self, uut, nchan, nsam, run_forever=False):
self.uut = uut
self.nchan = nchan
self.nsam = nsam
self.nsam = nsam
self.run_forever = run_forever
self.sw = self.sin()
self.aw = np.zeros((nsam,nchan))
for ch in range(nchan):
self.aw[:,ch] = self.rainbow(ch)

def load(self):
#for ch in range(self.nchan):
for ch in range(8): # convenient to plot 8
aw1 = np.copy(self.aw)
aw1[:,ch] = np.add(np.multiply(self.sinc(ch),5),2)
print("loading array ", aw1.shape)
self.uut.load_awg((aw1*(2**15-1)/10).astype(np.int16))
print("loaded array ", aw1.shape)
yield ch
def load(self):
for ii in range(99999 if self.run_forever else 1):
for ch in range(self.nchan):
aw1 = np.copy(self.aw)
aw1[:,ch] = np.add(np.multiply(self.sinc(ch),5),2)
print("loading array ", aw1.shape)
self.uut.load_awg((aw1*(2**15-1)/10).astype(np.int16))
print("loaded array ", aw1.shape)
yield ch
82 changes: 82 additions & 0 deletions hil_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python
# Harware In Loop : load AO data,run a shot, get AI data, repeat.
# upload to AWG and optionally run a capture.
# data for upload is either File (host-local data file) or Rainbow, a test pattern.
# assumes that clocking has been pre-assigned.

import sys
import acq400_hapi
import awg_data
import argparse
import numpy as np
import matplotlib.pyplot as plt

def store_file(it, rdata, nchan, nsam):
fn = 'DATA/ai%04d.dat' % (it)
print("store_file {}".format(fn))

with open(fn, 'w') as f:
f.write(rdata)

def plot(it, rdata, nchan, nsam):
raw = np.fromstring(rdata, dtype=np.int16)
chx = np.reshape(raw, (nsam, nchan))
for ch in range(0,nchan):
plt.plot(chx[:,ch])

plt.show()
plt.pause(0.0001)

def run_shots(args):
uut = acq400_hapi.Acq400(args.uuts[0])
acq400_hapi.cleanup.init()
if args.plot:
plt.ion()

uut.s0.transient = 'POST=%d SOFT_TRIGGER=%d DEMUX=0' % \
(args.post, 1 if args.trg == 'int' else 0)

for sx in uut.modules:
uut.modules[sx].trg = '1,1,1' if args.trg == 'int' else '1,0,1'

if args.files != "":
work = awg_data.RunsFiles(uut, args.files.split(','), run_forever=True)
else:
work = awg_data.RainbowGen(uut, args.nchan, args.awglen, run_forever=True)

store = store_file
loader = work.load()
for ii in range(0, args.loop):
print("shot: %d" % (ii))
f = loader.next()
print("Loaded %s" % (f))
uut.run_oneshot()
print("read_chan %d" % (args.post*args.nchan))
rdata = uut.read_chan(0, args.post*args.nchan)
store(ii, rdata, args.nchan, args.post)
if args.plot > 0 :
if args.plot == 1:
plt.cla()
plt.title("AI for shot %d %s" % (ii, "persistent plot" if args.plot > 1 else ""))
plot(ii, rdata, args.nchan, args.post)

raw_input("hit return when done")


def run_main():
parser = argparse.ArgumentParser(description='acq1001 HIL demo')
parser.add_argument('--files', default="", help="list of files to load")
parser.add_argument('--loop', type=int, default=1, help="loop count")
parser.add_argument('--nchan', type=int, default=32, help='channel count for pattern')
parser.add_argument('--awglen', type=int, default=2048, help='samples in AWG waveform')
parser.add_argument('--post', type=int, default=100000, help='samples in ADC waveform')
parser.add_argument('--trg', default="int", help='trg "int|ext rising|falling"')
parser.add_argument('--plot', type=int, default=1, help='--plot 1 : plot data, 2: persistent')
parser.add_argument('uuts', nargs=1, help="uut ")
run_shots(parser.parse_args())

# execution starts here

if __name__ == '__main__':
run_main()

0 comments on commit bf3158e

Please sign in to comment.