Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:python-ivi:writing-drivers [2013/07/22 02:39] – alex | en:python-ivi:writing-drivers [2013/07/22 04:17] (current) – alex | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Writing New Python-IVI Drivers ====== | + | ====== Writing New Python IVI Drivers ====== |
| Note: this page is under construction | Note: this page is under construction | ||
| Line 17: | Line 17: | ||
| Test the interface and identity query by instantiating your driver and connecting to the instrument by running something like this in ipython: | Test the interface and identity query by instantiating your driver and connecting to the instrument by running something like this in ipython: | ||
| - | < | + | < |
| import ivi | import ivi | ||
| mso = ivi.agilent.agilentMSO7104A(" | mso = ivi.agilent.agilentMSO7104A(" | ||
| Line 28: | Line 28: | ||
| Finally, you need to go write python code for all of the functions that the instrument supports. Take a look at some '' | Finally, you need to go write python code for all of the functions that the instrument supports. Take a look at some '' | ||
| + | |||
| + | ===== Driver Template ===== | ||
| + | |||
| + | This is a sample template driver that incorporates all of the major components. | ||
| + | |||
| + | <code python> | ||
| + | """ | ||
| + | |||
| + | Python Interchangeable Virtual Instrument Library | ||
| + | |||
| + | Copyright (c) 2012 Alex Forencich | ||
| + | |||
| + | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + | of this software and associated documentation files (the " | ||
| + | in the Software without restriction, | ||
| + | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + | copies of the Software, and to permit persons to whom the Software is | ||
| + | furnished to do so, subject to the following conditions: | ||
| + | |||
| + | The above copyright notice and this permission notice shall be included in | ||
| + | all copies or substantial portions of the Software. | ||
| + | |||
| + | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY | ||
| + | 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. | ||
| + | |||
| + | """ | ||
| + | |||
| + | import struct | ||
| + | |||
| + | from .. import ivi | ||
| + | from .. import scope | ||
| + | |||
| + | AcquisitionTypeMapping = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | # more instrument-specific sets and mappings | ||
| + | |||
| + | class agilent7000(ivi.Driver, | ||
| + | scope.GlitchTrigger, | ||
| + | scope.WaveformMeasurement, | ||
| + | scope.ContinuousAcquisition, | ||
| + | scope.SampleMode, | ||
| + | " | ||
| + | | ||
| + | def __init__(self, | ||
| + | self._analog_channel_name = list() | ||
| + | self._analog_channel_count = 4 | ||
| + | self._digital_channel_name = list() | ||
| + | self._digital_channel_count = 16 | ||
| + | self._channel_label = list() | ||
| + | # other per-channel instrument-specific variables that are | ||
| + | # referenced in _init_channels | ||
| + | | ||
| + | super(agilent7000, | ||
| + | | ||
| + | self._instrument_id = ' | ||
| + | self._analog_channel_name = list() | ||
| + | self._analog_channel_count = 4 | ||
| + | self._digital_channel_name = list() | ||
| + | self._digital_channel_count = 16 | ||
| + | self._channel_count = 20 | ||
| + | self._bandwidth = 1e9 | ||
| + | # initialize other instrument-specific variables | ||
| + | | ||
| + | self._identity_description = " | ||
| + | self._identity_identifier = "" | ||
| + | self._identity_revision = "" | ||
| + | self._identity_vendor = "" | ||
| + | self._identity_instrument_manufacturer = " | ||
| + | self._identity_instrument_model = "" | ||
| + | self._identity_instrument_firmware_revision = "" | ||
| + | self._identity_specification_major_version = 4 | ||
| + | self._identity_specification_minor_version = 1 | ||
| + | self._identity_supported_instrument_models =[' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | | ||
| + | self.channels._add_property(' | ||
| + | self._get_channel_label, | ||
| + | self._set_channel_label) | ||
| + | # other instrument specific properties | ||
| + | | ||
| + | self._init_channels() | ||
| + | | ||
| + | def initialize(self, | ||
| + | "Opens an I/O session to the instrument." | ||
| + | | ||
| + | self._channel_count = self._analog_channel_count + self._digital_channel_count | ||
| + | | ||
| + | super(agilent7000, | ||
| + | | ||
| + | # interface clear | ||
| + | if not self._driver_operation_simulate: | ||
| + | self._clear() | ||
| + | | ||
| + | # check ID | ||
| + | if id_query and not self._driver_operation_simulate: | ||
| + | id = self.identity.instrument_model | ||
| + | id_check = self._instrument_id | ||
| + | id_short = id[: | ||
| + | if id_short != id_check: | ||
| + | raise Exception(" | ||
| + | | ||
| + | # reset | ||
| + | if reset: | ||
| + | self.utility.reset() | ||
| + | | ||
| + | | ||
| + | def _load_id_string(self): | ||
| + | if self._driver_operation_simulate: | ||
| + | self._identity_instrument_manufacturer = "Not available while simulating" | ||
| + | self._identity_instrument_model = "Not available while simulating" | ||
| + | self._identity_instrument_firmware_revision = "Not available while simulating" | ||
| + | else: | ||
| + | lst = self._ask(" | ||
| + | self._identity_instrument_manufacturer = lst[0] | ||
| + | self._identity_instrument_model = lst[1] | ||
| + | self._identity_instrument_firmware_revision = lst[3] | ||
| + | self._set_cache_valid(True, | ||
| + | self._set_cache_valid(True, | ||
| + | self._set_cache_valid(True, | ||
| + | | ||
| + | def _get_identity_instrument_manufacturer(self): | ||
| + | if self._get_cache_valid(): | ||
| + | return self._identity_instrument_manufacturer | ||
| + | self._load_id_string() | ||
| + | return self._identity_instrument_manufacturer | ||
| + | | ||
| + | def _get_identity_instrument_model(self): | ||
| + | if self._get_cache_valid(): | ||
| + | return self._identity_instrument_model | ||
| + | self._load_id_string() | ||
| + | return self._identity_instrument_model | ||
| + | | ||
| + | def _get_identity_instrument_firmware_revision(self): | ||
| + | if self._get_cache_valid(): | ||
| + | return self._identity_instrument_firmware_revision | ||
| + | self._load_id_string() | ||
| + | return self._identity_instrument_firmware_revision | ||
| + | | ||
| + | def _utility_disable(self): | ||
| + | pass | ||
| + | | ||
| + | def _utility_error_query(self): | ||
| + | error_code = 0 | ||
| + | error_message = "No error" | ||
| + | if not self._driver_operation_simulate: | ||
| + | error_code, error_message = self._ask(": | ||
| + | error_code = int(error_code) | ||
| + | error_message = error_message.strip(' | ||
| + | return (error_code, | ||
| + | | ||
| + | def _utility_lock_object(self): | ||
| + | pass | ||
| + | | ||
| + | def _utility_reset(self): | ||
| + | if not self._driver_operation_simulate: | ||
| + | self._write(" | ||
| + | self.driver_operation.invalidate_all_attributes() | ||
| + | | ||
| + | def _utility_reset_with_defaults(self): | ||
| + | self._utility_reset() | ||
| + | | ||
| + | def _utility_self_test(self): | ||
| + | code = 0 | ||
| + | message = "Self test passed" | ||
| + | if not self._driver_operation_simulate: | ||
| + | code = int(self._ask(" | ||
| + | if code != 0: | ||
| + | message = "Self test failed" | ||
| + | return (code, message) | ||
| + | | ||
| + | def _utility_unlock_object(self): | ||
| + | pass | ||
| + | | ||
| + | def _init_channels(self): | ||
| + | super(agilent7000, | ||
| + | | ||
| + | self._channel_name = list() | ||
| + | self._channel_label = list() | ||
| + | # init per-channel instrument-specific variables | ||
| + | | ||
| + | for i in range(self._channel_count): | ||
| + | self._channel_name.append(" | ||
| + | self._channel_label.append(" | ||
| + | # init per-channel instrument-specific variables | ||
| + | | ||
| + | self.channels._set_list(self._channel_name) | ||
| + | | ||
| + | def _get_acquisition_start_time(self): | ||
| + | pos = 0 | ||
| + | if not self._driver_operation_simulate and not self._get_cache_valid(): | ||
| + | pos = float(self._ask(": | ||
| + | self._set_cache_valid() | ||
| + | self._acquisition_start_time = pos - self._get_acquisition_time_per_record() * 5 / 10 | ||
| + | return self._acquisition_start_time | ||
| + | | ||
| + | def _set_acquisition_start_time(self, | ||
| + | value = float(value) | ||
| + | value = value + self._get_acquisition_time_per_record() * 5 / 10 | ||
| + | if not self._driver_operation_simulate: | ||
| + | self._write(": | ||
| + | self._acquisition_start_time = value | ||
| + | self._set_cache_valid() | ||
| + | | ||
| + | # more definitions | ||
| + | | ||
| + | </ | ||
| + | |||
| + | |||