Skip to content

Commit e22facc

Browse files
committed
Added getting_started\discharge_channel scripts
1 parent fa049af commit e22facc

File tree

4 files changed

+331
-1
lines changed

4 files changed

+331
-1
lines changed

getting_started/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ For first-time users, Vektrex recommends running the sequences in the order show
1111
1. [Read *IDN?](read_idn) - Uses the SCPI Standard "*IDN?" query and following information queries to obtain the model of your SpikeSafe
1212
1. [Read All Events](read_all_events) - Reads all events from the SpikeSafe event queue
1313
1. [Read Memory Table Data](read_memory_table_data) - Reads the SpikeSafe status and obtains current operational information from the SpikeSafe
14-
1. [SCPI Logging](scpi_logging) - Shows how to log SpikeSafe SCPI messages sent over the TCP socket to a file.
14+
1. [Discharge Channel](discharge_channel) - Shows how to properly shut down the SpikeSafe channel and wait for the load voltage to discharge before taking further action
15+
1. [SCPI Logging](scpi_logging) - Shows how to log SpikeSafe SCPI messages sent over the TCP socket to a file
1516

1617
## Usage
1718
To run these sequences, an IDE such as [Visual Studio Code](https://code.visualstudio.com/) is required. The [spikesafe-python](https://pypi.org/project/spikesafe-python/) repository will need to be installed as a package using the command `python -m pip install spikesafe-python`. Vektrex recommends always having the latest version of spikesafe-python when running these sequences; the current version is 1.1.0. It may help to run these sequences in a [virtual environment](https://docs.python.org/3/tutorial/venv.html).
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Examples for Discharging a SpikeSafe PRF or PSMU Channel
2+
3+
## **Purpose**
4+
Demonstrate how to use a SpikeSafe PRF or PSMU to deliver high precision DC current to an LED or Laser load to increase its forward voltage for testing, once testing is complete turn off the current supply, and then wait to properly discharge the load voltage before taking any further action such as delivering current again to the load or removing it.
5+
6+
Vektrex recommends using the SpikeSafe Get Discharge Complete query to properly discharge the load voltage. This is available starting with SpikeSafe Firmware Version 3.6.1 consisting of Rev 3.0.5.5 and DSP version 2.0.45. Refer to [Discharge SpikeSafe Channel Using Get Discharge Complete query](#discharge-spikesafe-channel-using-get-discharge-complete-query) below.
7+
8+
For older SpikeSafe Firmware Versions, use a time delay to properly discharge the load voltage. Refer to [Discharge SpikeSafe Channel Using Time Delay](#discharge-spikesafe-channel-using-time-delay) below.
9+
10+
## **Discharge SpikeSafe Channel Using Get Discharge Complete query**
11+
12+
### Overview
13+
Operates the first test using SpikeSafe as a DC current source with single output current, stops current output, and then uses the SpikeSafe Get Discharge Complete query to properly discharge the load with the intent of running a second test. Afterwards, the same process is repeated for the second and final test, then the SpikeSafe Discharge Complete query is used again with the intent of ensuring the load is safe to be disconnected.
14+
15+
### Expected Output
16+
Once the SpikeSafe Get Discharge Complete query returns `TRUE` after the first test has completed, the second test begins supplying output current again to the load. Once the second test has completed, the SpikeSafe Get Discharge Complete query is monitored until all load voltage is discharged to notify the operator that it is safe be disconnected.
17+
18+
#### Log Output Between test #1 and test #2
19+
Sending SCPI command: `OUTP1 0`
20+
`0, OK`
21+
Waiting for Channel 1 to fully discharge after test #1...
22+
Sending SCPI command: `OUTP1:DISC:COMP?`
23+
Read Data reply: `FALSE`
24+
Sending SCPI command: `OUTP1:DISC:COMP?`
25+
Read Data reply: `FALSE`
26+
Sending SCPI command: `OUTP1:DISC:COMP?`
27+
Read Data reply: `FALSE`
28+
Sending SCPI command: `OUTP1:DISC:COMP?`
29+
Read Data reply: `FALSE`
30+
Sending SCPI command: `OUTP1:DISC:COMP?`
31+
Read Data reply: `FALSE`
32+
Sending SCPI command: `OUTP1:DISC:COMP?`
33+
Read Data reply: `TRUE`
34+
Sending SCPI command: `OUTP1 1`
35+
36+
#### Log Output Between test #2 and Completing the Script
37+
Sending SCPI command: `OUTP1 0`
38+
`0, OK`
39+
Waiting for Channel 1 to fully discharge after test #2...
40+
Sending SCPI command: `OUTP1:DISC:COMP?`
41+
Read Data reply: `FALSE`
42+
Sending SCPI command: `OUTP1:DISC:COMP?`
43+
Read Data reply: `FALSE`
44+
Sending SCPI command: `OUTP1:DISC:COMP?`
45+
Read Data reply: `FALSE`
46+
Sending SCPI command: `OUTP1:DISC:COMP?`
47+
Read Data reply: `FALSE`
48+
Sending SCPI command: `OUTP1:DISC:COMP?`
49+
Read Data reply: `FALSE`
50+
Sending SCPI command: `OUTP1:DISC:COMP?`
51+
Read Data reply: `FALSE`
52+
Sending SCPI command: `OUTP1:DISC:COMP?`
53+
Read Data reply: `TRUE`
54+
discharge_channel_using_delay.py completed.
55+
56+
## **Discharge SpikeSafe Channel Using Time Delay**
57+
58+
### Overview
59+
Operates SpikeSafe as a DC current source with single output current, stops current output, and then uses the [spikesafe-python](https://pypi.org/project/spikesafe-python/) [`get_spikesafe_channel_discharge_time()`](../../spikesafe_python_lib_docs/Discharge/get_spikesafe_channel_discharge_time/) and [`wait()`](../../spikesafe_python_lib_docs/Threading/wait/) functions to properly discharge the load with the intent of running a second test. Afterwards, the same process is repeated for the second and final test, then the SpikeSafe Discharge Complete query is used again with the intent of ensuring that it is safe to be disconnected.
60+
61+
### Expected Output
62+
Once the delay to discharge after the first test has completed, the second test begins supplying output current again to the load. Once the second test has completed, another delay to discharge occurs until all load voltage is discharged to notify the operator that it is safe to be disconnected.
63+
64+
Each delay will show the following message in the log:
65+
Waiting 0.027 seconds for Channel 1 to fully discharge...
66+
67+
### Remarks
68+
System timers dictate the resolution of time delays. See [Remarks](../../spikesafe_python_lib_docs/Threading/wait/README.md#remarks) describing resolution of system timers between operating systems.
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import sys
2+
import time
3+
import logging
4+
from spikesafe_python.Discharge import get_spikesafe_channel_discharge_time
5+
from spikesafe_python.MemoryTableReadData import log_memory_table_read
6+
from spikesafe_python.Precision import get_precise_compliance_voltage_command_argument
7+
from spikesafe_python.Precision import get_precise_current_command_argument
8+
from spikesafe_python.ReadAllEvents import log_all_events
9+
from spikesafe_python.ReadAllEvents import read_until_event
10+
from spikesafe_python.SpikeSafeEvents import SpikeSafeEvents
11+
from spikesafe_python.SpikeSafeError import SpikeSafeError
12+
from spikesafe_python.TcpSocket import TcpSocket
13+
from spikesafe_python.Threading import wait
14+
15+
### set these before starting application
16+
17+
# SpikeSafe IP address and port number
18+
ip_address = '10.0.0.220'
19+
port_number = 8282
20+
21+
### setting up sequence log
22+
log = logging.getLogger(__name__)
23+
logging.basicConfig(
24+
level=logging.INFO,
25+
format='%(asctime)s.%(msecs)03d, %(levelname)s, %(message)s',
26+
datefmt='%m/%d/%Y %I:%M:%S',
27+
handlers=[
28+
logging.FileHandler("SpikeSafePythonSamples.log"),
29+
logging.StreamHandler(sys.stdout)
30+
]
31+
)
32+
33+
### start of main program
34+
try:
35+
log.info("discharge_channel_using_delay.py started.")
36+
37+
log.info("Python version: {}".format(sys.version))
38+
39+
# instantiate new TcpSocket to connect to SpikeSafe
40+
tcp_socket = TcpSocket()
41+
tcp_socket.open_socket(ip_address, port_number)
42+
43+
# reset to default state and check for all events,
44+
# it is best practice to check for errors after sending each command
45+
tcp_socket.send_scpi_command('*RST')
46+
log_all_events(tcp_socket)
47+
48+
# set Channel 1's pulse mode to DC and check for all events
49+
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP DC')
50+
log_all_events(tcp_socket)
51+
52+
# set Channel 1's safety threshold for over current protection to 50% and check for all events
53+
tcp_socket.send_scpi_command('SOUR1:CURR:PROT 50')
54+
log_all_events(tcp_socket)
55+
56+
# set Channel 1's current to 100 mA and check for all events
57+
tcp_socket.send_scpi_command(f'SOUR1:CURR {get_precise_current_command_argument(0.1)}')
58+
log_all_events(tcp_socket)
59+
60+
# set Channel 1's voltage to 20 V and check for all events
61+
compliance_voltage = 20
62+
tcp_socket.send_scpi_command(f'SOUR1:VOLT {get_precise_compliance_voltage_command_argument(compliance_voltage)}')
63+
log_all_events(tcp_socket)
64+
65+
# start test #1 by turning on Channel 1 and check for all events
66+
tcp_socket.send_scpi_command('OUTP1 1')
67+
log_all_events(tcp_socket)
68+
69+
# wait until the channel is fully ramped to 10mA
70+
read_until_event(tcp_socket, SpikeSafeEvents.CHANNEL_READY) # event 100 is "Channel Ready"
71+
72+
# check for all events and measure readings on Channel 1 once per second for 5 seconds,
73+
# it is best practice to do this to ensure Channel 1 is on and does not have any errors
74+
time_end = time.time() + 5
75+
while time.time() < time_end:
76+
log_all_events(tcp_socket)
77+
log_memory_table_read(tcp_socket)
78+
wait(1)
79+
80+
# turn off Channel 1 and check for all events
81+
tcp_socket.send_scpi_command('OUTP1 0')
82+
log_all_events(tcp_socket)
83+
84+
# wait until the channel is fully discharged before starting test #2
85+
wait_time = get_spikesafe_channel_discharge_time(compliance_voltage)
86+
log.info('Waiting %s seconds for Channel 1 to fully discharge...', wait_time)
87+
wait(wait_time)
88+
89+
# start test #2 by turning on Channel 1 and check for all events
90+
tcp_socket.send_scpi_command('OUTP1 1')
91+
log_all_events(tcp_socket)
92+
93+
# wait until the channel is fully ramped to 10mA
94+
read_until_event(tcp_socket, SpikeSafeEvents.CHANNEL_READY) # event 100 is "Channel Ready"
95+
96+
# check for all events and measure readings on Channel 1 once per second for 5 seconds,
97+
# it is best practice to do this to ensure Channel 1 is on and does not have any errors
98+
time_end = time.time() + 5
99+
while time.time() < time_end:
100+
log_all_events(tcp_socket)
101+
log_memory_table_read(tcp_socket)
102+
wait(1)
103+
104+
# turn off Channel 1 and check for all events
105+
tcp_socket.send_scpi_command('OUTP1 0')
106+
log_all_events(tcp_socket)
107+
108+
# wait until the channel is fully discharged before disconnecting the load
109+
wait_time = get_spikesafe_channel_discharge_time(compliance_voltage)
110+
log.info('Waiting %s seconds for Channel 1 to fully discharge...', wait_time)
111+
wait(wait_time)
112+
113+
# disconnect from SpikeSafe
114+
tcp_socket.close_socket()
115+
116+
log.info("discharge_channel_using_delay.py completed.\n")
117+
118+
except SpikeSafeError as ssErr:
119+
# print any SpikeSafe-specific error to both the terminal and the log file, then exit the application
120+
error_message = 'SpikeSafe error: {}\n'.format(ssErr)
121+
log.error(error_message)
122+
print(error_message)
123+
sys.exit(1)
124+
except Exception as err:
125+
# print any general exception to both the terminal and the log file, then exit the application
126+
error_message = 'Program error: {}\n'.format(err)
127+
log.error(error_message)
128+
print(error_message)
129+
sys.exit(1)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import sys
2+
import time
3+
import logging
4+
from spikesafe_python.MemoryTableReadData import log_memory_table_read
5+
from spikesafe_python.Precision import get_precise_compliance_voltage_command_argument
6+
from spikesafe_python.Precision import get_precise_current_command_argument
7+
from spikesafe_python.ReadAllEvents import log_all_events
8+
from spikesafe_python.ReadAllEvents import read_until_event
9+
from spikesafe_python.SpikeSafeEvents import SpikeSafeEvents
10+
from spikesafe_python.SpikeSafeError import SpikeSafeError
11+
from spikesafe_python.TcpSocket import TcpSocket
12+
from spikesafe_python.Threading import wait
13+
14+
### set these before starting application
15+
16+
# SpikeSafe IP address and port number
17+
ip_address = '10.0.0.220'
18+
port_number = 8282
19+
20+
### setting up sequence log
21+
log = logging.getLogger(__name__)
22+
logging.basicConfig(
23+
level=logging.INFO,
24+
format='%(asctime)s.%(msecs)03d, %(levelname)s, %(message)s',
25+
datefmt='%m/%d/%Y %I:%M:%S',
26+
handlers=[
27+
logging.FileHandler("SpikeSafePythonSamples.log"),
28+
logging.StreamHandler(sys.stdout)
29+
]
30+
)
31+
32+
### start of main program
33+
try:
34+
log.info("discharge_channel_using_delay.py started.")
35+
36+
log.info("Python version: {}".format(sys.version))
37+
38+
# instantiate new TcpSocket to connect to SpikeSafe
39+
tcp_socket = TcpSocket()
40+
tcp_socket.open_socket(ip_address, port_number)
41+
42+
# reset to default state and check for all events,
43+
# it is best practice to check for errors after sending each command
44+
tcp_socket.send_scpi_command('*RST')
45+
log_all_events(tcp_socket)
46+
47+
# set Channel 1's pulse mode to DC and check for all events
48+
tcp_socket.send_scpi_command('SOUR1:FUNC:SHAP DC')
49+
log_all_events(tcp_socket)
50+
51+
# set Channel 1's safety threshold for over current protection to 50% and check for all events
52+
tcp_socket.send_scpi_command('SOUR1:CURR:PROT 50')
53+
log_all_events(tcp_socket)
54+
55+
# set Channel 1's current to 100 mA and check for all events
56+
tcp_socket.send_scpi_command(f'SOUR1:CURR {get_precise_current_command_argument(0.1)}')
57+
log_all_events(tcp_socket)
58+
59+
# set Channel 1's voltage to 20 V and check for all events
60+
compliance_voltage = 20
61+
tcp_socket.send_scpi_command(f'SOUR1:VOLT {get_precise_compliance_voltage_command_argument(compliance_voltage)}')
62+
log_all_events(tcp_socket)
63+
64+
# start test #1 by turning on Channel 1 and check for all events
65+
tcp_socket.send_scpi_command('OUTP1 1')
66+
log_all_events(tcp_socket)
67+
68+
# wait until the channel is fully ramped to 10mA
69+
read_until_event(tcp_socket, SpikeSafeEvents.CHANNEL_READY) # event 100 is "Channel Ready"
70+
71+
# check for all events and measure readings on Channel 1 once per second for 5 seconds,
72+
# it is best practice to do this to ensure Channel 1 is on and does not have any errors
73+
time_end = time.time() + 5
74+
while time.time() < time_end:
75+
log_all_events(tcp_socket)
76+
log_memory_table_read(tcp_socket)
77+
wait(1)
78+
79+
# turn off Channel 1 and check for all events
80+
tcp_socket.send_scpi_command('OUTP1 0', enable_logging=True)
81+
log_all_events(tcp_socket)
82+
83+
# wait until the channel is fully discharged before starting test #2
84+
log.info('Waiting for Channel 1 to fully discharge after test #1...')
85+
is_discharge_complete = ''
86+
while is_discharge_complete != 'TRUE':
87+
tcp_socket.send_scpi_command('OUTP1:DISC:COMP?', enable_logging=True)
88+
is_discharge_complete = tcp_socket.read_data(enable_logging=True)
89+
90+
# start test #2 by turning on Channel 1 and check for all events
91+
tcp_socket.send_scpi_command('OUTP1 1', enable_logging=True)
92+
log_all_events(tcp_socket)
93+
94+
# wait until the channel is fully ramped to 10mA
95+
read_until_event(tcp_socket, SpikeSafeEvents.CHANNEL_READY) # event 100 is "Channel Ready"
96+
97+
# check for all events and measure readings on Channel 1 once per second for 5 seconds,
98+
# it is best practice to do this to ensure Channel 1 is on and does not have any errors
99+
time_end = time.time() + 5
100+
while time.time() < time_end:
101+
log_all_events(tcp_socket)
102+
log_memory_table_read(tcp_socket)
103+
wait(1)
104+
105+
# turn off Channel 1 and check for all events
106+
tcp_socket.send_scpi_command('OUTP1 0', enable_logging=True)
107+
log_all_events(tcp_socket)
108+
109+
# wait until the channel is fully discharged before disconnecting the load
110+
log.info('Waiting for Channel 1 to fully discharge after test #2...')
111+
is_discharge_complete = ''
112+
while is_discharge_complete != 'TRUE':
113+
tcp_socket.send_scpi_command('OUTP1:DISC:COMP?', enable_logging=True)
114+
is_discharge_complete = tcp_socket.read_data(enable_logging=True)
115+
116+
# disconnect from SpikeSafe
117+
tcp_socket.close_socket()
118+
119+
log.info("discharge_channel_using_delay.py completed.\n")
120+
121+
except SpikeSafeError as ssErr:
122+
# print any SpikeSafe-specific error to both the terminal and the log file, then exit the application
123+
error_message = 'SpikeSafe error: {}\n'.format(ssErr)
124+
log.error(error_message)
125+
print(error_message)
126+
sys.exit(1)
127+
except Exception as err:
128+
# print any general exception to both the terminal and the log file, then exit the application
129+
error_message = 'Program error: {}\n'.format(err)
130+
log.error(error_message)
131+
print(error_message)
132+
sys.exit(1)

0 commit comments

Comments
 (0)