trigger_analog: Store pre-generated 25hz lowpass filter (at 250sps)

Store the 12 constants needed for the common probe_eddy_current "tap"
filter in trigger_analog.py code.  This avoids requiring "tap" users
to have the scipy python package installed.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor
2026-04-04 20:32:11 -04:00
parent c8b2ef0c21
commit 22dbdf1029
2 changed files with 30 additions and 6 deletions

View File

@@ -116,12 +116,6 @@ Practically, it ensures that the Eddy's output data absolute value
change per second (velocity) is high enough - higher than the noise level,
and that upon collision it always decreases by at least this value.
Before setting it to any other value, it is necessary to install `scipy`:
```bash
~/klippy-env/bin/pip install scipy
```
The suggested calibration routine works as follows:
1. Home Z
2. Place the toolhead at the center of the bed.

View File

@@ -25,6 +25,33 @@ def to_fixed_32(value, frac_bits=0):
fixed_val = int(value * (2**frac_bits))
return assert_is_int32(fixed_val, frac_bits)
# Pre-generated SOS filters (avoid Scipy package for common installs)
GeneratedSOS = {
('lowpass', 10.0, 4): [
[0.004824343357716228, 0.009648686715432456, 0.004824343357716228,
1.0, -1.0485995763626117, 0.2961403575616696],
[1.0, 2.0, 1.0, 1.0, -1.3209134308194264, 0.6327387928852766],
],
}
# Helper tool to pre-generate SOS filters. Run with something like:
# python -c 'import trigger_analog as m; m.pre_gen_filt("lowpass", 250, 25, 4)'
def pre_gen_filt(btype, sps, freq, order):
global GeneratedSOS
GeneratedSOS = {}
# Create filter
df = DigitalFilter(sps, ImportError)
fs = df._butter(freq, btype, order)
# Write filter info to stdout
msgs = []
msgs.append(" ('%s', %s, %d): [" % (btype, repr(float(sps)/freq), order))
for data in fs:
coeffs = ", ".join([repr(float(c)) for c in data])
msgs.append(" [%s]," % coeffs,)
msgs.append(" ],")
msgs.append("")
import sys
sys.stdout.write("\n".join(msgs))
# Digital filter designer and container
class DigitalFilter:
@@ -59,6 +86,9 @@ class DigitalFilter:
return
self.initial_state = signal.sosfilt_zi(self.filter_sections)
def _butter(self, frequency, btype, order):
key = (btype, float(self.sample_frequency)/frequency, int(order))
if key in GeneratedSOS:
return GeneratedSOS[key]
signal = self.get_scipy_signal()
return signal.butter(order, Wn=frequency, btype=btype,
fs=self.sample_frequency, output='sos')