[Python] Flexible data acquisition on the Keysight 34465A - Page 1
Forum section: electronics / projects

author: Pack34
author_rank: Frequent Contributor
timestamp: June 07, 2023, 08:27:18 pm
content: What I'm trying to accomplish, is to set the DMM to using the external trigger and collecting 1 sample at each edge of the trigger. The issue is that the amount of triggers will be unknown. I'd like to be able to set theTRIGGER:COUNTto infinity as per the programming manual and then do aREAD?when I'm ready to grab the data. The issue is that this doesn't work. The number of triggers specified seems to need to be satisfied in order to query the data from the meter. Otherwise it just times out waiting for a response.When doing aREADinstead of aFETCHit triggers error420 Query UNTERMINATED.The programming manual gives the option of INIFINTIY for the TRIGGER_COUNT value so I would assume I should be able to do something like this. Unless there's a specific mode I need to put it in? Do I need to send an alternate of INIT to close the data collection process?Code:import pyvisa as visaimport timeimport csvimport datetime# Setup our instrumentrm = visa.ResourceManager()v34465A = rm.open_resource('USB0::0x2A8D::0x0101::MY57514376::0::INSTR') # Open instrument over USBv34465A.write(':CONFigure:VOLTage:DC %G,%s' % (1.0, 'MAXimum')) # Set range and resolutionv34465A.write(':SAMPle:COUNt %d' % (1)) # Specify number of samples to 100#v34465A.write(':SAMPle:SOURce %s' % ('TIMer')) # Sample using a timer#v34465A.write(':SAMPle:TIMer %G' % (0.1)) # Timer interval of 100msv34465A.write(':SAMPle:SOURce %s' % ('IMMediate')) # Sample as fast as possiblev34465A.write(':TRIGger:SOURce %s;SLOP POS' % ('EXTernal')) # Immediately trigger on initv34465A.write(':TRIGger:COUNt %d' % (10)) #v34465A.write(':FORMat:DATA %s' % ('ASCii')) # Data format must be set to fetchv34465A.write(':INITiate:IMMediate') # Start sampling# Delay needed to sample. Fetching data will timeout if data not readyprint("Sampling...")input("Press Enter to continue...")print("Done")# Retrieve the data from the instrumenttemp_values = v34465A.query_ascii_values(':READ?')# temp_values = v34465A.query_ascii_values(':FETCh?')# Create data filefileNameString = datetime.datetime.now().strftime("%y%m%d%H%M") + "_data.csv"f1 = open(fileNameString, "w", newline='', encoding='utf-8')c = csv.writer(f1)header = ['Sample', 'Voltage']c.writerow(header)sample_counter = 0for x in temp_values:data = [ sample_counter, x ]c.writerow(data)sample_counter = sample_counter+1f1.close()v34465A.close()rm.close()

author: Pack34
author_rank: Frequent Contributor
timestamp: June 07, 2023, 09:43:35 pm
content: After spending most of the day on this, I think I figured it out. You have to return the device to idle before you can retrieve the data. The READ command is supposed to be a FETCH and delete but I haven't been able to get that to work. The workaround I'm using is to query the amount of data points in memory and then remove that data in a separate transaction. Feels cludgey but it works.Code:import pyvisa as visaimport timeimport csvimport datetime# Setup our instrumentrm = visa.ResourceManager()v34465A = rm.open_resource('USB0::0x2A8D::0x0101::MY57514376::0::INSTR') # Open instrument over USBv34465A.write(':CONFigure:VOLTage:DC %G,%s' % (1.0, 'MAXimum')) # Set range and resolutionv34465A.write(':SAMPle:COUNt %d' % (1)) # Specify number of samples to 100v34465A.write(':SAMPle:SOURce %s' % ('IMMediate')) # Sample as fast as possiblev34465A.write(':TRIGger:SOURce %s;SLOP POS' % ('EXTernal')) # External triggeringv34465A.write(':TRIGger:COUNt %s' % ('INFinity')) # Trigger as many times as memory allowsv34465A.write(':FORMat:DATA %s' % ('ASCii')) # Data format must be set to fetchv34465A.write(':INITiate:IMMediate') # Start sampling# Wait for keypress for testing purposesprint("Sampling...")input("Press Enter to continue...")print("Done")# ABORT returns the DMM to idle state to retrieve datav34465A.write(':ABORt')# Retrieve the data from the instrument by reading how much data there is, and removing that amount of datatemp_values = v34465A.query_ascii_values(':DATA:POINts?')points = int(temp_values)temp_values = v34465A.query_ascii_values(':DATA:REMove? %d' % (points))# Create data filefileNameString = datetime.datetime.now().strftime("%y%m%d%H%M") + "_data.csv"f1 = open(fileNameString, "w", newline='', encoding='utf-8')c = csv.writer(f1)header = ['Sample', 'Voltage']c.writerow(header)sample_counter = 0for x in temp_values:data = [ sample_counter, x ]c.writerow(data)sample_counter = sample_counter+1f1.close()v34465A.close()rm.close()

author: TizianoHV
author_rank: Regular Contributor
timestamp: June 08, 2023, 08:55:30 am
content: I think you shouldn't sent 'READ?' or 'FETCH?' with 'TRIG:COUNT INF' because they'll wait for infinite readings!Since readings are saved to the memory i would work only with memory. As soon as a reading is stored you read and clear it.Code:import pyvisa as visaimport timeimport csvimport datetime# Setup our instrumentrm = visa.ResourceManager()v34465A = rm.open_resource('USB0::0x2A8D::0x0101::MY57514376::0::INSTR') # Open instrument over USBv34465A.write('*RST') #Reset instrumentv34465A.write('CONF:VOLT:DC %G,%s' % (1.0, 'MAXimum')) # Set range and resolutionv34465A.write('SAMP:COUN %d' % (1)) #1 sample per triggerv34465A.write('TRIG:SOUR EXT;SLOP POS') # External triggeringv34465A.write('TRIG:COUN INF') #Infinite triggers#v34465A.write(':FORM:DATA %s' % ('ASCii')) #It is necessary? #Data format must be set to fetch# Create data filefileNameString = datetime.datetime.now().strftime("%y%m%d%H%M") + "_data.csv"f1 = open(fileNameString, "w", newline='', encoding='utf-8')c = csv.writer(f1)header = ['Sample', 'Voltage']c.writerow(header)tempData = []loop = "ok"while loop != "s":print("Meas loop started. CTRL+c to stop")v34465A.write(':INIT') # Exit from idle state, ready for triggerrdngCnt = 0try:while True:if int(v34465A.query("DATA:POINTS?").rstrip("\n").rstrip("\r")) > 0:tempData.append(v34465A.query("DATA:REMOVE? 1").rstrip("\n").rstrip("\r"))#Save to file ...rdngCnt += 1time.sleep(0.05) #some margin...except KeyboardInterrupt:print("SCAN STOPPED")except AttributeError:print("Something")v34465A.write(':ABORt') #Return to idle stateloop = input("'s' to stop: ")