First commit
This commit is contained in:
commit
d88e9f9955
2 changed files with 110 additions and 0 deletions
95
xfer_tracer/script.py
Executable file
95
xfer_tracer/script.py
Executable file
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import pyvisa
|
||||
import time
|
||||
|
||||
import pyaudio as pa
|
||||
import numpy as np
|
||||
|
||||
phase = 0.0 # in cycles
|
||||
scaled_frequency = 0.0
|
||||
# actual frequency = scaled_frequency * sample_rate
|
||||
# For repeatability, scaled_frequency should ideally fit in
|
||||
# much fewer than 53 bits.
|
||||
# More precisely, if scaled_frequency * frame_count is always exact, we get
|
||||
# negligible phase errors over 1hr.
|
||||
|
||||
def audio_callback(in_data, frame_count, time_info, status):
|
||||
global phase
|
||||
L = np.sin(2 * np.pi * (phase + np.arange(frame_count) * scaled_frequency)).astype(np.float32) # cast to float
|
||||
delta_phase = scaled_frequency * frame_count # exact
|
||||
delta_phase -= np.floor(delta_phase) # exact
|
||||
phase += delta_phase # error at most ulp(1) = 2^-52
|
||||
if(phase >= 1):
|
||||
phase -= int(phase)
|
||||
outbytes = L.tobytes()
|
||||
#print(L, frame_count)
|
||||
return (outbytes, pa.paContinue)
|
||||
|
||||
paudio = pa.PyAudio()
|
||||
stream = paudio.open(format=pa.paFloat32,
|
||||
channels=1,
|
||||
rate=48000,
|
||||
output=True,
|
||||
stream_callback=audio_callback)
|
||||
|
||||
def do_frequency(scaled_f, osci, hscale):
|
||||
scaled_frequency = scaled_f
|
||||
time.sleep(0.1)
|
||||
osci.write("acquire:state run") # Restart acquisition sequence
|
||||
time.sleep(10 * hscale)
|
||||
|
||||
osci.write("data:source CH1")
|
||||
A_samps = osci.query_binary_values("curve?",datatype='b',container=numpy.array)
|
||||
A_samps = A_samps.astype(np.float64)
|
||||
|
||||
osci.write("data:source CH2") # For now, do not adjust for zeros in the resp.
|
||||
B_samps = osci.query_binary_values("curve?",datatype='b',container=numpy.array)
|
||||
B_samps = B_samps.astype(np.float64)
|
||||
|
||||
A_samps = np.rfft(A_samps) # No window, because of the precise frequency
|
||||
B_samps = np.rfft(B_samps)
|
||||
|
||||
# We have (10 * hscale)/Tcurv periods
|
||||
return B_samps[np.round((10 * hscale) * (scaled_f * 4800))]
|
||||
/A_samps[np.round((10 * hscale) * (scaled_f * 4800))]
|
||||
|
||||
def find_oscillo():
|
||||
rm = pyvisa.ResourceManager()
|
||||
R = rm.list_resources("USB?*")
|
||||
if R.empty():
|
||||
print("No device found")
|
||||
exit(1)
|
||||
return rm.open_resource(R[0])
|
||||
|
||||
osci = find_oscillo()
|
||||
print(osci.query("*IDN?"))
|
||||
|
||||
osci.write("*RST")
|
||||
time.sleep(5)
|
||||
osci.write("horizontal:main:scale 5.0e-4")
|
||||
|
||||
osci.write("ch1:scale 1.0e-1")
|
||||
osci.write("ch1:bandwidth ON")
|
||||
osci.write("ch1:coupling AC")
|
||||
osci.write("select:ch1 1")
|
||||
|
||||
osci.write("ch2:scale 5.0e-2")
|
||||
osci.write("ch2:bandwidth ON")
|
||||
osci.write("ch2:coupling AC")
|
||||
osci.write("select:ch2 1")
|
||||
|
||||
# 8-bit data
|
||||
osci.write("data:source CH1")
|
||||
osci.write("data:encdg ascii")
|
||||
|
||||
osci.write("trigger:main:edge:source CH1")
|
||||
osci.write("trigger:main:mode NORMAL")
|
||||
osci.write("trigger:main:type EDGE")
|
||||
|
||||
osci.write("acquire:mode average")
|
||||
osci.write("acquire:numavg 128")
|
||||
osci.write("acquire:stopafter sequence")
|
||||
osci.write("acquire:state RUN")
|
||||
|
||||
print(osci.query("curve?"))
|
15
xfer_tracer/shell.nix
Normal file
15
xfer_tracer/shell.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> {};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [
|
||||
(pkgs.python3.withPackages (ps : [
|
||||
ps.pyvisa
|
||||
ps.pyvisa-py
|
||||
ps.zeroconf
|
||||
ps.psutil
|
||||
ps.pyusb
|
||||
ps.numpy
|
||||
ps.pyaudio]))
|
||||
];
|
||||
}
|
Loading…
Reference in a new issue