diff --git a/secop_psi/trinamic.py b/secop_psi/trinamic.py index 5ae65a7..3bfbaea 100644 --- a/secop_psi/trinamic.py +++ b/secop_psi/trinamic.py @@ -125,8 +125,9 @@ class Motor(PersistentMixin, HasIodev, Drivable): # fast_pollfactor = 0.001 # poll as fast as possible when busy fast_pollfactor = 0.05 _started = 0 - _calcTimeout = True + _calc_timeout = True _need_reset = None + _last_change = 0 def comm(self, cmd, adr, value=0, bank=0): """set or get a parameter @@ -137,8 +138,8 @@ class Motor(PersistentMixin, HasIodev, Drivable): :param value: if given, the parameter is written, else it is returned :return: the returned value """ - if self._calcTimeout: - self._calcTimeout = False + if self._calc_timeout: + self._calc_timeout = False baudrate = getattr(self._iodev._conn.connection, 'baudrate', None) if baudrate: if baudrate not in BAUDRATES: @@ -179,13 +180,17 @@ class Motor(PersistentMixin, HasIodev, Drivable): pobj = self.parameters[pname] scale = pobj.scale rawvalue = round(value / scale) - self.comm(SET_AXIS_PAR, pobj.adr, rawvalue, **kwds) - if check: - result = self.comm(GET_AXIS_PAR, pobj.adr, **kwds) - if result != rawvalue: - raise HardwareError('result does not match %d != %d' % (result, rawvalue)) - value = result * scale - return value + for itry in range(2): + self.comm(SET_AXIS_PAR, pobj.adr, rawvalue, **kwds) + if check: + result = self.comm(GET_AXIS_PAR, pobj.adr, **kwds) + if result != rawvalue: + self.log.warning('result for %s does not match %d != %d, try again', pname, result, rawvalue) + continue + value = result * scale + return value + else: + raise HardwareError('result for %s does not match %d != %d' % (pname, result, rawvalue)) def startModule(self, started_callback): # get encoder value from motor. at this stage self.encoder contains the persistent value @@ -251,8 +256,12 @@ class Motor(PersistentMixin, HasIodev, Drivable): self.log.error('encoder (%.2f) does not match internal pos (%.2f)', self.encoder, self.steppos) return self.Status.ERROR, 'encoder does not match internal pos' return self.status - if oldpos != self.steppos or not (self.read_target_reached() or self.read_move_status() - or self.read_error_bits()): + now = self.parameters['steppos'].timestamp + if self.steppos != oldpos: + self._last_change = now + return self.Status.BUSY, 'moving' + if now < self._last_change + 0.2 and not (self.read_target_reached() or self.read_move_status() + or self.read_error_bits()): return self.Status.BUSY, 'moving' diff = self.target - self.encoder if abs(diff) <= self.tolerance: @@ -275,7 +284,7 @@ class Motor(PersistentMixin, HasIodev, Drivable): self._need_reset = True self.status = self.Status.ERROR, 'encoder does not match internal pos' raise HardwareError('need reset (encoder does not match internal pos)') - self.set('steppos', self.encoder - self.zero) + self.set('steppos', self.encoder - self.zero, check=False) self._started = time.time() self.log.debug('move to %.1f', target) self.comm(MOVE, 0, (target - self.zero) / ANGLE_SCALE) @@ -357,7 +366,8 @@ class Motor(PersistentMixin, HasIodev, Drivable): @Command(FloatRange()) def set_zero(self, value): - self.write_zero(value - self.read_value()) + raw = self.read_value() - self.zero + self.write_zero(value - raw) def read_baudrate(self): return self.comm(GET_GLOB_PAR, 65)