Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP : DC sources #4

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a280af5
Rough structure...
MatthieuDartiailh Apr 22, 2015
3932937
renaming ...
MatthieuDartiailh Apr 22, 2015
9e264e6
WIP
MatthieuDartiailh Apr 23, 2015
ee001f5
Start refactoring GS200 to use SCPI base driver.
MatthieuDartiailh Apr 23, 2015
7cefbea
Start Bilt driver.
MatthieuDartiailh Apr 23, 2015
e998778
Wip assuming some changes in lantz:
MatthieuDartiailh May 1, 2015
15307d8
Fleshing a bit BE2100 driver needs to test and determine empirically …
MatthieuDartiailh May 3, 2015
bc3c77a
Fix some getters in Yokogawa7651, add DEFAULTS and PROTOCOLS to all d…
MatthieuDartiailh May 5, 2015
233760c
Flesh the ieee488 module.
MatthieuDartiailh May 6, 2015
37312d7
Use IEEE488 standards in YokogawaGS200.
MatthieuDartiailh May 6, 2015
54b14e2
Clean up imports in dc_sources standards.
MatthieuDartiailh May 6, 2015
e3a6fdb
Turn idn into a Feature and implement connected getter by testing rea…
MatthieuDartiailh May 6, 2015
6c77920
Use output channel.
MatthieuDartiailh Jun 5, 2015
79879c3
dc sources : WIP modifying the drivers to fit the new base classes.
MatthieuDartiailh Oct 8, 2015
f385d86
dc sources : more wip
MatthieuDartiailh Oct 8, 2015
ab3eee4
dc sources : clean up yokogawas and bilt drivers (mostly finished)
MatthieuDartiailh Oct 9, 2015
149e2fe
dc sources : progress on keysight E3631A
MatthieuDartiailh Oct 9, 2015
4cc5f06
dc sources : WIP on keysight E3633A and E3634A
MatthieuDartiailh Oct 9, 2015
9e3270d
common : add basic error reading for scpi and rs232 support through m…
MatthieuDartiailh Oct 12, 2015
29df6f0
dc sources : yokogawa use common.scpi for error_reading
MatthieuDartiailh Oct 12, 2015
7540136
dc sources : keysight refactor to use common and use a single base cl…
MatthieuDartiailh Oct 12, 2015
243d337
dc sources : wip on keysight sources.
MatthieuDartiailh Oct 12, 2015
57ef8cf
dc_sources : minor fixes
MatthieuDartiailh Oct 14, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lantz_drivers/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-

138 changes: 138 additions & 0 deletions lantz_drivers/base/dc_sources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
"""
lantz_drivers.base.dc_sources
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Definition of the standard expected from DC sources.

:copyright: 2015 by The Lantz Authors
:license: BSD, see LICENSE for more details.
"""
from __future__ import (division, unicode_literals, print_function,
absolute_import)
from lantz_core.has_features import (HasFeatures, channel, Subsystem, Action)
from lantz_core.features import Bool, Float, Unicode, constant


class DCPowerSource(HasFeatures):
"""Standard interface expected from all DC Power sources.

"""

#:
output = channel((0,))

with output as o:

#:
o.enabled = Bool(aliases={True: ['On', 'ON', 'On'],
False: ['Off', 'OFF', 'off']})

#:
o.voltage = Float(unit='V')

#:
o.voltage_range = Float(unit='V')

#:
o.voltage_limit_behavior = Unicode(constant('regulate'),
values=('irrelevant', 'trip',
'regulate'))

#:
o.current = Float(unit='A')

#:
o.current_range = Float(unit='A')

#:
o.current_limit_behavior = Unicode(constant('regulate'),
values=('irrelevant', 'trip',
'regulate'))

@o
@Action()
def read_output_status(self):
"""
"""
pass


class DCPowerSourceWithMeasure(Subsystem):
"""
"""
#:
output = channel((0,))

with output as o:

@o
@Action()
def measure(self, quantity, **kwargs):
"""Measure the output voltage/current.

Parameters
----------
quantity : unicode, {'voltage', 'current'}
Quantity to measure.

**kwargs :
Optional kwargs to specify the conditions of the measure
(integration time, averages, etc) if applicable.

Returns
-------
value : float or pint.Quantity
Measured value. If units are supported the value is a Quantity
object.

"""
pass


class DCSourceTriggerSubsystem(Subsystem):
"""
"""
#:
mode = Unicode(values=('disabled', 'enabled'))

#:
source = Unicode(values=('immediate', 'bus')) # Will extend later

#:
delay = Float(unit='s')

@Action()
def arm(self):
"""
"""
pass


class DCSourceProtectionSubsystem(Subsystem):
"""
"""
#:
enabled = Bool(aliases={True: ['On', 'ON', 'On'],
False: ['Off', 'OFF', 'off']})

#:
behavior = Unicode(constant('trip'))

#:
low_level = Float()

#:
high_level = Float()

@Action()
def read_status(self):
"""
"""
pass

@Action()
def reset(self):
"""
"""
pass
39 changes: 39 additions & 0 deletions lantz_drivers/base/identity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
"""
lantz_drivers.base.identity
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Definition of the standard identity subsystem.

:copyright: 2015 by The Lantz Authors
:license: BSD, see LICENSE for more details.
"""
from __future__ import (division, unicode_literals, print_function,
absolute_import)
from lantz_core.has_features import Subsystem
from lantz_core.features import Unicode


class Identity(Subsystem):
"""Standard subsystem defining the expected identity infos.

This should be used as a base class for the identity subsystem of
instruments providing identity informations.

Notes
-----
Somes of those infos might not be available for a given instrument. In such
a case the Feature should return ''.

"""
#: Manufacturer as returned by the instrument.
manufacturer = Unicode()

#: Model name as returned by the instrument.
model = Unicode()

#: Instrument serial number.
serial = Unicode()

#: Version of the installed firmware.
firmware = Unicode()
Empty file added lantz_drivers/bilt/__init__.py
Empty file.
44 changes: 44 additions & 0 deletions lantz_drivers/bilt/bn100.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
"""
lantz_drivers.bilt.bn100
~~~~~~~~~~~~~~~~~~~~~~~~

Driver for the Bilt BN100 chassis.

:copyright: 2015 by The Lantz Authors
:license: BSD, see LICENSE for more details.

"""
from __future__ import (division, unicode_literals, print_function,
absolute_import)

from lantz_core.has_features import channel

from ..common.scpi.error_reading import SCPIErrorReading
from ..common.ieee488 import IEEEReset
from .cards.be2100 import BE2100, detect_be2100


class BN100(IEEEReset, SCPIErrorReading):
"""Driver for the Bilt BN100 chassis.

"""

PROTOCOLS = {'TCPIP': '5025::SOCKET'}

DEFAULTS = {'COMMON': {'read_termination': '\n',
'write_termination': '\n'}
}

be2100 = channel('_list_be2100', BE2100)

IEEE_RESET_WAIT = 4

def initialize(self):
"""Make sure the communication parameters are correctly sets.

"""
super(BN100, self).initialize()
self.write('SYST:VERB 0')

_list_be2100 = detect_be2100
2 changes: 2 additions & 0 deletions lantz_drivers/bilt/cards/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-

165 changes: 165 additions & 0 deletions lantz_drivers/bilt/cards/be2100.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# -*- coding: utf-8 -*-
"""
lantz_drivers.bilt.cards.be2100
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Driver for the Bilt BE2100 card : high stability DC voltage source.

:copyright: 2015 by The Lantz Authors
:license: BSD, see LICENSE for more details.

"""
from __future__ import (division, unicode_literals, print_function,
absolute_import)

from lantz_core import set_feat, subsystem, channel, Action
from lantz_core.features import Float, Unicode, constant
from lantz_core.limits import FloatLimitsValidator
from lantz_core.unit import to_float

from .common import BN100Card, make_card_detector
from ...base.dc_sources import (DCPowerSourceWithMeasure,
DCSourceTriggerSubsystem)


detect_be2100 = make_card_detector(['BE2101', 'BE2102', 'BE2103'])


# Add identity parsing
class BE2100(BN100Card, DCPowerSourceWithMeasure):
"""Driver for the Bilt BE2100 high precision dc voltage source.

"""
output = channel()

with output as o:
o.enabled = set_feat(getter='OUT?', setter='OUT {}')

o.voltage = set_feat(getter='VOLT?', setter='VOLT {:E}',
limits='voltage')

o.voltage_range = set_feat(getter='VOLT:RANG?', setter='VOLT:RANG {}',
values=(1.2, 12), extract='{},{_}',
checks=(None, 'not driver.output'),
discard={'features': ('voltage',),
'limits': ('voltage',)})

o.voltage_limit_behavior = set_feat(getter=constant('irrelevant'))

#: Set the voltage settling filter. Slow 100 ms, Fast 10 ms
o.voltage_filter = Unicode('VOLT:FILT?', 'VOLT:FILT {}',
mapping={'Slow': 0, 'Fast': 1})

#: Specify stricter voltage limitations than the ones linked to the
#: range.
o.voltage_saturation = subsystem()
with o.voltage_saturation as vs:
#: Lowest allowed voltage.
vs.low = Float('VOLT:SAT:NEG?', 'VOLT:SAT:NEG {}', unit='V',
limits=(-12, 0), discard={'limits': ('voltage',)})

#: Highest allowed voltage.
vs.high = Float('VOLT:SAT:POS?', 'VOLT:SAT:POS {}', unit='V',
limits=(-12, 0), discard={'limits': ('voltage',)})

o.current = set_feat(getter=constant(0.2))

o.current_range = set_feat(getter=constant(0.2))

o.current_limit_behavior = set_feat(getter=constant('regulate'))

#: Subsystem handling triggering and reaction to triggering.
o.trigger = subsystem(DCSourceTriggerSubsystem)
with o.trigger as tr:
#: Type of response to triggering :
#: - disabled : immediate update of voltage everytime the voltage
#: feature is
#: updated.
#: - slope : update after receiving a trigger based on the slope
#: value.
#: - stair : update after receiving a trigger using step_amplitude
#: and step_width.
#: - step : increment by one step_amplitude till target value for
#: each triggering.
#: - auto : update after receiving a trigger by steps but
#: determining when to move to next step based on voltage
#: sensing.
tr.mode = Unicode('TRIG:IN?', 'TRIG:IN {}',
mapping={'disabled': '0', 'slope': '1',
'stair': '2', 'step': '4', 'auto': '5'})

#: Delay to wait after receiving a trigger event before reacting.
tr.delay = set_feat(getter='TRIG:IN:DEL?', setter='TRIG:IN:DEL {}',
unit='ms', limits=(0, 60000, 1))

#: Voltage slope to use in slope mode.
tr.slope = Float('VOLT:SLOP?', 'VOLT:SLOP {}', unit='V/ms',
limits=(1.2e-6, 1))

#: High of each update in stair and step mode.
tr.step_amplitude = Float('VOLT:ST:AMPL?', 'VOLT:ST:AMPL {}',
unit='V', limits='voltage')

#: Width of each step in stair mode.
tr.step_width = Float('VOLT:ST:WID?', 'VOLT:ST:WID {}', unit='ms',
limits=(100, 60000, 1))

#: Absolute threshold value of the settling tracking comparator.
tr.ready_amplitude = Float('TRIG:READY:AMPL?',
'TRIG:READY:AMPL {}',
unit='V', limits='voltage')

# XXXX
@o
@Action()
def read_output_status(self):
"""
"""
pass

@o
@Action()
def read_voltage_status(self):
"""Progression of the current voltage update.

Returns
-------
progression : int
Progression of the voltage update. The value is between 0
and 1.

"""
return int(self.query('I {};VOLT:STAT?'.format(self.ch_id)))

# XXXX
@o
@Action(unit=())
def measure(self, kind, **kwargs):
"""
"""
if kind != 'voltage':
raise ValueError('')

# =====================================================================
# --- Private API -----------------------------------------------------
# =====================================================================

@o
def _limits_voltage(self):
"""Compute the voltage limits based on range and saturation.

"""
rng = to_float(self.voltage_range)
low = max(-rng, float(self.voltage_saturation.low))
high = min(rng, float(self.voltage_saturation.high))

step = 1.2e-6 if rng == 1.2 else 1.2e-5

return FloatLimitsValidator(low, high, step, 'V')

@Action
def fire_trigger(self):
"""Send a software trigger.

"""
self.write('I {};TRIG:IN:INIT'.format(self.ch_id))
Loading