diff --git a/klippy/extras/adxl345.py b/klippy/extras/adxl345.py index e331e33d..ad973698 100644 --- a/klippy/extras/adxl345.py +++ b/klippy/extras/adxl345.py @@ -36,14 +36,37 @@ class ADXL345QueryHelper: self.cconn = cconn print_time = printer.lookup_object('toolhead').get_last_move_time() self.request_start_time = self.request_end_time = print_time - self.samples = [] + self.samples = self.raw_samples = [] def finish_measurements(self): toolhead = self.printer.lookup_object('toolhead') self.request_end_time = toolhead.get_last_move_time() toolhead.wait_moves() self.cconn.finalize() - def decode_samples(self): + def _get_raw_samples(self): raw_samples = self.cconn.get_messages() + if raw_samples: + self.raw_samples = raw_samples + return self.raw_samples + def has_valid_samples(self): + raw_samples = self._get_raw_samples() + for msg in raw_samples: + data = msg['params']['data'] + first_sample_time = data[0][0] + last_sample_time = data[-1][0] + if (first_sample_time > self.request_end_time + or last_sample_time < self.request_start_time): + continue + # The time intervals [first_sample_time, last_sample_time] + # and [request_start_time, request_end_time] have non-zero + # intersection. It is still theoretically possible that none + # of the samples from raw_samples fall into the time interval + # [request_start_time, request_end_time] if it is too narrow + # or on very heavy data losses. In practice, that interval + # is at least 1 second, so this possibility is negligible. + return True + return False + def get_samples(self): + raw_samples = self._get_raw_samples() if not raw_samples: return self.samples total = sum([len(m['params']['data']) for m in raw_samples]) @@ -68,7 +91,7 @@ class ADXL345QueryHelper: pass f = open(filename, "w") f.write("#time,accel_x,accel_y,accel_z\n") - samples = self.samples or self.decode_samples() + samples = self.samples or self.get_samples() for t, accel_x, accel_y, accel_z in samples: f.write("%.6f,%.6f,%.6f,%.6f\n" % ( t, accel_x, accel_y, accel_z)) @@ -129,7 +152,7 @@ class ADXLCommandHelper: aclient = self.chip.start_internal_client() self.printer.lookup_object('toolhead').dwell(1.) aclient.finish_measurements() - values = aclient.decode_samples() + values = aclient.get_samples() if not values: raise gcmd.error("No adxl345 measurements found") _, accel_x, accel_y, accel_z = values[-1] diff --git a/klippy/extras/resonance_tester.py b/klippy/extras/resonance_tester.py index f66e229c..00797156 100644 --- a/klippy/extras/resonance_tester.py +++ b/klippy/extras/resonance_tester.py @@ -183,12 +183,12 @@ class ResonanceTester: "%s file" % (raw_name,)) if helper is None: continue - for chip_axis, chip_values in raw_values: - if not chip_values: + for chip_axis, aclient in raw_values: + if not aclient.has_valid_samples(): raise gcmd.error( "%s-axis accelerometer measured no data" % ( chip_axis,)) - new_data = helper.process_accelerometer_data(chip_values) + new_data = helper.process_accelerometer_data(aclient) if calibration_data[axis] is None: calibration_data[axis] = new_data else: @@ -285,6 +285,9 @@ class ResonanceTester: aclient.finish_measurements() helper = shaper_calibrate.ShaperCalibrate(self.printer) for chip_axis, aclient in raw_values: + if not aclient.has_valid_samples(): + raise gcmd.error( + "%s-axis accelerometer measured no data" % (chip_axis,)) data = helper.process_accelerometer_data(aclient) vx = data.psd_x.mean() vy = data.psd_y.mean() diff --git a/klippy/extras/shaper_calibrate.py b/klippy/extras/shaper_calibrate.py index 3c6065de..cc0f0593 100644 --- a/klippy/extras/shaper_calibrate.py +++ b/klippy/extras/shaper_calibrate.py @@ -264,7 +264,10 @@ class ShaperCalibrate: if isinstance(raw_values, np.ndarray): data = raw_values else: - data = np.array(raw_values.decode_samples()) + samples = raw_values.get_samples() + if not samples: + return None + data = np.array(samples) N = data.shape[0] T = data[-1,0] - data[0,0]