| Products > Test Equipment |
| DIY scan card for Keysight 34970A |
| << < (8/13) > >> |
| H.O:
Regarding --- Code: ---#define CMD_CHAN_SCAN1 (0xD8 >> 3) // TODO don't understand this yet, scan channel list maybe? --- End code --- When using the front panel you can close more than one channel at the same time (depending on type of card). However, my guess is that the above command means "Open all closed channels, then close channel nn (followed by channel number)). --- Code: ---#define CMD_CHAN_SCAN2 (0x08 >> 3) // TODO don't understand this yet --- End code --- Don't think I've seen this one yet...what did you do to make the DAQ send that one? Am I correct that the cold junction reference temperatur is returned in units of 0.00390625°C per LSB? The DS75s datasheet says 12bits resoultion but I'm guessing the card CPU is doing some oversampling and is providing a psuedo 16bit result |
| voltsandjolts:
--- Quote from: H.O on June 03, 2022, 10:56:33 pm ---Regarding --- Code: ---#define CMD_CHAN_SCAN1 (0xD8 >> 3) // TODO don't understand this yet, scan channel list maybe? --- End code --- When using the front panel you can close more than one channel at the same time (depending on type of card). However, my guess is that the above command means "Open all closed channels, then close channel nn (followed by channel number)). --- End quote --- Agree. When scanning a list of channels like: print(inst.query('MEAS:VOLT:DC? 10,(@101:112)')) The 0xD8 command is used like 'close ch1' then 'close ch2'...etc without any 'open' command. So yes, it opens the closed channels, then closes requested channel(s). There is also 0x1E1 0FF which seems to mean 'open all relays', including measurement bus relays and channel relays. --- Quote --- --- Code: ---#define CMD_CHAN_SCAN2 (0x08 >> 3) // TODO don't understand this yet --- End code --- Don't think I've seen this one yet...what did you do to make the DAQ send that one? --- End quote --- My bad ignore that..its dupilcate...thats the 0x08 CMD_QUERY_BUSY command. --- Quote ---Am I correct that the cold junction reference temperatur is returned in units of 0.00390625°C per LSB? The DS75s datasheet says 12bits resoultion but I'm guessing the card CPU is doing some oversampling and is providing a psuedo 16bit result --- End quote --- The DS75s are used in 12bit mode (config byte is written at startup). They are sampled continuously (600ms interval alternatively). I haven't looked at what the scaling is, yes, maybe some averaging done there. Edit: I had expected the scaling to match the DS75 datasheet, but it's not quite the same. Examples of hex values I returned from my card and the resulting temperature (as read by Python script): --- Code: ---0x0000 == -9.012 (expected 0.0 degC) 0x0873 == 0.003 0x1910 == 24.352 (expected 25.0625 degC) 0x7D00 == 124.290 (expected 125.0 degC) --- End code --- It's like the dmm is applying some additional calibration but I haven't seen values read from the card that look like calibration data. |
| voltsandjolts:
My interpretation of commands so far: --- Code: ---// Commands are shifted down 3 bits to remove the address bits and thus // allow the compiler to make a jump table with 32 entries for command decoding. #define CMD_IDENTIFY (0x18 >> 3) // response is 0x101-0x108 for 34901A-34908A cards respectively #define CMD_SRQ_CLEAR (0x20 >> 3) // card holds SRQ low after power on, this cmd de-asserts it then responds with 0x121 #define CMD_POWEROFF (0x40 >> 3) // see this 200ms before power off, address bits all zero i.e. 0x140 (broadcast addr?), no response required #define CMD_UNKNOWN (0xB8 >> 3) // 0x1B0 000 000 000 010 seen at power on, excercising or opening relays #define CMD_UNKNOWN2 (0xC0 >> 3) // seen at power on, no response so doesn't need implemented or mimicked #define CMD_QUERY_BUSY (0x08 >> 3) // response is either 0x100,0x101,0x120 (all busy in some way) or 0x121 (idle) #define CMD_QUERY_DATA (0x48 >> 3) // read data from the transmit buffer, byte at a time, last byte available has 9th bit set #define CMD_REFJUNC (0xC8 >> 3) // get reference junction temperatures (read from DS75 i2c temperature sensors) #define CMD_EXECUTE (0x68 >> 3) // begin read of firmware version, relay cycle counts and other unknown stuff #define CMD_CHAN_CLOSE (0xD8 >> 3) // close measurement bus and channel relays #define CMD_CHAN_OPEN (0xE0 >> 3) // 1E1 0FF seems to be "open all relays" for channels and measurement bus --- End code --- |
| voltsandjolts:
If you use python for instrument control, here is the scrappy script I am using for experiments: --- Code: ---import pyvisa as visa import time,sys #py -m pip install -U pyvisa #py -m pip install -U pyvisa-py (for the pure python backend) #py -m pip install -U pyserial #https://pyvisa.readthedocs.io/en/latest/index.html #How do I know if PyVISA-py is properly installed? Get info about PyVISA, the installed backends and their options: # python -m visa info #On Windows, you may have to uninstall the USBTMC specific driver installed by Windows and re-install a generic driver. #https://pyvisa.readthedocs.io/en/latest/introduction/configuring.html #rm = visa.ResourceManager('@py') # Use pure python backend #rm = visa.ResourceManager('@ivi') # Use IVI-VISA backend rm = visa.ResourceManager() # default backend #print('Available devices: ', rm.list_resources()) # Will show async serial devices (comports) as e.g. ASRL16::INSTR for COM16 print('\nOpening device:') inst = rm.open_resource('USB0::0x0957::0x2007::MY57007585::INSTR') #For the 34972A on USB #inst = rm.open_resource("ASRL3::INSTR", baud_rate = 115200) #For the 34970A on RS232 (need to edit port number appropriately 'ASRL?' and check instrument baud setting) #reading and writing values: #https://pyvisa.readthedocs.io/en/latest/introduction/rvalues.html #inst.write('*rst; *cls') #reset to power on state, clear status # After *rst we now have these settings: # 1PLC, 5½ digits resolution # scaling is OFF and scale values are cleared # sets the scan interval to immediate (0 seconds) and the scan count to 1 sweep. DEFAULT_TIMEOUT = 5000 # default timeout is 5 seconds inst.timeout = DEFAULT_TIMEOUT #print(inst.query('*IDN?')) #print('Slot 1 card type:') #print(inst.query(':SYST:CTYPE? 100')) #print('Slot 2 card type:') #print(inst.query(':SYST:CTYPE? 200')) #print('Slot 3 card type:') #print(inst.query(':SYST:CTYPE? 300')) #print('Internal relay cycle count:') #print(inst.query('DIAG:DMM:CYCLES?')) #print(inst.query('CAL:SEC:STAT?')) #inst.write('CAL:SEC:STAT OFF,HP034970') #unsecure the instrument #print(inst.query('CAL:SEC:STAT?')) #inst.write('DIAG:REL:CYCL:CLE (@118)') #clears the relay cycle count on channel 18 in card slot 100 #inst.write('DIAG:REL:CYCL:CLE (@118)') #clears the relay cycle count on channel 18 in slot 100 #inst.write('DIAGnostic:DMM:CYCLes:CLEar 1') #clear internal DMM relay cycle count K102 #inst.write('DIAGnostic:DMM:CYCLes:CLEar 2') #clear internal DMM relay cycle count K103 #inst.write('DIAGnostic:DMM:CYCLes:CLEar 3') #clear internal DMM relay cycle count K104 #inst.write('CAL:SEC:STAT ON,HP034970') #secure the instrument #inst.write("DISP:TEXT 'HELLO'") #time.sleep(1) #inst.write('DISPLAY:TEXT:CLEAR') #time.sleep(1) #inst.write('DISPLAY OFF') # Avoid screen burn on the VFD display by switching it off #time.sleep(1) ####################### 20 Channel Card ##################### # Assume this card is in slot 1, channels addresses are in 0x100 range # MEASure is equivalent to CONFigure followed by a READ? # These are the basic commands required # MEASure:VOLTage:DC? [{<range>|AUTO|MIN|MAX|DEF}[,{<resolution>|MIN|MAX|DEF}],] (@<scan_list>) # MEASure:RESistance? [{<range>|AUTO|MIN|MAX|DEF}[,{<resolution>|MIN|MAX|DEF}],] (@<scan_list>) # MEASure:FRESistance? [{<range>|AUTO|MIN|MAX|DEF}[,{<resolution>|MIN|MAX|DEF}],] (@<scan_list>) # MEASure:FREQuency? [{<range>|AUTO|MIN|MAX|DEF}[,{<resolution>|MIN|MAX|DEF}],] (@<scan_list>) #print('Slot1 relay cycle count:') #print(inst.query('DIAG:RELAY:CYCLES? (@101:120)')) # The relay cycle count from the chinese clone cards is always zero!! #print(inst.query('MEAS:VOLT:DC? 10,(@112:115)')) #10VDC range, default resolution #print(inst.query('MEAS:FRES? (@104)')) # 4W channels are paired. Specify channel 1 to 10, which is paired with 11 to 20. print(inst.query('MEAS:CURR:DC? 1,(@121:122)')) #1A range, default resolution #time.sleep(1) #1sec delay exit() # temperature stuff #inst.query('SENS:TEMP:TRAN:TC:TYPE K,(@101)') #inst.query('SENS:TEMP:TRAN:TC:RJUN:TYPE FIXED,(@101)') #print(inst.query('SENS:TEMP:RJUN? (@102)')) #read the internal ref junction temp for bank1 ch01-10 (from DS75 U152) #print(inst.query('SENS:TEMP:RJUN? (@118)')) #read the internal ref junction temp for bank1 ch11-20 (from DS75 U151) print(inst.query('MEAS:CURR:DC? 1,MAX,(@121)')) #1A DC range, 6½ digits of resolution print('\n---Measuring Examples---') print('Measure one channel:') print(inst.query('MEAS:VOLT:DC? 100,MAX,(@101)')) #100VDC range, 6½ digits of resolution print('Measure one channel:') print(inst.query('MEAS:VOLT:DC? 10,(@112)')) #10VDC range, default resolution exit() print('Measure several sequential channels:') voltages = inst.query('MEAS:VOLT:DC? (@101:104)') #Auto ranging, default resolution print(voltages) print('Measure random channels:') inst.timeout = 20000 # 15 sec timeout for this longer operation print(inst.query('MEAS:VOLT:DC? (@101:110,115,120)')) inst.timeout = DEFAULT_TIMEOUT print('Measure 2W resistance:') print(inst.query('MEAS:RES? (@118)')) print(inst.query('MEAS:RES? (@101)')) print(inst.query('MEAS:RES? (@102)')) print('Measure 4W resistance:') print(inst.query('MEAS:FRES? (@109)')) # 4W channels are paired. Specify channel 1 to 10, which is paired with 11 to 20. --- End code --- |
| H.O:
--- Quote --- --- Code: ---#define CMD_QUERY_BUSY (0x08 >> 3) // response is either 0x100,0x101,0x120 (all busy in some way) or 0x121 (idle) --- End code --- --- End quote --- Hmmm...my impression is that 0x101, like 0x121, means confirmed/done/ready/idle - not busy. The scaling for the reference juctions is weird. It's not the 12bit format shown in the datasheet because the card returned values where the low 4 bits are not all zeros. My initial value of 125/32000 does not quite match, neither does 125/32768. My (genuine) card returns 0x17E4 for a reported temperature of 23.0156°C but the above scale factors eqauls 23.89 or 23.33. Like you say, there does not seem to be any calibration data transfered from the card. |
| Navigation |
| Message Index |
| Next page |
| Previous page |