I began getting some trigger too fast errors with the code I was using, and the problem was somewhat sporadic at 50 SPS - worse at some times, better at others. At 40 SPS, I got no errors, at 60 SPS, I always got them. From doing a little bit of experimentation, I found that running captures while transferring one data point per GPIB transaction could not do better than about 19 ms with my GPIB to USB bridge. This was with all the settings necessary for fast mode and "OFORMAT SINT". That is not much faster than transferring not in fast mode with "OFORMAT ASCII", just about 1 ms for me.
To solve this problem, I just transferred all the data in one transaction. It is not much more work to go from the float values to integers, and you can get a lot better throughput with integers, probably because this output format puts the meter in fast mode. However, it is difficult to avoid trigger too fast errors for long captures at fast sample rates, even if you can further increase the sample rate and get no errors with short captures. For example, with 10kSPS and 10k samples I get an error, and with 50kSPS and 131 samples I get no error. I consistently get an error at 132 samples with 50kSPS. With 10kSPS, 1k samples is fine (I haven't checked the exact limit), and with 5kSPS, 10k samples is fine. Changing the aperture time as a fraction of the sampling interval has minimal effect up to maybe 90% unless you are on the line. The code I used for this is below - I just used this for testing, and there is the possibility it will hang forever if something goes awry.
from pyvisa import ResourceManager
import time
import pandas as pd
import numpy as np
#import matplotlib.pyplot as plt
DCVrange = 0.1
numsamp = 10000
sfreq = 5000
sleeptime = 1
stime = 1/sfreq
aper = 80*stime/100
logfile = 'test.csv'
df = pd.DataFrame(columns = ("V","freq"), dtype = float)
rm = ResourceManager()
dmm = rm.open_resource('GPIB1::22::INSTR')
dmm.timeout = None
# Setup commands and clear errors
dmm.write("END ALWAYS")
dmm.write("BEEP OFF")
dmm.write("TARM HOLD")
dmm.write("TRIG HOLD")
dmm.write("ERR?")
dmm.write("OFORMAT ASCII")
print("")
print("Voltage meter: ", dmm.query("ID?"))
print("")
print("Waiting %d seconds" % sleeptime)
time.sleep(sleeptime)
# For high-speed mode
dmm.write("ARANGE OFF")
dmm.write("MATH OFF")
dmm.write("OFORMAT DINT")
dmm.write("DISP OFF")
# Measurement parameters
dmm.write("DCV %f" % DCVrange)
dmm.write("APER %f" % aper)
dmm.write("TIMER %f" % stime)
dmm.write("NRDGS %d, TIMER" % numsamp)
dmm.write("AZERO OFF")
dmm.write("MEM OFF")
dmm.write("INBUF ON")
dmm.write("RATIO OFF")
dmm.write("TARM AUTO")
V = np.empty([numsamp], dtype=np.int32)
t0 = time.time()
V = dmm.query_binary_values("TRIG SGL", datatype='i', delay=0, container=np.ndarray, data_points=numsamp, is_big_endian=True, header_fmt='empty')
scale_factor = dmm.query_ascii_values("ISCALE?")[0]
t_tot = time.time() - t0
avg_time = t_tot/(numsamp-1)
print("Average sample time: ", avg_time)
dmm.write("DISP ON")
dmm.write("BEEP ONCE")
dmm.write("OFORMAT ASCII")
df["V"] = V*scale_factor
df["freq"][0] = sfreq
df.to_csv(path_or_buf= logfile)
err_code = dmm.query("ERRSTR?")
if(int(err_code[0]) == 0):
print("Valid data: no errors")
else:
print("Invalid data: ", err_code)
I don't know offhand why I get the trigger too fast error under specific conditions with this code. It would seem that if the GPIB transfers can keep up with a handful of readings, there should be idle time between the transfers of individual samples. If there is idle time, there should not be enough fluctuation between times of individual transfers that 50kSPS could work for 100 or so readings and 10kSPS could give errors at some point. This code has no way of giving the intervals between individual samples, so it is not clear how many times in, for example, a 1M sample capture at 10kSPS the error is being thrown. In such an experiment with aperture time at 90% of the sampling interval, the average sample time was 100.14us, and this was consistent. In any event, I have run multiple captures using this code (with OFORMAT DREAL) at 4M samples and 200 SPS with no trigger errors, and I used 90% aperture for those. It would be nice to use this method to take arbitrarily large captures at the GPIB bandwidth limit of about 50kSPS for DINT and 100kSPS for SINT, but I haven't been able to pull that off yet.