+# Copyright (C) 2009-2011 W. Trevor King <wking@drexel.edu>
+#
+# This file is part of pyafm.
+#
+# pyafm is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# pyafm is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyafm. If not, see <http://www.gnu.org/licenses/>.
+
"""Tools for controlling atomic force microscopes.
Provides control of AFM postition using both short-range (piezo) and
module only contains methods that require the capabilities of both.
"""
-import logging as _logging
-
-from pypiezo.base import convert_volts_to_bits as _convert_volts_to_bits
-from pypiezo.base import convert_meters_to_bits as _convert_meters_to_bits
-from pypiezo.base import convert_bits_to_meters as _convert_bits_to_meters
-from pypiezo.surface import SurfaceError as _SurfaceError
-from pypiezo.surface import FlatFit as _FlatFit
-
-
-__version__ = '0.1'
-
-
-LOG = _logging.getLogger('pyafm')
-"pyafm logger"
-
-LOG.setLevel(_logging.DEBUG)
-h = _logging.StreamHandler()
-f = _logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
-h.setFormatter(f)
-LOG.addHandler(h)
-del h, f
+from pycomedi.device import Device
+from pycomedi.subdevice import StreamingSubdevice
+from pycomedi.channel import AnalogChannel, DigitalChannel
+from pycomedi.constant import AREF, IO_DIRECTION, SUBDEVICE_TYPE, UNIT
+from pypiezo.afm import AFMPiezo
+from pypiezo.base import PiezoAxis, InputChannel
+from pypiezo.config import HDF5_ChannelConfig, HDF5_AxisConfig, pprint_HDF5
+from stepper import Stepper
+from pyafm import AFM
+from pypid.controller import Controller
+from pypid.backend import get_backend
+from . import LOG as _LOG
class AFM (object):
moving the zpiezo) until deflection voltage is greater than
`setpoint`.
"""
- LOG.info('moving to %g onto the surface' % depth)
+ _LOG.info('moving to %g onto the surface' % depth)
stepper_tolerance = 2*self.stepper.step_size
zero = _convert_volts_to_bits(axis.axis_channel_config, 0)
target_def = _convert_volts_to_bits(axis.axis_channel_config, setpoint)
- LOG.debug('zero the %s piezo output' % self.axis_name)
+ _LOG.debug('zero the %s piezo output' % self.axis_name)
self.piezo.jump(axis_name=self.axis_name, position=zero)
- LOG.debug("see if we're starting near the surface")
+ _LOG.debug("see if we're starting near the surface")
try:
pos = self.piezo.get_surface_position(
axis_name=self.axis_name, max_deflection=target_def)
except _FlatFit, e:
- LOG.info(e)
+ _LOG.info(e)
pos = self._stepper_approach_again(
target_deflection=target_def, far=far)
except _SurfaceError, e:
- LOG.info(e)
+ _LOG.info(e)
pos = self._stepper_approach_again(
target_deflection=target_def, far=far)
pos_m = _convert_bits_to_meters(
axis.axis_channel_config, axis.axis_config, pos)
- LOG.debug('located surface at stepper %d, piezo %d (%g m)'
+ _LOG.debug('located surface at stepper %d, piezo %d (%g m)'
% (self.stepper.position, pos, pos_m))
- LOG.debug('fine tune the stepper position')
+ _LOG.debug('fine tune the stepper position')
while pos_m < -stepper_tolerance: # step back if we need to
- LOG.debug('step back')
+ _LOG.debug('step back')
self.stepper.step_relative(-1, backlash_safe=True)
try:
pos = self.piezo.get_surface_position(
axis_name=self.axis_name, max_deflection=target_def)
except _FlatFit, e:
- LOG.debug(e)
+ _LOG.debug(e)
continue
pos_m = _convert_bits_to_meters(
axis.axis_channel_config, axis.axis_config, pos)
- LOG.debug('located surface at stepper %d, piezo %d (%g m)'
+ _LOG.debug('located surface at stepper %d, piezo %d (%g m)'
% (self.stepper.position, pos, pos_m))
while pos_m > stepper_tolerance: # step forward if we need to
- LOG.debug('step forward')
+ _LOG.debug('step forward')
self.stepper.step_relative(1)
try:
pos = self.piezo.get_surface_position(
axis_name=self.axis_name, max_deflection=target_def)
except _FlatFit, e:
- LOG.debug(e)
+ _LOG.debug(e)
continue
pos_m = _convert_bits_to_meters(
axis.axis_channel_config, axis.axis_config, pos)
- LOG.debug('located surface at stepper %d, piezo %d (%g m)'
+ _LOG.debug('located surface at stepper %d, piezo %d (%g m)'
% (self.stepper.position, pos, pos_m))
- LOG.debug('adjust the %s piezo to place us just onto the surface'
+ _LOG.debug('adjust the %s piezo to place us just onto the surface'
% self.axis_name)
target_m = pos_m + depth
target = _convert_meters_to_bits(
axis.axis_channel_config, axis.axis_config, target_m)
self.piezo.jump(self.axis_name, target)
- LOG.debug(
+ _LOG.debug(
'positioned %g m into the surface at stepper %d, piezo %d (%g m)'
% (depth, self.stepper.position, target, target_m))
def _stepper_approach_again(self, target_deflection, far):
- LOG.info('back off %d half steps and approach until deflection > %g'
+ _LOG.info('back off %d half steps and approach until deflection > %g'
% (far, target_deflection))
# back away
self.stepper.step_relative(-far, backlash_safe=True)
cd = self.piezo.read_deflection() # cd = current deflection in bits
- LOG.debug('single stepping approach')
+ _LOG.debug('single stepping approach')
while cd < target_deflection:
- LOG.debug('deflection %g < setpoint %g. step closer'
+ _LOG.debug('deflection %g < setpoint %g. step closer'
% (cd, target_deflection))
self.stepper.single_step(1) # step in
cd = self.piezo.read_deflection()
for i in range(2*max(1, self.stepper.backlash)):
- LOG.debug(
+ _LOG.debug(
'additional surface location attempt (stepping backwards)')
try:
pos = self.piezo.get_surface_position(
axis_name=self.axis_name, max_deflection=target_deflection)
return pos
except _SurfaceError, e:
- LOG.info(e)
+ _LOG.info(e)
self.stepper.single_step(-1) # step out
- LOG.debug('giving up on finding the surface')
- LOG.warn(e)
+ _LOG.debug('giving up on finding the surface')
+ _LOG.warn(e)
raise e