Use stepper.single_step instead of stepper.step_relative in AFM methods.
[pyafm.git] / pyafm / afm.py
index 92c0679071b7dc8add4a7aca27088d0cc634f27b..fdacc81a38931aa39f9267608fafd195c22359a6 100644 (file)
@@ -68,7 +68,7 @@ class AFM (object):
 
         Uses `.piezo.get_surface_position()` to pinpoint the position
         of the surface.  Adjusts the stepper position as required via
-        `.stepper.step_relative()` to get within
+        `.stepper.single_step()` to get within
         `2*.stepper.step_size` meters of the surface.  Then adjusts
         the piezo to place the cantilever `depth` meters onto the
         surface.  Negative `depth`\s place the tip off the surface
@@ -83,9 +83,11 @@ class AFM (object):
         stepper_tolerance = 2*self.stepper.step_size
 
         axis = self.piezo.axis_by_name(self.axis_name)
+        def_config = self.piezo.config.select_config('inputs', 'deflection')
 
         zero = _convert_volts_to_bits(axis.config['channel'], 0)
-        target_def = _convert_volts_to_bits(axis.config['channel'], setpoint)
+        target_def = _convert_volts_to_bits(def_config, setpoint)
+        self._check_target_deflection(deflection=target_def)
 
         _LOG.debug('zero the %s piezo output' % self.axis_name)
         self.piezo.jump(axis_name=self.axis_name, position=zero)
@@ -113,7 +115,7 @@ class AFM (object):
         _LOG.debug('fine tune the stepper position')
         while pos_m < -stepper_tolerance:  # step back if we need to
             _LOG.debug('step back')
-            self.stepper.step_relative(-1, backlash_safe=True)
+            self.stepper.single_step(-1)
             try:
                 pos = self.piezo.get_surface_position(
                     axis_name=self.axis_name, max_deflection=target_def,
@@ -126,7 +128,7 @@ class AFM (object):
                       % (self.stepper.position, pos, pos_m))
         while pos_m > stepper_tolerance:  # step forward if we need to
             _LOG.debug('step forward')
-            self.stepper.step_relative(1)
+            self.stepper.single_step(1)
             try:
                 pos = self.piezo.get_surface_position(
                     axis_name=self.axis_name, max_deflection=target_def,
@@ -148,6 +150,19 @@ class AFM (object):
             'positioned %g m into the surface at stepper %d, piezo %d (%g m)'
             % (depth, self.stepper.position, target, target_m))
 
+    def _check_target_deflection(self, deflection):
+        defc = self.piezo._deflection_channel()
+        max_def = defc.get_maxdata()
+        if deflection > max_def:
+            _LOG.error(('requested setpoint ({} bits) is larger than the '
+                        'maximum deflection value of {} bits'
+                        ).format(deflection, max_def))
+            raise ValueError(deflection)
+        elif deflection < 0:
+            _LOG.error(('requested setpoint ({} bits) is less than the '
+                        'minimum deflection value of 0 bits'
+                        ).format(deflection))
+            raise ValueError(deflection)
 
     def _stepper_approach_again(self, target_deflection, min_slope_ratio, far):
         _LOG.info('back off %d half steps and approach until deflection > %g'
@@ -161,7 +176,7 @@ class AFM (object):
             try:
                 pos = self.piezo.get_surface_position(
                     axis_name=self.axis_name, max_deflection=target_deflection,
-                    min_slope_position=min_slope_postion)
+                    min_slope_ratio=min_slope_ratio)
                 return pos
             except _SurfaceError, e:
                 _LOG.info(e)
@@ -173,6 +188,7 @@ class AFM (object):
     def stepper_approach(self, target_deflection):
         _LOG.info('approach with stepper until deflection > {}'.format(
                 target_deflection))
+        self._check_target_deflection(deflection=target_deflection)
         cd = self.piezo.read_deflection()  # cd = current deflection in bits
         _LOG.debug('single stepping approach')
         while cd < target_deflection: