Posted Thu, 27 Apr 2023 11:29:01 GMT by W, J
<p>What is the fastest rate I should be able to sweep/update the voltage output on the K2450, using point-by-point level updates (not a source measure loop controlled by the machine)?
I am trying to understand the delay that occurs when the source level is updated, and how this relates to the current measurement range and any automatically applied source delay. I know why delays are added for current measure (I have seen ringing on high capacitance lines on other instruments when voltage changes) but in this case I just want the fastest source update time.
We discovered that sweeps executed point by point could cause a 'pile-up' of voltage updates. You can drop in an *OPC? command to make sure you don't rush the measurement (on another instrument) but the process is slow, hundreds of milliseconds.
I tried to set the source delays to zero (:SOUR:VOLT:DEL 0) and confirmed that this deactivated the auto setting :SOUR:VOLT:DEL:AUTO? but this did not help. Changing the current measurement range of the instrument to a less sensitive range changed the delay time by a factor 2, but this did not tally with the numbers in the manual for the autodelay (we see ~ 170 ms for measure range 1uA).
This looks like some artificially added software delay that I have not got under control. The response time on other queries is ~normal (10 ms for a range setting query, for instance). Any ideas?
PS: I could move the speed/performance slider but I assume this has the effect of changing multiple real parameters like the integration time on the ammeter and the delays times and is largely focussed on the noise/resolution of me measurement.  I'd rather set the actual parameters.
Posted Fri, 28 Apr 2023 15:02:59 GMT by C, Andrea
<span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">If I understand, you want to sweep or source a series of voltage values but do it from a Loop on the PC side where you send a command for each source level.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">And if also obtaining measurements, from your loop you are also sending commands to cause a current measurement to occur.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">You will have overhead and possibly some timing variation by the loop-based approach.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">Using TSP command set and Python, I have this code that does the loop and obtains a measurement.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">The measurements are sent to PC at the end (one bus transfer).</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">Duration at each source level is about 900usec. Scope shot image uploaded.</span></span></span><br> <br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">If I instead send each measurement one by one, the duration increases to about 3.6msec; I have set the integration rate to fastest and turned off autozero.</span></span></span><br> <br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">If you know source values ahead of time and can load them into a Source Config List, you can get faster operations.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">From datasheet for 2450, you can approach 1700 Hz Source-Measure rate at 0.01 NPLC.</span></span></span><br> <span style="font-size:11pt;"><span style="line-height:107%;"><span style="font-family:Calibri,sans-serif;">Look at the System Measurement Speeds table in datasheet (pg 10).</span></span></span> <pre class="linenums prettyprint">my_instr.write(&quot;reset()&quot;) my_instr.write(&quot;status.clear()&quot;) my_instr.write(&quot;errorqueue.clear()&quot;) MEAS_RANGE = 100e-3 cmd_list = [&quot;smu.source.func = smu.FUNC_DC_VOLTAGE&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.autorange = smu.OFF&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.range = 20&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.ilimit.level = &quot; + str(MEAS_RANGE), &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.delay = 0&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.autodelay = smu.OFF&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.source.readback = smu.OFF&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.measure.func = smu.FUNC_DC_CURRENT&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.measure.autorange = smu.OFF&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.measure.range = &quot; + str(MEAS_RANGE), &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.measure.nplc = 0.01&quot;, &#160; &#160; &#160; &#160; &#160; &#160; &quot;smu.measure.autozero.enable = smu.OFF&quot; &#160; &#160; &#160; &#160; &#160; &#160; ] &#160; &#160;&#160; for cmd in cmd_list: &#160; &#160; my_instr.write(cmd) &#160; &#160;&#160; &#160; &#160;&#160; #lets loop thru some source levels and measure speed with scope debug = 1 voltage_list = {} for i in range(0, 11): &#160; &#160; voltage_list[i] = i/10 print(voltage_list) &#160; &#160; &#160; &#160;&#160; my_instr.write(&quot;smu.source.output = smu.ON&quot;) for j in range(0,1): &#160; &#160; for i in range( 0 ,len(voltage_list)): &#160; &#160; &#160; &#160; my_instr.write(&quot;smu.source.level = &quot; + str(voltage_list[i])) &#160; &#160; &#160; &#160; my_instr.write(&quot;smu.measure.read()&quot;) &#160; #obtain a reading into the buffer &#160; &#160; &#160; &#160; #print(my_instr.query(&quot;print(smu.measure.read())&quot;)) &#160;# this will slow you down! &#160; &#160; &#160; &#160;&#160; &#160; &#160; &#160; &#160; &#160; &#160; #all done, turn output off my_instr.write(&quot;smu.source.level = 0&quot;) my_instr.write(&quot;smu.source.output = smu.OFF&quot;) #bring the data back from the buffer print(my_instr.query(&quot;printbuffer(1, defbuffer1.n, defbuffer1.readings)&quot;)) </pre>
Posted Mon, 15 May 2023 15:59:10 GMT by Blayne, Hamilton
I have encountered the same issue on my unit. For me at least, the issue seems to be tied to the measurement range (even if a voltage is being set without actually measuring the current back).
Andrea, I modified your script to sweep the voltage from 0 - 5V on each range, measuring the average time per setpoint do so. The script used either the time taken to successfully return the measured current, or, when not reading the current, by issuing the query waitcomplete() print([[1]])  (significantly less elegant than the SCPI equivalent *OPC?) following each voltage asserted to ensure the action had completed.
my_instr.timeout= 50000;
measurements= 50;
measure_I = False;
check_complete = True;
I_ranges = [1, 100E-3, 10E-3, 1E-3, 100E-6, 10E-6, 1E-6, 100E-9, 10E-9]
#my_instr.write(&quot;reset()&quot;)
my_instr.write(&quot;status.clear()&quot;)
my_instr.write(&quot;errorqueue.clear()&quot;)
for MEAS_RANGE in I_ranges: cmd_list = [&quot;smu.source.func = smu.FUNC_DC_VOLTAGE&quot;, &quot;smu.source.autorange = smu.OFF&quot;, &quot;smu.source.range = 20&quot;, &quot;smu.source.ilimit.level = &quot; + str(MEAS_RANGE), &quot;smu.source.delay = 0&quot;, &quot;smu.source.autodelay = smu.OFF&quot;, &quot;smu.source.readback = smu.OFF&quot;, &quot;smu.measure.func = smu.FUNC_DC_CURRENT&quot;, &quot;smu.measure.autorange = smu.OFF&quot;, &quot;smu.measure.range = &quot; + str(MEAS_RANGE), &quot;smu.measure.nplc = 0.01&quot;, &quot;smu.measure.autozero.enable = smu.OFF&quot; ] for cmd in cmd_list: my_instr.write(cmd) #lets loop thru some source levels and measure speed with scope debug = 1 voltage_list = {} for i in range(0, measurements): voltage_list[i] = i/10 #print(f'voltages:{voltage_list}') my_instr.write(&quot;smu.source.output = smu.ON&quot;) startTime = time.time() for j in range(0,1): for i in range( 0 ,len(voltage_list)): my_instr.write(&quot;smu.source.level = &quot; + str(voltage_list[i])) if (measure_I): my_instr.write(&quot;smu.measure.read()&quot;) #obtain a reading into the buffer #print(my_instr.query(&quot;print(smu.measure.read())&quot;)) # this will slow you down! if (check_complete): my_instr.query(&quot;waitcomplete() print([[1]])&quot;) #confirm voltage is set before setting next value #all done, turn output off my_instr.write(&quot;smu.source.level = 0&quot;) my_instr.write(&quot;smu.source.output = smu.OFF&quot;) if (measure_I): #bring the data back from the buffer print(my_instr.query(&quot;printbuffer(1, defbuffer1.n, defbuffer1.readings)&quot;)) endTime = time.time() print(f'range: {MEAS_RANGE}') print(f'avg time: {(endTime-startTime)/measurements} s')</pre> <br> When setting the voltage for each point and measuring the current: <pre class="linenums prettyprint">measure_I = True; check_complete = False;</pre> <br> and just setting each voltage but making no measurement: <pre class="linenums prettyprint">measure_I = False; check_complete = True;</pre> <br> I get a slowdown described by Jim, with a set-measure cycle of &gt; 300 ms on the 10 nA range compared to ~ 5 ms on the higher ranges, and when just setting the voltages similar times of&#160; ~300 ms and ~2 ms respectively<br> <br> Andrea, do you see the same behaviour on your unit, or have any idea how to optimise this when measuring on small current ranges?<br> <br> &#160;
Posted Wed, 24 May 2023 14:36:19 GMT by C, Andrea
What is your firmware level?&#160; I've been using 1.7.12b on my 2450 SourceMeter.<br> <br> If source delay is zero and auto delay is off, my understanding is that there should not be any current range dependent timing.<br> Of course, if using sensitive ranges where settling time is likely to be required given the RC time constants, operating the instrument this way can easily result in unsettled measurements.<br> <br> I used the same code but add a command to set the smu.measure.count equal to three, and use the relativetimestamps differences to get an idea about how fast the instrument is going.<br> So readings 1 through 3 are at source level 1;&#160; readings 4 through 6 are source level 2, etc.<br> <br> Regardless of range, the delta in timestamps for readings obtained at same source level is about 320usec.<br> But when comparing the timestamps from before and after a source level change, we have to expect some larger amount of time for the sourcing action to take place.<br> However, I also see that the amount of time in those time stamps does vary with the current measure range setting and for the 10nA and 100nA ranges it is about 300msec.&#160; But for 10uA and higher ranges, the delta timestamp is about 900usec.<br> <br> Timestamp delta for after src change to before src change:<br> print(my_instr.query(&quot;print(defbuffer1.relativetimestamps[4] - defbuffer1.relativetimestamps[3] )&quot;))<br> <br> <img alt="" src="https://fortive.box.com/shared/static/l5ikdfyii7iel6yjzbjd03g5d06wwj5d.png">
Posted Wed, 31 May 2023 15:40:23 GMT by C, Andrea
Hello,
I'm not sure if a bug or feature.
But I have opened a formal issue in our quality tracking system.
My expectation was that we should be able to turn off the delays even if it is likely to wreck your data quality.
As for the 300msec that is imposed for use of the most sensitive ranges, it is a reasonable number.
If operating in the nA levels, is reasonable to assume there are GΩ of resistance.
As for estimating the capacitance, is easy to envision 100pF from a few feet of cable.
At 1GΩ and 100pF, the RC time constant is 100msec.
For settled readings, is not uncommon to wait 5 time constants.  It really depends on the setup and particular goals.
Keep in mind, when the voltage steps from one value to the next, a displacement current is generated in proportion to the C and the step size and edge speed ( I = C * dV/dt).
The delay is targeting enough time to have a reasonably steady state measurement.
I will mention our 2600B series have more flexible trigger models. By this I mean it can measure Asynchronously from the sourcing action, so you can capture the transient displacement currents as the voltage is stepped.   
Andrea
Posted Fri, 02 Jun 2023 14:49:09 GMT by W, J
<p>Thanks for raising a ticket. &#128077;</p> <p>The example you cite with the <a href="https://forum.tek.com/viewtopic.php?f=14&amp;t=142669">other instrument is an interesting one</a>. We have done similar&#160;measurments with other instruments by starting an acquisition loop just after asserting updating the voltage. This is a good way of characterising transients, and seeing how they change with capacitive loading (you can choose how much effort to go to reduce capactance)<br> <br> In that post, a&#160;ramp in fairly large steps (+1 V every 200 ms) on a 10 GOhm resistor gives a short transient and a longer decay,<br> While there is sometimes variation on ~100s ms time scales, the 0 to 1 V seems to settle quickly, within ~ 5 point say (which is ~20 ms if I am correct that the rate = 250 S/s). This is the kind of speed that we are targeting.</p> <p>If it turns out we can remove the delay with a firmware update that would be great.</p>

You must be signed in to post in this forum.