Skip to content

Commit 57665dc

Browse files
authored
Merge pull request #77 from VektrexElectronicSystems/development
Development v1.16.0
2 parents 160a118 + c2e56a9 commit 57665dc

File tree

55 files changed

+720
-438
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+720
-438
lines changed

README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ Use these code samples to start learning how to communicate with your SpikeSafe
44
- [SpikeSafe PSMU](https://www.vektrex.com/products/spikesafe-source-measure-unit/)
55
- [SpikeSafe Performance Series ("PRF")](https://www.vektrex.com/products/spikesafe-performance-series-precision-pulsed-current-sources/)
66

7+
Additional turn-key software solutions for advanced scenarios, such as LM-92 UV Measurement and Reliability/Burn-in Test, may be purchased. For a complete list, visit [Vektrex Software Applications](https://www.vektrex.com/software-applications/).
8+
79
## Directory
810

911
- [Getting Started](getting_started) - These sequences are primarily intended for first-time users of Vektrex products. They contain steps to perform the basic tasks that are necessary to run the sequences within the run_spikesafe_operating_modes folder.
1012
- [Run SpikeSafe Operating Modes](run_spikesafe_operating_modes) - These folders contain examples to run specific SpikeSafe modes designed to test LEDs, Lasers, and electrical equipment. Basic settings will be sent to the SpikeSafe, and then one or more channels will be enabled to demonstrate the operation of each mode.
1113
- [Making Integrated Voltage Measurements](making_integrated_voltage_measurements) - These folders contain examples to measure voltage using the SpikeSafe PSMU's integrated voltage Digitizer. The SpikeSafe outputs current to an LED, Laser, or electrical equipment, and then voltage measurements are read and displayed onscreen.
1214
- [Using the Force Sense Selector Switch](using_force_sense_selector_switch) - These folders contain examples to operate the optional integrated switch within the SpikeSafe PSMU. The SpikeSafe outputs to an LED, Laser, or electrical equipment as in the previous examples, and the switch is used to either disconnect the SpikeSafe from the test circuit or to operate an auxiliary source to power the DUT.
1315
- [Application-Specific Examples](application_specific_examples) - These folders consist of more advanced sequences to address specific test scenarios, as well as some demonstrations to fine-tune your SpikeSafe current output. These sequences explain how to make light measurements using a SpikeSafe and a spectrometer, how to make in-situ junction temperature measurements on LEDs, and how to take full advantage of all SpikeSafe features.
14-
- [spikesafe-python API Overview](spikesafe_python_lib_docs). These folders contain complete class documentation for the spikesafe-python package used to power all of the aforementioned example directories.
16+
- [spikesafe-python API Overview](spikesafe_python_lib_docs). These folders contain complete class documentation for the [spikesafe-python](https://pypi.org/project/spikesafe-python/) package used to power all of the aforementioned example directories.
1517

1618
## Downloading Files
1719

@@ -23,7 +25,7 @@ If only a specific sequence or folder is needed, right-click the desired file/fo
2325

2426
### Setup Steps
2527

26-
1. **Install Python 3.10 to 3.13**
28+
1. **Install Python 3.10 to 3.14**
2729
- Download Python from [python.org](https://www.python.org/downloads/).
2830
- During installation check **Add Python to PATH**.
2931

@@ -64,9 +66,9 @@ To run these sequences in a more feature rich IDE, use the free [Visual Studio C
6466

6567
Start with [TCP Socket Sample](getting_started/tcp_socket_sample) to learn how setup a simple socket to communicate with your SpikeSafe. Then check out the rest of the samples under [Getting Started](getting_started).
6668

67-
You will need to modify the specified IP address within a sequence to match the IP address that is physically set on your SpikeSafe's DIP switch. In each sequence, the default IP address of 10.0.0.220 is set in the line `ip_address = '10.0.0.220'`.
69+
You will need to modify the specified IP address within a sequence to match the IP address that is physically set on your SpikeSafe's DIP switch. In each sequence, the default IP address of 10.0.0.220 is set in the line `ip_address: str = '10.0.0.220'`.
6870
69-
Each file can be modified to include additional settings and commands to fit individual needs. Complete class documentation is available in [spikesafe-python API Overview](spikesafe_python_lib_docs).
71+
Each file can be modified to include additional settings and commands to fit individual needs. Complete class documentation for the [spikesafe-python](https://pypi.org/project/spikesafe-python/) package is available in [spikesafe-python API Overview](spikesafe_python_lib_docs).
7072
7173
Most examples will log messages to the SpikeSafePythonSamples.log file under your local SpikeSafePythonSamples\ directory. Please refer to this file to ensure your sequence is running correctly.
7274
@@ -81,12 +83,18 @@ We use [SemVer](http://semver.org/) for versioning. For the versions available,
8183
8284
## FAQ
8385
84-
I'm developing an application using NI-VISA, what is the recommended practice for handling termination characters?
85-
See [Termination Characters in NI-VISA](https://www.ni.com/en-us/support/documentation/supplemental/06/termination-characters-in-ni-visa.html)
86+
I'm developing an application using C/C++, how do I get started?
87+
See [Wrapping C/C++ for Python](https://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/c++-wrapping.html)
88+
89+
I'm developing an application using LabView, how do I get started?
90+
See [Integrating Python Code in LabVIEW](https://www.ni.com/en/support/documentation/supplemental/18/installing-python-for-calling-python-code.html?srsltid=AfmBOopUCkwZOUDOXRi8BDeCwXPoa-t65l7ChqWDWXJgeQWCP3ZqJAqT)
8691
8792
I'm developing an application using MATLAB, how do I get started?
8893
See [System Requirements for MATLAB Engine API for Python](https://www.mathworks.com/help/matlab/matlab_external/system-requirements-for-matlab-engine-for-python.html) to ensure your system can support Python. Then see [Call Python from MATLAB](https://www.mathworks.com/help/matlab/call-python-libraries.html) on how to access Python libraries in MATLAB.
8994

95+
I'm developing an application using NI-VISA, what is the recommended practice for handling termination characters?
96+
See [Termination Characters in NI-VISA](https://www.ni.com/en-us/support/documentation/supplemental/06/termination-characters-in-ni-visa.html)
97+
9098
Why does my script's performance vary between different operating systems and machines?
9199
See [Remarks](/spikesafe_python_lib_docs/Threading/wait/README.md#remarks) describing resolution of system timers between operating systems.
92100

application_specific_examples/fixed_pulse_count_using_software_timing/FixedPulseCountUsingSoftwareTimingExample.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
### set these before starting application
1010

1111
# SpikeSafe IP address and port number
12-
ip_address = '10.0.0.220'
13-
port_number = 8282
12+
ip_address: str = '10.0.0.220'
13+
port_number:int = 8282
1414

1515
### setting up sequence log
1616
log = logging.getLogger(__name__)
@@ -39,6 +39,9 @@
3939
tcp_socket.send_scpi_command('*RST')
4040
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
4141

42+
# parse the SpikeSafe information
43+
spikesafe_info = spikesafe_python.SpikeSafeInfoParser.parse_spikesafe_info(tcp_socket)
44+
4245
# set Channel 1's mode to DC Dynamic and check for all events
4346
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP PULSEDDYNAMIC')
4447
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
@@ -52,7 +55,7 @@
5255
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
5356

5457
# set Channel 1's Pulse On Time to 1us and check for all events
55-
pulse_on_time = 0.000001
58+
pulse_on_time: float = 0.000001
5659
tcp_socket.send_scpi_command(f'SOUR1:PULS:TON {spikesafe_python.Precision.get_precise_time_command_argument(pulse_on_time)}')
5760
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
5861

@@ -65,12 +68,13 @@
6568
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
6669

6770
# set Channel 1's current to 100mA and check for all events
68-
set_current = 0.1
71+
set_current: float = 0.1
6972
tcp_socket.send_scpi_command(f'SOUR1:CURR {spikesafe_python.Precision.get_precise_current_command_argument(set_current)}')
7073
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
7174

7275
# set Channel 1's voltage to 20V and check for all events
73-
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(20)}')
76+
compliance_voltage: float = 20
77+
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(compliance_voltage)}')
7478
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
7579

7680
# set Channel 1's Auto Range to On and check for all events
@@ -91,7 +95,7 @@
9195
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
9296

9397
# Start the channel
94-
tcp_socket.send_scpi_command('OUTP1 ON')
98+
tcp_socket.send_scpi_command('OUTP1 1')
9599

96100
# wait until Channel 1 is ready
97101
spikesafe_python.ReadAllEvents.read_until_event(tcp_socket, spikesafe_python.SpikeSafeEvents.CHANNEL_READY) # event 100 is "Channel Ready"
@@ -101,7 +105,14 @@
101105
time.sleep(0.030)
102106

103107
# disable Channel
104-
tcp_socket.send_scpi_command('OUTP1 OFF')
108+
tcp_socket.send_scpi_command('OUTP1 0')
109+
110+
# wait until the channel is fully discharged
111+
if spikesafe_info.supports_discharge_query:
112+
spikesafe_python.Discharge.wait_for_spikesafe_channel_discharge(tcp_socket, channel_number=1)
113+
else:
114+
wait_time = spikesafe_python.Discharge.get_spikesafe_channel_discharge_time(compliance_voltage)
115+
spikesafe_python.Threading.wait(wait_time)
105116

106117
# disconnect from SpikeSafe
107118
tcp_socket.close_socket()

application_specific_examples/making_tj_measurements/TjMeasurement.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import spikesafe_python
1616
from matplotlib import pyplot as plt
1717

18-
def log_and_print_to_console(message_string):
18+
def log_and_print_to_console(message_string: str) -> None:
1919
log.info(message_string.replace('\n',''))
2020
print(message_string)
2121

@@ -24,7 +24,7 @@ def receive_user_input_and_log():
2424
log.info(inputText)
2525
return inputText
2626

27-
def calculate_Vf0(start_point, end_point, digitizer_data_list):
27+
def calculate_Vf0(start_point: int, end_point: int, digitizer_data_list: list[spikesafe_python.DigitizerData]) -> float:
2828
# only want to reference the data within the straight line
2929
straight_line_digitizer_data = []
3030
for index in range(start_point, end_point):
@@ -56,8 +56,8 @@ def calculate_Vf0(start_point, end_point, digitizer_data_list):
5656
### set these before starting application
5757

5858
# SpikeSafe IP address and port number
59-
ip_address = '10.0.0.220'
60-
port_number = 8282
59+
ip_address: str = '10.0.0.220'
60+
port_number:int = 8282
6161

6262
# The graph zoom offset is used to zoom in or out to better visualize data in the final graph to make it easier to determine Vf(0). Value is in volts
6363
# A value of zero corresponds to a completely zoomed in graph. Increase the value to zoom out. Recommended values are between 0.001 and 0.100
@@ -90,10 +90,13 @@ def calculate_Vf0(start_point, end_point, digitizer_data_list):
9090
tcp_socket.send_scpi_command('*RST')
9191
spikesafe_python.ReadAllEvents.log_all_events(tcp_socket)
9292

93+
# parse the SpikeSafe information
94+
spikesafe_info = spikesafe_python.SpikeSafeInfoParser.parse_spikesafe_info(tcp_socket)
95+
9396
# set up Channel 1 for Bias Current output to determine the K-factor
9497
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP BIAS')
9598
tcp_socket.send_scpi_command(f'SOUR0:CURR:BIAS {spikesafe_python.Precision.get_precise_current_command_argument(0.033)}')
96-
compliance_voltage = 40
99+
compliance_voltage: float = 40
97100
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(compliance_voltage)}')
98101
tcp_socket.send_scpi_command('SOUR1:CURR:PROT 50')
99102
tcp_socket.send_scpi_command('OUTP1:RAMP FAST')
@@ -127,32 +130,38 @@ def calculate_Vf0(start_point, end_point, digitizer_data_list):
127130

128131
# turn off Channel 1
129132
tcp_socket.send_scpi_command('OUTP1 0')
130-
wait_time = spikesafe_python.Discharge.get_spikesafe_channel_discharge_time(compliance_voltage)
131-
spikesafe_python.Threading.wait(wait_time)
133+
134+
# wait until the channel is fully discharged
135+
if spikesafe_info.supports_discharge_query:
136+
spikesafe_python.Discharge.wait_for_spikesafe_channel_discharge(tcp_socket, channel_number=1)
137+
else:
138+
wait_time = spikesafe_python.Discharge.get_spikesafe_channel_discharge_time(compliance_voltage)
139+
spikesafe_python.Threading.wait(wait_time)
132140

133141
log_and_print_to_console('\nK-factor values obtained. Stopped bias current output. Configuring to perform Electrical Test Method measurement.')
134142

135143
# set up Channel 1 for CDBC output to make the junction temperature measurement
136144
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP BIASPULSEDDYNAMIC')
137145
tcp_socket.send_scpi_command(f'SOUR1:CURR {spikesafe_python.Precision.get_precise_current_command_argument(3.5)}')
138146
tcp_socket.send_scpi_command(f'SOUR0:CURR:BIAS {spikesafe_python.Precision.get_precise_current_command_argument(0.033)}')
139-
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(40)}')
147+
compliance_voltage: float = 40
148+
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(compliance_voltage)}')
140149
tcp_socket.send_scpi_command(f'SOUR1:PULS:TON {spikesafe_python.Precision.get_precise_time_command_argument(1)}')
141150
tcp_socket.send_scpi_command(f'SOUR1:PULS:TOFF {spikesafe_python.Precision.get_precise_time_command_argument(0.001)}')
142151
tcp_socket.send_scpi_command('SOUR1:CURR:PROT 50')
143152
tcp_socket.send_scpi_command('OUTP1:RAMP FAST')
144153

145154
# set Digitizer settings to take a series of quick measurements during the Off Time of CDBC operation
146155
tcp_socket.send_scpi_command('VOLT:RANG 100')
147-
aperture = 2
156+
aperture: int = 2
148157
tcp_socket.send_scpi_command(f'VOLT:APER {spikesafe_python.Precision.get_precise_time_microseconds_command_argument(aperture)}')
149-
hardware_trigger_delay = 0
158+
hardware_trigger_delay: int = 0
150159
tcp_socket.send_scpi_command(f'VOLT:TRIG:DEL {spikesafe_python.Precision.get_precise_time_microseconds_command_argument(hardware_trigger_delay)}')
151160
tcp_socket.send_scpi_command('VOLT:TRIG:SOUR HARDWARE')
152161
tcp_socket.send_scpi_command('VOLT:TRIG:EDGE FALLING')
153-
hardware_trigger_count = 1
162+
hardware_trigger_count: int = 1
154163
tcp_socket.send_scpi_command(f'VOLT:TRIG:COUN {hardware_trigger_count}')
155-
reading_count = 500
164+
reading_count: int = 500
156165
tcp_socket.send_scpi_command(f'VOLT:READ:COUN {reading_count}')
157166

158167
# check all SpikeSafe event since all settings have been sent
@@ -180,6 +189,13 @@ def calculate_Vf0(start_point, end_point, digitizer_data_list):
180189
# turn off Channel 1 after routine is complete
181190
tcp_socket.send_scpi_command('OUTP1 0')
182191

192+
# wait until the channel is fully discharged
193+
if spikesafe_info.supports_discharge_query:
194+
spikesafe_python.Discharge.wait_for_spikesafe_channel_discharge(tcp_socket, channel_number=1)
195+
else:
196+
wait_time = spikesafe_python.Discharge.get_spikesafe_channel_discharge_time(compliance_voltage)
197+
spikesafe_python.Threading.wait(wait_time)
198+
183199
# prepare digitizer voltage data to plot
184200
samples = []
185201
voltage_readings = []

application_specific_examples/making_transient_dual_interface_measurement/digitizer_log_sampling_demo.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
from matplotlib import pyplot as plt
1111
import numpy as np
1212

13-
def log_and_print_to_console(message_string):
13+
def log_and_print_to_console(message_string: str) -> None:
1414
print(message_string)
1515

16-
def receive_user_input_and_log():
16+
def receive_user_input_and_log() -> str:
1717
inputText = input()
1818
return inputText
1919

2020
### set these before starting application
2121

2222
# SpikeSafe port number
23-
port_number = 8282
23+
port_number: int = 8282
2424

2525
ok_string = "0, OK"
2626
channel_ready_string = "100, Channel Ready; Channel(s) 1"
@@ -55,7 +55,10 @@ def receive_user_input_and_log():
5555
tcp_socket.open_socket(ip_address, port_number)
5656

5757
# reset to default state and check for all events, this will automatically abort digitizer in order get it into a known state. This is good practice when connecting to a SpikeSafe PSMU
58-
tcp_socket.send_scpi_command('*RST')
58+
tcp_socket.send_scpi_command('*RST')
59+
60+
# parse the SpikeSafe information
61+
spikesafe_info = spikesafe_python.SpikeSafeInfoParser.parse_spikesafe_info(tcp_socket)
5962

6063
# Set digitizer range to 10V
6164
tcp_socket.send_scpi_command('VOLT:RANG 10')
@@ -95,7 +98,8 @@ def receive_user_input_and_log():
9598
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP DCDYNAMIC')
9699

97100
# set MCV to 25
98-
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(40)}')
101+
compliance_voltage: float = 40
102+
tcp_socket.send_scpi_command(f'SOUR1:VOLT {spikesafe_python.Precision.get_precise_compliance_voltage_command_argument(compliance_voltage)}')
99103

100104
# set Auto Range
101105
tcp_socket.send_scpi_command('SOUR1:CURR:RANG:AUTO 1')
@@ -117,7 +121,7 @@ def receive_user_input_and_log():
117121
tcp_socket.send_scpi_command('VOLT:INIT')
118122

119123
# Start the channel
120-
tcp_socket.send_scpi_command('OUTP1 ON')
124+
tcp_socket.send_scpi_command('OUTP1 1')
121125
# wait for channel ready
122126
while True:
123127
tcp_socket.send_scpi_command('SYST:ERR?')
@@ -145,6 +149,16 @@ def receive_user_input_and_log():
145149
syst_err_string = tcp_socket.read_data()
146150
if syst_err_string == ok_string:
147151
break
152+
153+
# disable Channel
154+
tcp_socket.send_scpi_command('OUTP1 0')
155+
156+
# wait until the channel is fully discharged
157+
if spikesafe_info.supports_discharge_query:
158+
spikesafe_python.Discharge.wait_for_spikesafe_channel_discharge(tcp_socket, channel_number=1)
159+
else:
160+
wait_time = spikesafe_python.Discharge.get_spikesafe_channel_discharge_time(compliance_voltage)
161+
spikesafe_python.Threading.wait(wait_time)
148162

149163
# disconnect from SpikeSafe
150164
tcp_socket.close_socket()

application_specific_examples/making_transient_dual_interface_measurement/produce_conductive_thermal_resistance.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
from matplotlib import pyplot as plt
1010
import numpy as np
1111

12-
def log_and_print_to_console(message_string):
12+
def log_and_print_to_console(message_string: str) -> None:
1313
print(message_string)
1414

15-
def receive_user_input_and_log():
15+
def receive_user_input_and_log() -> str:
1616
inputText = input()
1717
return inputText
1818

@@ -72,6 +72,7 @@ def receive_user_input_and_log():
7272
else:
7373
num_of_data = num_of_data_noGrease
7474

75+
sampling_mode_string = ""
7576
if sampling_mode_input == fast_sampling_mode:
7677
sampling_mode_string = fast_sampling_string
7778
elif sampling_mode_input == medium_sampling_mode:

0 commit comments

Comments
 (0)