adxl345: Add new start_internal_client() function and use in callers
Introduce a new start_internal_client() function and change all client code to use that instead of manually calling start_measurements() and finish_measurements(). Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
8cfaed441d
commit
d87f7a77c3
|
@ -28,23 +28,28 @@ SCALE = 0.0039 * FREEFALL_ACCEL # 3.9mg/LSB * Earth gravity in mm/s**2
|
||||||
Accel_Measurement = collections.namedtuple(
|
Accel_Measurement = collections.namedtuple(
|
||||||
'Accel_Measurement', ('time', 'accel_x', 'accel_y', 'accel_z'))
|
'Accel_Measurement', ('time', 'accel_x', 'accel_y', 'accel_z'))
|
||||||
|
|
||||||
# Sample results
|
# Helper class to obtain measurements
|
||||||
class ADXL345Results:
|
class ADXL345QueryHelper:
|
||||||
def __init__(self):
|
def __init__(self, printer, chip, axes_map):
|
||||||
|
self.printer = printer
|
||||||
|
self.chip = chip
|
||||||
|
self.axes_map = axes_map
|
||||||
self.raw_samples = None
|
self.raw_samples = None
|
||||||
self.samples = []
|
self.samples = []
|
||||||
self.drops = self.overflows = 0
|
self.drops = self.overflows = 0
|
||||||
self.time_per_sample = self.start_range = self.end_range = 0.
|
self.time_per_sample = self.start_range = self.end_range = 0.
|
||||||
|
def finish_measurements(self):
|
||||||
|
self.chip._finish_measurements()
|
||||||
|
self._setup_data(*self.chip.final_results) # XXX
|
||||||
def get_stats(self):
|
def get_stats(self):
|
||||||
return ("drops=%d,overflows=%d"
|
return ("drops=%d,overflows=%d"
|
||||||
",time_per_sample=%.9f,start_range=%.6f,end_range=%.6f"
|
",time_per_sample=%.9f,start_range=%.6f,end_range=%.6f"
|
||||||
% (self.drops, self.overflows,
|
% (self.drops, self.overflows,
|
||||||
self.time_per_sample, self.start_range, self.end_range))
|
self.time_per_sample, self.start_range, self.end_range))
|
||||||
def setup_data(self, axes_map, raw_samples, end_sequence, overflows,
|
def _setup_data(self, raw_samples, end_sequence, overflows,
|
||||||
start1_time, start2_time, end1_time, end2_time):
|
start1_time, start2_time, end1_time, end2_time):
|
||||||
if not raw_samples or not end_sequence:
|
if not raw_samples or not end_sequence:
|
||||||
return
|
return
|
||||||
self.axes_map = axes_map
|
|
||||||
self.raw_samples = raw_samples
|
self.raw_samples = raw_samples
|
||||||
self.overflows = overflows
|
self.overflows = overflows
|
||||||
self.start2_time = start2_time
|
self.start2_time = start2_time
|
||||||
|
@ -101,6 +106,7 @@ class ADXLCommandHelper:
|
||||||
def __init__(self, config, chip):
|
def __init__(self, config, chip):
|
||||||
self.printer = config.get_printer()
|
self.printer = config.get_printer()
|
||||||
self.chip = chip
|
self.chip = chip
|
||||||
|
self.bg_client = None
|
||||||
self.name = "default"
|
self.name = "default"
|
||||||
if len(config.get_name().split()) > 1:
|
if len(config.get_name().split()) > 1:
|
||||||
self.name = config.get_name().split()[1]
|
self.name = config.get_name().split()[1]
|
||||||
|
@ -126,30 +132,34 @@ class ADXLCommandHelper:
|
||||||
def cmd_ACCELEROMETER_MEASURE(self, gcmd):
|
def cmd_ACCELEROMETER_MEASURE(self, gcmd):
|
||||||
if not self.chip.is_measuring():
|
if not self.chip.is_measuring():
|
||||||
# Start measurements
|
# Start measurements
|
||||||
self.chip.start_measurements()
|
self.bg_client = self.chip.start_internal_client()
|
||||||
gcmd.respond_info("adxl345 measurements started")
|
gcmd.respond_info("adxl345 measurements started")
|
||||||
return
|
return
|
||||||
|
if self.bg_client is None:
|
||||||
|
raise gcmd.error("adxl345 measurements in progress")
|
||||||
# End measurements
|
# End measurements
|
||||||
name = gcmd.get("NAME", time.strftime("%Y%m%d_%H%M%S"))
|
name = gcmd.get("NAME", time.strftime("%Y%m%d_%H%M%S"))
|
||||||
if not name.replace('-', '').replace('_', '').isalnum():
|
if not name.replace('-', '').replace('_', '').isalnum():
|
||||||
raise gcmd.error("Invalid adxl345 NAME parameter")
|
raise gcmd.error("Invalid adxl345 NAME parameter")
|
||||||
res = self.chip.finish_measurements()
|
bg_client = self.bg_client
|
||||||
|
self.bg_client = None
|
||||||
|
bg_client.finish_measurements()
|
||||||
# Write data to file
|
# Write data to file
|
||||||
if self.name == "default":
|
if self.name == "default":
|
||||||
filename = "/tmp/adxl345-%s.csv" % (name,)
|
filename = "/tmp/adxl345-%s.csv" % (name,)
|
||||||
else:
|
else:
|
||||||
filename = "/tmp/adxl345-%s-%s.csv" % (self.name, name,)
|
filename = "/tmp/adxl345-%s-%s.csv" % (self.name, name,)
|
||||||
res.write_to_file(filename)
|
bg_client.write_to_file(filename)
|
||||||
gcmd.respond_info("Writing raw accelerometer data to %s file"
|
gcmd.respond_info("Writing raw accelerometer data to %s file"
|
||||||
% (filename,))
|
% (filename,))
|
||||||
cmd_ACCELEROMETER_QUERY_help = "Query accelerometer for the current values"
|
cmd_ACCELEROMETER_QUERY_help = "Query accelerometer for the current values"
|
||||||
def cmd_ACCELEROMETER_QUERY(self, gcmd):
|
def cmd_ACCELEROMETER_QUERY(self, gcmd):
|
||||||
if self.chip.is_measuring():
|
if self.chip.is_measuring():
|
||||||
raise gcmd.error("adxl345 measurements in progress")
|
raise gcmd.error("adxl345 measurements in progress")
|
||||||
self.chip.start_measurements()
|
aclient = self.chip.start_internal_client()
|
||||||
self.printer.lookup_object('toolhead').dwell(1.)
|
self.printer.lookup_object('toolhead').dwell(1.)
|
||||||
result = self.chip.finish_measurements()
|
aclient.finish_measurements()
|
||||||
values = result.decode_samples()
|
values = aclient.decode_samples()
|
||||||
if not values:
|
if not values:
|
||||||
raise gcmd.error("No adxl345 measurements found")
|
raise gcmd.error("No adxl345 measurements found")
|
||||||
_, accel_x, accel_y, accel_z = values[-1]
|
_, accel_x, accel_y, accel_z = values[-1]
|
||||||
|
@ -247,7 +257,7 @@ class ADXL345:
|
||||||
reg, val, stored_val))
|
reg, val, stored_val))
|
||||||
def is_measuring(self):
|
def is_measuring(self):
|
||||||
return self.query_rate > 0
|
return self.query_rate > 0
|
||||||
def start_measurements(self):
|
def _start_measurements(self):
|
||||||
if self.is_measuring():
|
if self.is_measuring():
|
||||||
return
|
return
|
||||||
# In case of miswiring, testing ADXL345 device ID prevents treating
|
# In case of miswiring, testing ADXL345 device ID prevents treating
|
||||||
|
@ -277,9 +287,10 @@ class ADXL345:
|
||||||
self.query_rate = self.data_rate
|
self.query_rate = self.data_rate
|
||||||
self.query_adxl345_cmd.send([self.oid, reqclock, rest_ticks],
|
self.query_adxl345_cmd.send([self.oid, reqclock, rest_ticks],
|
||||||
reqclock=reqclock)
|
reqclock=reqclock)
|
||||||
def finish_measurements(self):
|
logging.info("ADXL345 starting measurements")
|
||||||
|
def _finish_measurements(self):
|
||||||
if not self.is_measuring():
|
if not self.is_measuring():
|
||||||
return ADXL345Results()
|
return
|
||||||
# Halt bulk reading
|
# Halt bulk reading
|
||||||
print_time = self.printer.lookup_object('toolhead').get_last_move_time()
|
print_time = self.printer.lookup_object('toolhead').get_last_move_time()
|
||||||
clock = self.mcu.print_time_to_clock(print_time)
|
clock = self.mcu.print_time_to_clock(print_time)
|
||||||
|
@ -294,13 +305,16 @@ class ADXL345:
|
||||||
end2_time = self._clock_to_print_time(params['end2_clock'])
|
end2_time = self._clock_to_print_time(params['end2_clock'])
|
||||||
end_sequence = self._convert_sequence(params['sequence'])
|
end_sequence = self._convert_sequence(params['sequence'])
|
||||||
overflows = params['limit_count']
|
overflows = params['limit_count']
|
||||||
res = ADXL345Results()
|
logging.info("ADXL345 finished measurements")
|
||||||
res.setup_data(self.axes_map, raw_samples, end_sequence, overflows,
|
self.final_results = (raw_samples, end_sequence, overflows,
|
||||||
self.samples_start1, self.samples_start2,
|
self.samples_start1, self.samples_start2,
|
||||||
end1_time, end2_time)
|
end1_time, end2_time) # XXX
|
||||||
logging.info("ADXL345 finished %d measurements: %s",
|
def start_internal_client(self):
|
||||||
res.total_count, res.get_stats())
|
if self.is_measuring():
|
||||||
return res
|
raise self.printer.command_error(
|
||||||
|
"ADXL345 measurement already in progress")
|
||||||
|
self._start_measurements()
|
||||||
|
return ADXL345QueryHelper(self.printer, self, self.axes_map)
|
||||||
|
|
||||||
def load_config(config):
|
def load_config(config):
|
||||||
return ADXL345(config)
|
return ADXL345(config)
|
||||||
|
|
|
@ -164,26 +164,25 @@ class ResonanceTester:
|
||||||
if len(axes) > 1:
|
if len(axes) > 1:
|
||||||
gcmd.respond_info("Testing axis %s" % axis.get_name())
|
gcmd.respond_info("Testing axis %s" % axis.get_name())
|
||||||
|
|
||||||
for chip_axis, chip in self.accel_chips:
|
|
||||||
if axis.matches(chip_axis):
|
|
||||||
chip.start_measurements()
|
|
||||||
# Generate moves
|
|
||||||
self.test.run_test(axis, gcmd)
|
|
||||||
raw_values = []
|
raw_values = []
|
||||||
for chip_axis, chip in self.accel_chips:
|
for chip_axis, chip in self.accel_chips:
|
||||||
if axis.matches(chip_axis):
|
if axis.matches(chip_axis):
|
||||||
results = chip.finish_measurements()
|
aclient = chip.start_internal_client()
|
||||||
if raw_name_suffix is not None:
|
raw_values.append((chip_axis, aclient))
|
||||||
raw_name = self.get_filename(
|
# Generate moves
|
||||||
'raw_data', raw_name_suffix, axis,
|
self.test.run_test(axis, gcmd)
|
||||||
point if len(test_points) > 1 else None)
|
for chip_axis, aclient in raw_values:
|
||||||
results.write_to_file(raw_name)
|
aclient.finish_measurements()
|
||||||
gcmd.respond_info(
|
if raw_name_suffix is not None:
|
||||||
"Writing raw accelerometer data to "
|
raw_name = self.get_filename(
|
||||||
"%s file" % (raw_name,))
|
'raw_data', raw_name_suffix, axis,
|
||||||
raw_values.append((chip_axis, results))
|
point if len(test_points) > 1 else None)
|
||||||
gcmd.respond_info("%s-axis accelerometer stats: %s" % (
|
aclient.write_to_file(raw_name)
|
||||||
chip_axis, results.get_stats(),))
|
gcmd.respond_info(
|
||||||
|
"Writing raw accelerometer data to "
|
||||||
|
"%s file" % (raw_name,))
|
||||||
|
gcmd.respond_info("%s-axis accelerometer stats: %s" % (
|
||||||
|
chip_axis, aclient.get_stats(),))
|
||||||
if helper is None:
|
if helper is None:
|
||||||
continue
|
continue
|
||||||
for chip_axis, chip_values in raw_values:
|
for chip_axis, chip_values in raw_values:
|
||||||
|
@ -281,14 +280,14 @@ class ResonanceTester:
|
||||||
"Measures noise of all enabled accelerometer chips")
|
"Measures noise of all enabled accelerometer chips")
|
||||||
def cmd_MEASURE_AXES_NOISE(self, gcmd):
|
def cmd_MEASURE_AXES_NOISE(self, gcmd):
|
||||||
meas_time = gcmd.get_float("MEAS_TIME", 2.)
|
meas_time = gcmd.get_float("MEAS_TIME", 2.)
|
||||||
for _, chip in self.accel_chips:
|
raw_values = [(chip_axis, chip.start_internal_client())
|
||||||
chip.start_measurements()
|
|
||||||
self.printer.lookup_object('toolhead').dwell(meas_time)
|
|
||||||
raw_values = [(chip_axis, chip.finish_measurements())
|
|
||||||
for chip_axis, chip in self.accel_chips]
|
for chip_axis, chip in self.accel_chips]
|
||||||
|
self.printer.lookup_object('toolhead').dwell(meas_time)
|
||||||
|
for chip_axis, aclient in raw_values:
|
||||||
|
aclient.finish_measurements()
|
||||||
helper = shaper_calibrate.ShaperCalibrate(self.printer)
|
helper = shaper_calibrate.ShaperCalibrate(self.printer)
|
||||||
for chip_axis, raw_data in raw_values:
|
for chip_axis, aclient in raw_values:
|
||||||
data = helper.process_accelerometer_data(raw_data)
|
data = helper.process_accelerometer_data(aclient)
|
||||||
vx = data.psd_x.mean()
|
vx = data.psd_x.mean()
|
||||||
vy = data.psd_y.mean()
|
vy = data.psd_y.mean()
|
||||||
vz = data.psd_z.mean()
|
vz = data.psd_z.mean()
|
||||||
|
|
Loading…
Reference in New Issue