Add gain control & options for data collection/plotting; fix doc

master
Harry Ho 2021-03-15 15:26:36 +08:00
parent bd792739c3
commit 33d81cdbdc
3 changed files with 38 additions and 16 deletions

View File

@ -6,7 +6,7 @@
# └── pi/ # └── pi/
# └── mlabs-testsuite/ # └── mlabs-testsuite/
# ├── rp_get_sayma_data.py # ├── rp_get_sayma_data.py
# └── creotech-raw/ # └── raw/
# | (possible existing data files, will be overwritten) # | (possible existing data files, will be overwritten)
# ├── rp_..._y1_raw.bin.py # ├── rp_..._y1_raw.bin.py
# ├── rp_..._y2_raw.bin.py # ├── rp_..._y2_raw.bin.py
@ -25,24 +25,27 @@
export HOST=pi@rpi-2 export HOST=pi@rpi-2
export HOSTPORT=6000 export HOSTPORT=6000
if [[ $1 = "" ]] || [[ $2 = "" ]] || [[ $3 = "" ]] || [[ $4 = "" ]] if [[ $1 = "" ]] || [[ $2 = "" ]] || [[ $3 = "" ]] || [[ $4 = "" ]] || [[ $5 = "" ]]
then then
echo "Arguments: <RP#1 name> <RP#1 channel> <RP#2 name> <RP#2 channel>" echo "Arguments: <RP#1 name> <RP#1 channel> <RP#2 name> <RP#1 channel> <RP#1 name>:<IN1 gain>,<IN2 gain> [<RP#2 name>:<IN1 gain>,<IN2 gain>]"
echo "(RP#1 and RP#2 can be the same)" echo "(If RP#1 and RP#2 are the same, skip the bracketed arguments)"
echo "Examples: "
echo "(1) creotech-1 1 creotech-1 2 creotech-1:LV,HV"
echo "(2) creotech-1 1 creotech-2 1 creotech-1:LV,LV creotech-2:HV,HV"
exit exit
fi fi
# Acquire data at the remote # Acquire data at the remote
if [[ $1 = $3 ]] if [[ $1 = $3 ]]
then then
ssh -t -p $HOSTPORT $HOST "cd mlabs-testsuite && python3 rp_get_sayma_data.py creotech-raw $1" ssh -t -p $HOSTPORT $HOST "cd mlabs-testsuite && python3 rp_get_sayma_data.py raw $5"
else else
ssh -t -p $HOSTPORT $HOST "cd mlabs-testsuite && python3 rp_get_sayma_data.py creotech-raw $1 $3" ssh -t -p $HOSTPORT $HOST "cd mlabs-testsuite && python3 rp_get_sayma_data.py raw $5 $6"
fi fi
# Transfer data from remote to local # Transfer data from remote to local
scp -P $HOSTPORT $HOST:/home/pi/mlabs-testsuite/creotech-raw/rp_$1_y$2_raw.bin creotech-raw/ scp -P $HOSTPORT $HOST:/home/pi/mlabs-testsuite/raw/rp_$1_y$2_raw.bin creotech-raw/
scp -P $HOSTPORT $HOST:/home/pi/mlabs-testsuite/creotech-raw/rp_$3_y$4_raw.bin creotech-raw/ scp -P $HOSTPORT $HOST:/home/pi/mlabs-testsuite/raw/rp_$3_y$4_raw.bin creotech-raw/
# Plot data at local # Plot data at local
# (Note: requires numpy, matplotlib and scipy on local) # (Note: requires numpy, matplotlib and scipy on local)

View File

@ -46,15 +46,17 @@ def main():
y1 = rp_raw_to_numpy(y1_raw) y1 = rp_raw_to_numpy(y1_raw)
y2 = rp_raw_to_numpy(y2_raw) y2 = rp_raw_to_numpy(y2_raw)
# Note that RedPitaya's oscilloscope has a sampling rate @ 125MHz # Define t as an array of timestamps (in seconds) for each sample
# (Note that RedPitaya's oscilloscope has a sampling rate @ 125MHz)
t = np.arange(y1.shape[0])/125e6 t = np.arange(y1.shape[0])/125e6
# Generate matrix Y by having arrays y1 and y2 as 2 rows # Generate matrix Y by having arrays y1 and y2 as 2 rows
y = np.c_[y1, y2].T y = np.c_[y1, y2].T
# Multiply an array of cos(2pi*9e6*t) with each row in Y; # Element-wise multiply an array of cos(2pi*9e6*t) with each row in Y;
# Then, downsample the array by 10 as Z. # Then, downsample the array by 10 as Z
z = signal.decimate(y*np.exp(1j*2*np.pi*9e6*t), q=10, ftype="fir", zero_phase=True)[:, 10:] z = signal.decimate(y*np.exp(1j*2*np.pi*9e6*t), q=10, ftype="fir", zero_phase=True)[:, 10:]
# Downsample Z by 10 again. # Downsample Z by 10 again.
z = signal.decimate(z, q=10, ftype="fir", zero_phase=True)[:, 10:] z = signal.decimate(z, q=10, ftype="fir", zero_phase=True)[:, 10:]
# Element-wise multiply Z[0] with the conjugate of Z[1] to get the phase difference (i.e. angle(z0) - angle(z1)), and use the mean value.
angle = np.angle(np.mean(z[0]*z[1].conj())) angle = np.angle(np.mean(z[0]*z[1].conj()))
print(angle) print(angle)

View File

@ -6,9 +6,11 @@ import os
class RPSCPI: class RPSCPI:
def __init__(self, rp_name, rp_host): def __init__(self, rp_name, rp_host, ch1_gain, ch2_gain):
self.name = rp_name self.name = rp_name
self.host = rp_host self.host = rp_host
self.ch1_gain = ch1_gain
self.ch2_gain = ch2_gain
def connect(self): def connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -27,6 +29,8 @@ class RPSCPI:
def trigger_prep(self): def trigger_prep(self):
self.sendmsg("ACQ:RST") self.sendmsg("ACQ:RST")
self.sendmsg("ACQ:SOUR1:GAIN {}".format(self.ch1_gain.upper()))
self.sendmsg("ACQ:SOUR2:GAIN {}".format(self.ch2_gain.upper()))
self.sendmsg("ACQ:START") self.sendmsg("ACQ:START")
async def trigger(self): async def trigger(self):
@ -55,17 +59,30 @@ async def gather_trigger(rp_list):
def main(): def main():
parser = argparse.ArgumentParser(description="Data collection tool for Sayma DAC/TTL at RedPitaya") parser = argparse.ArgumentParser(description="Data collection tool for Sayma DAC/TTL at RedPitaya")
parser.add_argument("dir", help="output directory", type=str) parser.add_argument("dir", help="output directory", type=str)
parser.add_argument("rps", help="name(s) of the target RedPitayas where data is collected " parser.add_argument("rps_gains", metavar="RP_NAME:CH1_GAIN,CH2_GAIN",
"simultaneously; any of: " + " ".join(list(RP_IP_ADDRS.keys())), help="choose LV (+-1V) gain or HV (+-20V) gain on each channel for RP named <RP_NAME>; "
"e.g. mlabs:LV,HV means LV for IN1 and HV for IN2 on RP mlabs;\n"
"<RP_NAME> must be one of: " + " ".join(list(RP_IP_ADDRS.keys())),
type=str, nargs='+') type=str, nargs='+')
parser.add_argument("--txt", help="save data as additional human-readable text files", parser.add_argument("--txt", help="save data as additional human-readable text files",
action="store_true") action="store_true")
args = parser.parse_args() args = parser.parse_args()
gains = dict()
try:
for gain in args.rps_gains:
rp_name, ch1ch2_gains = gain.split(':')
ch1_gain, ch2_gain = ch1ch2_gains.split(',')
gains[rp_name] = ch1_gain, ch2_gain
if rp_name == "" or ch1_gain == "" or ch2_gain == "":
raise SyntaxError("Must specify IN1 and IN2 gains for each target RP.")
except ValueError:
raise SyntaxError("Must specify input gains in the format of: <RP_NAME>:<CH1_GAIN>,<CH2_GAIN>")
# Connect a socket to each RP # Connect a socket to each RP
rps = [] rps = []
for rp_name in args.rps: for rp_name in gains:
rp = RPSCPI(rp_name, RP_IP_ADDRS[rp_name]) rp = RPSCPI(rp_name, RP_IP_ADDRS[rp_name], *gains[rp_name])
rp.connect() rp.connect()
rps.append(rp) rps.append(rp)