Skip to content

Commit

Permalink
PAD4 feature extensions
Browse files Browse the repository at this point in the history
All methods for the PAD4 were refactored.
Now the PAD4 measuring range can be configured with Python and whether current or voltage is to be measured.
The connection to the term has also been optimised.
Thales 5.8.5 is mandatory for this version. This version is not downward compatible.
  • Loading branch information
maxkrapp1 committed Feb 9, 2023
1 parent 462bb67 commit 4a3e4dd
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 82 deletions.
7 changes: 6 additions & 1 deletion Examples/CyclicVoltammetry/CyclicVoltammetry.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
Expand All @@ -92,7 +93,11 @@
"In the next step, the actual parameters for the measurement method are set. \n",
"Alternatively, a rule file could be loaded which sets the parameters for the measurement.\n",
"\n",
"The methods are named after the parameters they set. Additional information can be found in the [API documentation](https://doc.zahner.de/thales_remote/script_wrapper.html)."
"The methods are named after the parameters they set. Additional information can be found in the [API documentation](https://doc.zahner.de/thales_remote/script_wrapper.html).\n",
"\n",
"[setCVMinimumCurrent()](https://doc.zahner.de/thales_remote/script_wrapper.html#thales_remote.script_wrapper.ThalesRemoteScriptWrapper.setCVMinimumCurrent) and [setCVMaximumCurrent()](https://doc.zahner.de/thales_remote/script_wrapper.html#thales_remote.script_wrapper.ThalesRemoteScriptWrapper.setCVMaximumCurrent) implicitly set the current measuring range which is used. If these current limits are set too high, the measurement accuracy will deteriorate because the current measurement range may be too large for the object current. The minimum and maximum current cannot be disabled.\n",
"\n",
"It is recommended to execute [disableCVAutoRestartAtCurrentOverflow()](https://doc.zahner.de/thales_remote/script_wrapper.html#thales_remote.script_wrapper.ThalesRemoteScriptWrapper.disableCVAutoRestartAtCurrentOverflow) and [disableCVAutoRestartAtCurrentUnderflow()](https://doc.zahner.de/thales_remote/script_wrapper.html#thales_remote.script_wrapper.ThalesRemoteScriptWrapper.disableCVAutoRestartAtCurrentUnderflow), this prevents the measurement from being restarted with other adjusted parameters."
]
},
{
Expand Down
6 changes: 3 additions & 3 deletions Examples/EIS/EIS.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"source": [
"import sys\n",
"from thales_remote.connection import ThalesRemoteConnection\n",
"from thales_remote.script_wrapper import PotentiostatMode,ThalesRemoteScriptWrapper"
"from thales_remote.script_wrapper import PotentiostatMode,ThalesRemoteScriptWrapper,ScanStrategy,ScanDirection"
]
},
{
Expand Down Expand Up @@ -112,8 +112,8 @@
" zahnerZennium.setLowerStepsPerDecade(2)\n",
" zahnerZennium.setUpperNumberOfPeriods(20)\n",
" zahnerZennium.setUpperStepsPerDecade(5)\n",
" zahnerZennium.setScanDirection(\"startToMax\")\n",
" zahnerZennium.setScanStrategy(\"single\")"
" zahnerZennium.setScanDirection(ScanDirection.START_TO_MAX)\n",
" zahnerZennium.setScanStrategy(ScanStrategy.SINGLE_SINE)"
]
},
{
Expand Down
11 changes: 8 additions & 3 deletions Examples/EIS/EIS.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import sys
from thales_remote.connection import ThalesRemoteConnection
from thales_remote.script_wrapper import PotentiostatMode, ThalesRemoteScriptWrapper
from thales_remote.script_wrapper import (
PotentiostatMode,
ThalesRemoteScriptWrapper,
ScanStrategy,
ScanDirection,
)

if __name__ == "__main__":
zenniumConnection = ThalesRemoteConnection()
Expand All @@ -26,8 +31,8 @@
zahnerZennium.setLowerStepsPerDecade(2)
zahnerZennium.setUpperNumberOfPeriods(20)
zahnerZennium.setUpperStepsPerDecade(5)
zahnerZennium.setScanDirection("startToMax")
zahnerZennium.setScanStrategy("single")
zahnerZennium.setScanDirection(ScanDirection.START_TO_MAX)
zahnerZennium.setScanStrategy(ScanStrategy.SINGLE_SINE)

zahnerZennium.enablePotentiostat()

Expand Down
103 changes: 72 additions & 31 deletions Examples/EISPad4/EISPad4.ipynb

Large diffs are not rendered by default.

26 changes: 17 additions & 9 deletions Examples/EISPad4/EISPad4.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import sys
from thales_remote.connection import ThalesRemoteConnection
from thales_remote.script_wrapper import PotentiostatMode, ThalesRemoteScriptWrapper
from thales_remote.script_wrapper import (
PotentiostatMode,
ScanStrategy,
ScanDirection,
FileNaming,
Pad4Mode,
ThalesRemoteScriptWrapper,
)

from zahner_analysis.file_import.ism_import import IsmImport
import matplotlib.pyplot as plt
Expand All @@ -16,27 +23,28 @@

zahnerZennium.calibrateOffsets()

zahnerZennium.setEISNaming("counter")
zahnerZennium.setEISNaming(FileNaming.COUNTER)
zahnerZennium.setEISCounter(1)
zahnerZennium.setEISOutputPath(r"C:\THALES\temp\test1")
zahnerZennium.setEISOutputFileName("spectra_cells")

zahnerZennium.setPotentiostatMode(PotentiostatMode.POTMODE_POTENTIOSTATIC)
zahnerZennium.setAmplitude(100e-3)
zahnerZennium.setPotential(0)
zahnerZennium.setLowerFrequencyLimit(0.1)
zahnerZennium.setLowerFrequencyLimit(1)
zahnerZennium.setStartFrequency(1000)
zahnerZennium.setUpperFrequencyLimit(50000)
zahnerZennium.setUpperFrequencyLimit(10000)
zahnerZennium.setLowerNumberOfPeriods(2)
zahnerZennium.setLowerStepsPerDecade(5)
zahnerZennium.setUpperNumberOfPeriods(20)
zahnerZennium.setUpperStepsPerDecade(10)
zahnerZennium.setScanDirection("startToMax")
zahnerZennium.setScanStrategy("single")
zahnerZennium.setScanDirection(ScanDirection.START_TO_MAX)
zahnerZennium.setScanStrategy(ScanStrategy.SINGLE_SINE)

zahnerZennium.setupPAD4(1, 1, 1)
zahnerZennium.setupPAD4(1, 2, 1)
zahnerZennium.enablePAD4()
zahnerZennium.setupPad4Channel(1, 1, 1, voltageRange=4.0, shuntResistor=10e-3)
zahnerZennium.setupPad4Channel(1, 2, 1, voltageRange=4.0, shuntResistor=10e-3)
zahnerZennium.setupPad4ModeGlobal(Pad4Mode.VOLTAGE) # or Pad4Mode.CURRENT
zahnerZennium.enablePad4Global()

zahnerZennium.enablePotentiostat()
zahnerZennium.measureEIS()
Expand Down
15 changes: 8 additions & 7 deletions Examples/FileExchangeEIS/FileExchangeEIS.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"source": [
"import sys\n",
"from thales_remote.connection import ThalesRemoteConnection\n",
"from thales_remote.script_wrapper import PotentiostatMode,ThalesRemoteScriptWrapper\n",
"from thales_remote.script_wrapper import PotentiostatMode,ScanStrategy,ScanDirection,FileNaming,Pad4Mode,ThalesRemoteScriptWrapper\n",
"from thales_remote.file_interface import ThalesFileInterface\n",
"from zahner_analysis.file_import.ism_import import IsmImport\n",
"\n",
Expand Down Expand Up @@ -95,7 +95,7 @@
"outputs": [],
"source": [
" zahnerZennium.setEISOutputPath(r\"C:\\THALES\\temp\")\n",
" zahnerZennium.setEISNaming(\"individual\")\n",
" zahnerZennium.setEISNaming(FileNaming.INDIVIDUAL)\n",
" zahnerZennium.setEISOutputFileName(\"myeis\")\n",
"\n",
" zahnerZennium.setPotentiostatMode(PotentiostatMode.POTMODE_POTENTIOSTATIC)\n",
Expand All @@ -108,8 +108,8 @@
" zahnerZennium.setLowerStepsPerDecade(5)\n",
" zahnerZennium.setUpperNumberOfPeriods(20)\n",
" zahnerZennium.setUpperStepsPerDecade(5)\n",
" zahnerZennium.setScanDirection(\"startToMax\")\n",
" zahnerZennium.setScanStrategy(\"single\")\n",
" zahnerZennium.setScanDirection(ScanDirection.START_TO_MAX)\n",
" zahnerZennium.setScanStrategy(ScanStrategy.SINGLE_SINE)\n",
"\n",
" zahnerZennium.enablePotentiostat()\n",
"\n",
Expand Down Expand Up @@ -294,9 +294,10 @@
" zahnerZennium.setEISCounter(13)\n",
" zahnerZennium.setEISOutputFileName(\"spectra\")\n",
" \n",
" zahnerZennium.setupPAD4(1,1,1)\n",
" zahnerZennium.setupPAD4(1,2,1)\n",
" zahnerZennium.enablePAD4()"
" zahnerZennium.setupPad4Channel(1,1,1,voltageRange=4.0,shuntResistor=10e-3)\n",
" zahnerZennium.setupPad4Channel(1,2,1,voltageRange=4.0,shuntResistor=10e-3)\n",
" zahnerZennium.setupPad4ModeGlobal(Pad4Mode.VOLTAGE) # or Pad4Mode.CURRENT\n",
" zahnerZennium.enablePad4Global()"
]
},
{
Expand Down
22 changes: 15 additions & 7 deletions Examples/FileExchangeEIS/FileExchangeEIS.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import sys
from thales_remote.connection import ThalesRemoteConnection
from thales_remote.script_wrapper import PotentiostatMode, ThalesRemoteScriptWrapper
from thales_remote.script_wrapper import (
PotentiostatMode,
ScanStrategy,
ScanDirection,
FileNaming,
Pad4Mode,
ThalesRemoteScriptWrapper,
)
from thales_remote.file_interface import ThalesFileInterface
from zahner_analysis.file_import.ism_import import IsmImport

Expand All @@ -24,7 +31,7 @@
fileInterface = ThalesFileInterface(remoteIP)

zahnerZennium.setEISOutputPath(r"C:\THALES\temp")
zahnerZennium.setEISNaming("individual")
zahnerZennium.setEISNaming(FileNaming.INDIVIDUAL)
zahnerZennium.setEISOutputFileName("myeis")

zahnerZennium.setPotentiostatMode(PotentiostatMode.POTMODE_POTENTIOSTATIC)
Expand All @@ -37,8 +44,8 @@
zahnerZennium.setLowerStepsPerDecade(5)
zahnerZennium.setUpperNumberOfPeriods(20)
zahnerZennium.setUpperStepsPerDecade(5)
zahnerZennium.setScanDirection("startToMax")
zahnerZennium.setScanStrategy("single")
zahnerZennium.setScanDirection(ScanDirection.START_TO_MAX)
zahnerZennium.setScanStrategy(ScanStrategy.SINGLE_SINE)

zahnerZennium.enablePotentiostat()

Expand Down Expand Up @@ -108,9 +115,10 @@
zahnerZennium.setEISCounter(13)
zahnerZennium.setEISOutputFileName("spectra")

zahnerZennium.setupPAD4(1, 1, 1)
zahnerZennium.setupPAD4(1, 2, 1)
zahnerZennium.enablePAD4()
zahnerZennium.setupPad4Channel(1, 1, 1, voltageRange=4.0, shuntResistor=10e-3)
zahnerZennium.setupPad4Channel(1, 2, 1, voltageRange=4.0, shuntResistor=10e-3)
zahnerZennium.setupPad4ModeGlobal(Pad4Mode.VOLTAGE) # or Pad4Mode.CURRENT
zahnerZennium.enablePad4Global()

zahnerZennium.measureEIS()
fileInterface.disableAutomaticFileExchange()
Expand Down
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Zahner-elektrik
Copyright (c) 2023 Zahner-elektrik

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
3 changes: 2 additions & 1 deletion thales_remote/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def connectToTerm(
:param connection_name: name of the connection ScriptRemote for Remote and Logging as Online Display
:returns: True on success, False on failure
"""
time.sleep(0.4)
self._socket_handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self._socket_handle.connect((address, self._term_port))
Expand All @@ -98,7 +99,7 @@ def connectToTerm(

registration_packet = bytearray()
registration_packet += bytearray(struct.pack("<H", payload_length))
registration_packet += bytearray([0x02, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF])
registration_packet += bytearray([0x12, 0xD0, 0xFF, 0xFF, 0xFF, 0xFF])
registration_packet += bytearray(connection_name, "ASCII")

# print("\n" + str(datetime.now().time()) + " send:")
Expand Down
78 changes: 60 additions & 18 deletions thales_remote/script_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ class FileNaming(Enum):
"""

DATE_TIME = 0
INDIVIDUAL = 1
COUNTER = 2
COUNTER = 1
INDIVIDUAL = 2

@classmethod
def stringToEnum(cls, string: str):
Expand All @@ -116,6 +116,17 @@ def stringToEnum(cls, string: str):
return stringEnumMap.get(string)


class Pad4Mode(Enum):
"""
options for the PAD4 operating mode.
All channels can be either voltage or current. Individual setting is not possible.
"""

VOLTAGE = 0
CURRENT = 1


class ThalesRemoteScriptWrapper(object):
"""
Wrapper that uses the ThalesRemoteConnection class.
Expand Down Expand Up @@ -401,29 +412,58 @@ def disableRuleFileUsage(self) -> str:
"""
return self.enableRuleFileUsage(False)

def setupPAD4(self, card: int, channel: int, state: Union[int, bool]) -> str:
def setupPad4Channel(
self,
card: int,
channel: int,
state: Union[int, bool],
voltageRange: Optional[float] = None,
shuntResistor: Optional[float] = None,
) -> None:
"""
Setting a channel of a PAD4 card for an EIS measurement
Each PAD4 channel must be configured individually. Each channel can be switched on or off individually.
But the PAD4 measurements must still be switched on globally with :func:`~thales_remote.script_wrapper.ThalesRemoteScriptWrapper.enablePad4Global`.
Each channel can be given a different voltage range or shunt.
:param card: index of the card starting at 1 and up to 4
:param channel: index of the card starting at 1 and up to 4
:param state: If `1` or `True` the channel is switched on else switched off
:returns: reponse string from the device
:param voltageRange: input voltage range, if this differs from 4 V
:param shuntResistor: shunt resistor, which is used. Only used if :func:`~thales_remote.script_wrapper.ThalesRemoteScriptWrapper.setupPad4ModeGlobal` is set to :class:`.Pad4Mode`.CURRENT
:returns: reponse string from the device
"""
commands = [f"PAD4={card};{channel};{1 if state else 0}"]
if voltageRange:
commands.append(f"PAD4_PRANGE={card};{channel};{voltageRange}")
if shuntResistor:
commands.append(f"PAD4_RSHUNT={card};{channel};{shuntResistor}")

for command in commands:
if isinstance(state, int):
state = state == 1
reply = self.executeRemoteCommand(command)

if "ERROR" in reply:
raise ThalesRemoteError(
reply.rstrip("\r")
+ ThalesRemoteScriptWrapper.undefindedStandardErrorString
)
return

def setupPad4ModeGlobal(self, mode: Pad4Mode) -> str:
"""
if isinstance(state, int):
state = state == 1
reply = self.executeRemoteCommand(
"PAD4=" + str(card) + ";" + ("1" if state else "0")
)
Switch between current and voltage measurement
if "ERROR" in reply:
raise ThalesRemoteError(
reply.rstrip("\r")
+ ThalesRemoteScriptWrapper.undefindedStandardErrorString
)
return reply
The user can switch the type of PAD4 channels between voltage sense (standard configuration) and current sense (with additional shunt resistor).
:param mode: :class:`.Pad4Mode`.VOLTAGE or :class:`.Pad4Mode`.CURRENT
:returns: reponse string from the device
"""
return self.executeRemoteCommand(f"PAD4MOD={mode.value}")

def enablePAD4(self, state: bool = True) -> str:
def enablePad4Global(self, state: bool = True) -> str:
"""
switch on the set PAD4 channels
Expand All @@ -435,15 +475,15 @@ def enablePAD4(self, state: bool = True) -> str:
"""
return self.setValue("PAD4ENA", 1 if state else 0)

def disablePAD4(self) -> str:
def disablePad4Global(self) -> str:
"""
switch off the set PAD4 channels
:returns: reponse string from the device
"""
return self.enablePAD4(False)

def readPAD4Setup(self) -> str:
def readPad4SetupGlobal(self) -> str:
"""
read the currently set parameters
Expand Down Expand Up @@ -806,6 +846,7 @@ def setCVMaximumCurrent(self, current: float) -> str:
set the maximum current
The maximum positive current at which the measurement is interrupted.
This is also the current which is used to determine the shunt. This cannot be deactivated.
:param current: The maximum current for measurement in A at which the measurement is interrupted
:returns: reponse string from the device
Expand All @@ -817,6 +858,7 @@ def setCVMinimumCurrent(self, current: float) -> str:
set the minimum current
The maximum negative current at which the measurement is interrupted.
This is also the current which is used to determine the shunt. This cannot be deactivated.
:param current: The minimum current for measurement in A.
:returns: reponse string from the device
Expand Down

0 comments on commit 4a3e4dd

Please sign in to comment.