Skip to content

Conversation

@nefelim4ag
Copy link
Collaborator

@nefelim4ag nefelim4ag commented Jan 2, 2026

This is draft, I want to collect data from at least 3 BTT Eddys, I think.

BTT Eddy uses 12MHz clock in frequency.
Coil is oscillating at 3+MHz.
Which is out of spec for LDC1612 sensors.
Division of coil frequency seems to reduce output noise.

So, basic idea, if we divide the coil output frequency, for some reason it improves the noise level.
This will not work for other boards, where CLKIN is adequately sized to the coil frequency.

image

F_REF = 12MHz.
F_REF_DIV = 1
So, basically, coil oscillating with frequency ~3.2MHz F_COIL , F_IN_DIV = 2, makes it counts as 3.2/2 = 1.6MHz (in raw units) F_IN.
So, it now satisfy the requirements of F_IN < F_REF/4.

So, how I test it, and how I suggest to test it with the current code:

# I have safe_z_home so it is always happening at the same point
G28 Z
G90
G0 Z1
PROBE_EDDY_CURRENT_CALIBRATE CHIP=ldc1612
TESTZ Z=-1
ACCEPT

So, we home the machine, we do calibration from this zero, we record the noise output of calibration routine.

How to checkout locally:

git fetch origin pull/7160/head
git checkout FETCH_HEAD
sudo systemctl restart klipper

There are my outputs, did it 3 times to have an idea if it is calibration noise or divider works.

Before

// probe_eddy_current: noise 0.000271mm, MAD_Hz=17.278 in 2524 queries
// Total frequency range: 262263.422 Hz
// z_offset: 0.290 # noise 0.000206mm, MAD_Hz=31.267
// z_offset: 0.530 # noise 0.000298mm, MAD_Hz=38.789
// z_offset: 1.010 # noise 0.000284mm, MAD_Hz=26.850
// z_offset: 2.010 # noise 0.000284mm, MAD_Hz=14.996
// z_offset: 3.010 # noise 0.000276mm, MAD_Hz=8.805
---
// probe_eddy_current: noise 0.000310mm, MAD_Hz=19.340 in 2526 queries
// Total frequency range: 262828.928 Hz
// z_offset: 0.290 # noise 0.000246mm, MAD_Hz=37.583
// z_offset: 0.530 # noise 0.000328mm, MAD_Hz=42.794
// z_offset: 1.010 # noise 0.000303mm, MAD_Hz=28.814
// z_offset: 2.010 # noise 0.000173mm, MAD_Hz=9.130
// z_offset: 3.010 # noise 0.000295mm, MAD_Hz=9.413
---
// probe_eddy_current: noise 0.000360mm, MAD_Hz=23.504 in 2523 queries
// Total frequency range: 263002.453 Hz
// z_offset: 0.290 # noise 0.000361mm, MAD_Hz=55.518
// z_offset: 0.530 # noise 0.000391mm, MAD_Hz=50.987
// z_offset: 1.010 # noise 0.000302mm, MAD_Hz=28.760
// z_offset: 2.010 # noise 0.000345mm, MAD_Hz=18.081
// z_offset: 3.010 # noise 0.000400mm, MAD_Hz=12.792

After (I've forced divider = 2 for my Not BTT EDDY, there should be no significant difference):

// probe_eddy_current: noise 0.000264mm, MAD_Hz=17.100 in 2526 queries
// Total frequency range: 262119.984 Hz
// z_offset: 0.290 # noise 0.000416mm, MAD_Hz=63.815
// z_offset: 0.530 # noise 0.000309mm, MAD_Hz=40.362
// z_offset: 1.010 # noise 0.000425mm, MAD_Hz=40.562
// z_offset: 2.010 # noise 0.000234mm, MAD_Hz=12.216
// z_offset: 3.010 # noise 0.000316mm, MAD_Hz=10.106
---
// probe_eddy_current: noise 0.000303mm, MAD_Hz=19.882 in 2524 queries
// Total frequency range: 261504.979 Hz
// z_offset: 0.290 # noise 0.000225mm, MAD_Hz=34.461
// z_offset: 0.530 # noise 0.000347mm, MAD_Hz=45.132
// z_offset: 1.010 # noise 0.000416mm, MAD_Hz=39.482
// z_offset: 2.010 # noise 0.000294mm, MAD_Hz=15.349
// z_offset: 3.010 # noise 0.000147mm, MAD_Hz=4.693
---
// probe_eddy_current: noise 0.000303mm, MAD_Hz=20.105 in 2526 queries
// Total frequency range: 263790.872 Hz
// z_offset: 0.290 # noise 0.000342mm, MAD_Hz=52.586
// z_offset: 0.530 # noise 0.000353mm, MAD_Hz=46.305
// z_offset: 1.010 # noise 0.000318mm, MAD_Hz=30.391
// z_offset: 2.010 # noise 0.000251mm, MAD_Hz=13.282
// z_offset: 3.010 # noise 0.000432mm, MAD_Hz=13.797

So, for me it doesn't work, maybe even make the output a little bit noisier.

I would appreciate any data from the BTT Eddy sensors.

Thanks,
-Timofey

@KevinOConnor
Copy link
Collaborator

master (e60fe3d):

g28
g1 z10 x60 y60
g1 z1
PROBE_EDDY_CURRENT_CALIBRATE CHIP=eddy
TESTZ Z=-1
ACCEPT

probe_eddy_current: noise 0.003082mm, MAD_Hz=49.630 in 2523 queries
Total frequency range: 90151.400 Hz
z_offset: 0.250 # noise 0.000728mm, MAD_Hz=36.174
z_offset: 0.530 # noise 0.001581mm, MAD_Hz=62.191
z_offset: 1.010 # noise 0.002133mm, MAD_Hz=68.672
z_offset: 2.010 # noise 0.000982mm, MAD_Hz=21.452
z_offset: 3.010 # noise 0.007244mm, MAD_Hz=84.394

save_config: set [probe_eddy_current eddy] calibrate = 
0.050000:3313688.192,0.090000:3311696.693,0.130000:3309880.233,
0.170000:3308126.711,0.210000:3306369.290,0.250000:3304380.512,
0.290000:3302600.468,0.330000:3300949.085,0.370000:3299281.930,
0.410000:3297409.285,0.450000:3295723.509,0.490000:3294130.490,
0.530000:3292557.469,0.570000:3290891.905,0.610000:3289329.130,
0.650000:3287768.310,0.690000:3286231.308,0.730000:3284589.343,
0.770000:3283109.166,0.810000:3281692.954,0.850000:3280285.732,
0.890000:3278750.043,0.930000:3277406.538,0.970000:3276094.866,
1.010000:3274806.835,1.050000:3273385.143,1.090000:3272153.501,
1.130000:3270887.767,1.170000:3269716.616,1.210000:3268437.211,
1.250000:3267208.729,1.290000:3266061.348,1.330000:3264994.074,
1.370000:3263826.163,1.410000:3262768.732,1.450000:3261706.157,
1.490000:3260724.138,1.530000:3259609.827,1.570000:3258592.817,
1.610000:3257630.893,1.650000:3256691.469,1.690000:3255742.114,
1.730000:3254849.973,1.770000:3253919.417,1.810000:3253073.655,
1.850000:3252144.438,1.890000:3251323.843,1.930000:3250503.234,
1.970000:3249673.685,2.010000:3248799.825,2.050000:3248034.566,
2.090000:3247286.400,2.130000:3246572.898,2.170000:3245818.831,
2.210000:3245105.148,2.250000:3244352.549,2.290000:3243700.374,
2.330000:3243008.330,2.370000:3242361.281,2.410000:3241673.983,
2.450000:3241055.585,2.490000:3240427.240,2.530000:3239843.568,
2.570000:3239227.619,2.610000:3238640.751,2.650000:3238037.107,
2.690000:3237510.576,2.730000:3236927.526,2.770000:3236395.322,
2.810000:3235859.973,2.850000:3235375.609,2.890000:3234822.029,
2.930000:3234348.687,2.970000:3233824.713,3.010000:3233358.672,
3.050000:3232859.521,3.090000:3232417.865,3.130000:3231932.768,
3.170000:3231488.439,3.210000:3231049.672,3.250000:3230646.320,
3.290000:3230210.448,3.330000:3229804.791,3.370000:3229373.744,
3.410000:3228966.708,3.450000:3228578.569,3.490000:3228207.697,
3.530000:3227847.437,3.570000:3227449.252,3.610000:3227085.718,
3.650000:3226728.904,3.690000:3226376.132,3.730000:3226046.029,
3.770000:3225694.061,3.810000:3225382.438,3.850000:3225045.113,
3.890000:3224727.285,3.930000:3224402.583,3.970000:3224102.524,
4.010000:3223803.041,4.050000:3223536.792

nefelim4ag-btt-eddy-reduce-noise (204eb8d):

g28
g1 z10 x60 y60
g1 z1
PROBE_EDDY_CURRENT_CALIBRATE CHIP=eddy
TESTZ Z=-1
ACCEPT

probe_eddy_current: noise 0.000642mm, MAD_Hz=11.314 in 2525 queries
Total frequency range: 89932.012 Hz
z_offset: 0.250 # noise 0.000225mm, MAD_Hz=11.161
z_offset: 0.530 # noise 0.000323mm, MAD_Hz=12.742
z_offset: 1.010 # noise 0.000435mm, MAD_Hz=14.105
z_offset: 2.010 # noise 0.000604mm, MAD_Hz=12.817
z_offset: 3.010 # noise 0.000783mm, MAD_Hz=9.230

save_config: set [probe_eddy_current eddy] calibrate = 
0.050000:3313389.638,0.090000:3311454.502,0.130000:3309648.732,
0.170000:3307933.642,0.210000:3306119.142,0.250000:3304137.901,
0.290000:3302389.119,0.330000:3300747.524,0.370000:3299092.662,
0.410000:3297201.483,0.450000:3295542.287,0.490000:3293938.744,
0.530000:3292360.203,0.570000:3290657.033,0.610000:3289081.492,
0.650000:3287510.226,0.690000:3285995.879,0.730000:3284358.054,
0.770000:3282912.512,0.810000:3281458.426,0.850000:3280059.325,
0.890000:3278551.036,0.930000:3277224.283,0.970000:3275908.298,
1.010000:3274611.554,1.050000:3273226.522,1.090000:3271987.485,
1.130000:3270740.722,1.170000:3269538.542,1.210000:3268242.080,
1.250000:3267071.353,1.290000:3265910.486,1.330000:3264856.610,
1.370000:3263700.696,1.410000:3262610.167,1.450000:3261518.437,
1.490000:3260550.463,1.530000:3259467.884,1.570000:3258488.127,
1.610000:3257496.968,1.650000:3256573.466,1.690000:3255597.053,
1.730000:3254686.561,1.770000:3253796.307,1.810000:3252938.225,
1.850000:3252027.605,1.890000:3251189.851,1.930000:3250346.890,
1.970000:3249567.783,2.010000:3248718.528,2.050000:3247949.116,
2.090000:3247189.872,2.130000:3246468.296,2.170000:3245715.165,
2.210000:3245015.165,2.250000:3244274.662,2.290000:3243623.907,
2.330000:3242927.749,2.370000:3242280.228,2.410000:3241592.960,
2.450000:3240971.160,2.490000:3240326.071,2.530000:3239740.216,
2.570000:3239119.227,2.610000:3238555.209,2.650000:3237959.865,
2.690000:3237425.190,2.730000:3236849.370,2.770000:3236330.473,
2.810000:3235773.075,2.850000:3235279.462,2.890000:3234762.318,
2.930000:3234277.900,2.970000:3233774.550,3.010000:3233303.300,
3.050000:3232802.753,3.090000:3232349.535,3.130000:3231877.674,
3.170000:3231453.495,3.210000:3231004.704,3.250000:3230584.005,
3.290000:3230152.495,3.330000:3229766.006,3.370000:3229342.032,
3.410000:3228936.153,3.450000:3228528.506,3.490000:3228161.488,
3.530000:3227780.625,3.570000:3227407.379,3.610000:3227022.643,
3.650000:3226669.253,3.690000:3226309.712,3.730000:3225948.690,
3.770000:3225636.070,3.810000:3225324.812,3.850000:3224996.481,
3.890000:3224676.240,3.930000:3224347.769,3.970000:3224058.852,
4.010000:3223750.827,4.050000:3223457.626

This is a test rig (the eddy sensor just ziptied to the side of the toolhead), so don't conclude anything serious from these results.

Cheers,
-Kevin

@KevinOConnor
Copy link
Collaborator

FWIW, the reduction on "noise" is repeatable in my test rig. I ran the test 3 times in a row with:

g1 z10 x60 y60
g1 z1
PROBE_EDDY_CURRENT_CALIBRATE CHIP=eddy
TESTZ Z=-1
ACCEPT

and got on nefelim4ag-btt-eddy-reduce-noise (204eb8d):

probe_eddy_current: noise 0.000609mm, MAD_Hz=10.487 in 2524 queries
Total frequency range: 90170.989 Hz
z_offset: 0.250 # noise 0.000190mm, MAD_Hz=9.545
z_offset: 0.530 # noise 0.000249mm, MAD_Hz=10.071
z_offset: 1.010 # noise 0.000412mm, MAD_Hz=13.128
z_offset: 2.010 # noise 0.000014mm, MAD_Hz=0.304
z_offset: 3.010 # noise 0.000736mm, MAD_Hz=8.676

probe_eddy_current: noise 0.000561mm, MAD_Hz=10.233 in 2525 queries
Total frequency range: 90164.437 Hz
z_offset: 0.250 # noise 0.000291mm, MAD_Hz=14.252
z_offset: 0.530 # noise 0.000201mm, MAD_Hz=7.876
z_offset: 1.010 # noise 0.000471mm, MAD_Hz=15.053
z_offset: 2.010 # noise 0.000211mm, MAD_Hz=4.453
z_offset: 3.010 # noise 0.000968mm, MAD_Hz=11.373

probe_eddy_current: noise 0.000586mm, MAD_Hz=10.982 in 2525 queries
Total frequency range: 90113.107 Hz
z_offset: 0.250 # noise 0.000414mm, MAD_Hz=20.335
z_offset: 0.530 # noise 0.000197mm, MAD_Hz=7.800
z_offset: 1.010 # noise 0.000184mm, MAD_Hz=5.862
z_offset: 2.010 # noise 0.000330mm, MAD_Hz=6.999
z_offset: 3.010 # noise 0.000497mm, MAD_Hz=5.815

And then I returned to master (e60fe3d) and got:

probe_eddy_current: noise 0.003054mm, MAD_Hz=49.431 in 2525 queries
Total frequency range: 89955.979 Hz
z_offset: 0.250 # noise 0.000419mm, MAD_Hz=20.919
z_offset: 0.530 # noise 0.001052mm, MAD_Hz=42.343
z_offset: 1.010 # noise 0.001787mm, MAD_Hz=57.761
z_offset: 2.010 # noise 0.002182mm, MAD_Hz=47.129
z_offset: 3.010 # noise 0.001080mm, MAD_Hz=13.362

probe_eddy_current: noise 0.002936mm, MAD_Hz=48.685 in 2526 queries
Total frequency range: 89962.776 Hz
z_offset: 0.250 # noise 0.000742mm, MAD_Hz=37.094
z_offset: 0.530 # noise 0.000984mm, MAD_Hz=39.286
z_offset: 1.010 # noise 0.002422mm, MAD_Hz=76.508
z_offset: 2.010 # noise 0.004463mm, MAD_Hz=96.147
z_offset: 3.010 # noise 0.003868mm, MAD_Hz=45.084

Frequency too noisy at step 3.930 -> 3.970
Frequency diff: 272.822, MAD_Hz: 103.825 -> MAD_Hz: 41.376
probe_eddy_current: noise 0.002843mm, MAD_Hz=49.012 in 2451 queries
Total frequency range: 89030.746 Hz
z_offset: 0.250 # noise 0.000645mm, MAD_Hz=32.104
z_offset: 0.530 # noise 0.001021mm, MAD_Hz=39.518
z_offset: 1.010 # noise 0.001117mm, MAD_Hz=35.450
z_offset: 2.010 # noise 0.000620mm, MAD_Hz=13.738
z_offset: 3.010 # noise 0.003201mm, MAD_Hz=37.617

-Kevin

@ifreislich
Copy link

ifreislich commented Jan 3, 2026

[edit] Mine is a BTT Eddy Coil.

On master:

// Frequency too noisy at step 3.250 -> 3.290
// Frequency diff: 252.237, MAD_Hz: 42.663 -> MAD_Hz: 107.419
// probe_eddy_current: noise 0.003837mm, MAD_Hz=44.431 in 2024 queries
// Total frequency range: 42697.325 Hz
// z_offset: 0.290 # noise 0.001613mm, MAD_Hz=37.181
// z_offset: 0.530 # noise 0.001204mm, MAD_Hz=25.114
// z_offset: 1.010 # noise 0.004307mm, MAD_Hz=66.982
// z_offset: 2.010 # noise 0.006634mm, MAD_Hz=65.732
// z_offset: 3.010 # noise 0.013372mm, MAD_Hz=86.787

// Frequency too noisy at step 3.050 -> 3.090
// Frequency diff: 246.400, MAD_Hz: 104.469 -> MAD_Hz: 24.238
// probe_eddy_current: noise 0.004148mm, MAD_Hz=48.572 in 1900 queries
// Total frequency range: 41444.358 Hz
// z_offset: 0.290 # noise 0.002349mm, MAD_Hz=53.895
// z_offset: 0.530 # noise 0.001754mm, MAD_Hz=35.421
// z_offset: 1.010 # noise 0.002563mm, MAD_Hz=43.670
// z_offset: 2.010 # noise 0.008039mm, MAD_Hz=81.323
// z_offset: 3.010 # noise 0.006583mm, MAD_Hz=43.990

// Frequency too noisy at step 2.690 -> 2.730
// Frequency diff: 293.364, MAD_Hz: 84.125 -> MAD_Hz: 84.994
// probe_eddy_current: noise 0.003555mm, MAD_Hz=46.405 in 1675 queries
// Total frequency range: 38640.674 Hz
// z_offset: 0.290 # noise 0.002411mm, MAD_Hz=55.474
// z_offset: 0.530 # noise 0.001737mm, MAD_Hz=35.947
// z_offset: 1.010 # noise 0.003024mm, MAD_Hz=46.638
// z_offset: 2.010 # noise 0.009671mm, MAD_Hz=94.999

On 204eb8d ldc1612: enable frequency div to reduce noise:

// probe_eddy_current: noise 0.000911mm, MAD_Hz=8.711 in 2526 queries
// Total frequency range: 47137.971 Hz
// z_offset: 0.290 # noise 0.000584mm, MAD_Hz=13.951
// z_offset: 0.530 # noise 0.000394mm, MAD_Hz=8.362
// z_offset: 1.010 # noise 0.000310mm, MAD_Hz=5.161
// z_offset: 2.010 # noise 0.000658mm, MAD_Hz=6.795
// z_offset: 3.010 # noise 0.001478mm, MAD_Hz=9.881

// probe_eddy_current: noise 0.000901mm, MAD_Hz=8.365 in 2522 queries
// Total frequency range: 46997.774 Hz
// z_offset: 0.290 # noise 0.000668mm, MAD_Hz=15.847
// z_offset: 0.530 # noise 0.000868mm, MAD_Hz=18.124
// z_offset: 1.010 # noise 0.000181mm, MAD_Hz=3.050
// z_offset: 2.010 # noise 0.001042mm, MAD_Hz=10.672
// z_offset: 3.010 # noise 0.001779mm, MAD_Hz=12.038

// probe_eddy_current: noise 0.000969mm, MAD_Hz=9.384 in 2525 queries
// Total frequency range: 46938.665 Hz
// z_offset: 0.290 # noise 0.000646mm, MAD_Hz=15.214
// z_offset: 0.530 # noise 0.000455mm, MAD_Hz=9.470
// z_offset: 1.010 # noise 0.000839mm, MAD_Hz=13.769
// z_offset: 2.010 # noise 0.000472mm, MAD_Hz=4.882
// z_offset: 3.010 # noise 0.001026mm, MAD_Hz=6.920

@nefelim4ag
Copy link
Collaborator Author

Cool! Thanks.
Than it is less likely that it was a fluke on the initial measurments done by @ifreislich in discord.

I honestly don't know why it works.
At least, I don't have an good explanation which would explain why it does not change noise for my sensor, but does for BTT Eddy at the same time.
And I don't know why the difference is so huge. It is about ~5 times better.
And so why it is increases the frequency range.

the reduction on "noise"

Btw, if someone have better wording I'm not against it :D

Also, I don't like how code looks with divs here. It is just placed in a way, that introduce minimal conflicts with all other PRs.
Probably I will try to refactor some calculation within or after the tap PR.

-Timofey

@nefelim4ag nefelim4ag marked this pull request as ready for review January 3, 2026 18:25
@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jan 3, 2026

Nice find!

At least, I don't have an good explanation which would explain why it does not change noise for my sensor, but does for BTT Eddy at the same time.

What frequency is your clock input to the ldc1612 and what frequencies do you find are reported by the sensor after calibration?

Also, I don't like how code looks with divs here.

How about something like the following?

--- a/klippy/extras/ldc1612.py
+++ b/klippy/extras/ldc1612.py
@@ -3,7 +3,7 @@
 # Copyright (C) 2020-2024  Kevin O'Connor <kevin@koconnor.net>
 #
 # This file may be distributed under the terms of the GNU GPLv3 license.
-import logging
+import math, logging
 from . import bus, bulk_sensor
 
 MIN_MSG_TIME = 0.100
@@ -13,6 +13,7 @@ BATCH_UPDATES = 0.100
 LDC1612_ADDR = 0x2a
 
 DEFAULT_LDC1612_FREQ = 12000000
+MAX_SENSOR_FREQ = 4000000.
 SETTLETIME = 0.005
 DRIVECUR = 15
 DEGLITCH = 0x05 # 10 Mhz
@@ -87,8 +88,10 @@ class LDC1612:
         self.oid = oid = mcu.create_oid()
         self.query_ldc1612_cmd = None
         self.ldc1612_setup_home_cmd = self.query_ldc1612_home_state_cmd = None
-        self.frequency = config.getint("frequency", DEFAULT_LDC1612_FREQ,
-                                       2000000, 40000000)
+        self.clock_freq = config.getint("frequency", DEFAULT_LDC1612_FREQ,
+                                        2000000, 40000000)
+        self.sensor_div = int(math.ceil(4.*MAX_SENSOR_FREQ / self.clock_freq))
+        self.freq_conv = float(self.clock_freq * sensor_div) / (1<<28)
         if config.get('intb_pin', None) is not None:
             ppins = config.get_printer().lookup_object("pins")
             pin_params = ppins.lookup_pin(config.get('intb_pin'))
@@ -143,7 +146,7 @@ class LDC1612:
     def setup_home(self, print_time, trigger_freq,
                    trsync_oid, hit_reason, err_reason):
         clock = self.mcu.print_time_to_clock(print_time)
-        tfreq = int(trigger_freq * (1<<28) / float(self.frequency) + 0.5)
+        tfreq = int(trigger_freq / self.freq_conv + 0.5)
         self.ldc1612_setup_home_cmd.send(
             [self.oid, clock, tfreq, trsync_oid, hit_reason, err_reason])
     def clear_home(self):
@@ -155,7 +158,7 @@ class LDC1612:
         return self.mcu.clock_to_print_time(tclock)
     # Measurement decoding
     def _convert_samples(self, samples):
-        freq_conv = float(self.frequency) / (1<<28)
+        freq_conv = self.freq_conv
         count = 0
         for ptime, val in samples:
             mv = val & 0x0fffffff
@@ -176,11 +179,11 @@ class LDC1612:
                 "(e.g. faulty wiring) or a faulty ldc1612 chip."
                 % (manuf_id, dev_id, LDC1612_MANUF_ID, LDC1612_DEV_ID))
         # Setup chip in requested query rate
-        rcount0 = self.frequency / (16. * self.data_rate)
+        rcount0 = self.clock_freq / (16. * self.data_rate)
         self.set_reg(REG_RCOUNT0, int(rcount0 + 0.5))
         self.set_reg(REG_OFFSET0, 0)
-        self.set_reg(REG_SETTLECOUNT0, int(SETTLETIME*self.frequency/16. + .5))
-        self.set_reg(REG_CLOCK_DIVIDERS0, (1 << 12) | 1)
+        self.set_reg(REG_SETTLECOUNT0, int(SETTLETIME*self.clock_freq/16. + .5))
+        self.set_reg(REG_CLOCK_DIVIDERS0, (self.sensor_div << 12) | 1)
         self.set_reg(REG_ERROR_CONFIG, (0x1f << 11) | 1)
         self.set_reg(REG_MUX_CONFIG, 0x0208 | DEGLITCH)
         self.set_reg(REG_CONFIG, 0x001 | (1<<12) | (1<<10) | (1<<9))

-Kevin

EDIT: Update patch to also take into account (1<<28).

@nefelim4ag
Copy link
Collaborator Author

What frequency is your clock input to the ldc1612 and what frequencies do you find are reported by the sensor after calibration?

Clock input is 24MHz, Coil frequencies are similiar to Eddy's:

calibrate =
	0.050000:3299232.867,0.090000:3292506.201,0.130000:3285771.500,
 	0.170000:3279264.035,0.210000:3272820.461,0.250000:3266655.607,
 	0.290000:3260582.059,0.330000:3254717.792,0.370000:3248924.189,
 	0.410000:3243372.052,0.450000:3237903.389,0.490000:3232647.722,
 	0.530000:3227465.143,0.570000:3222502.252,0.610000:3217579.390,
 	0.650000:3212855.598,0.690000:3208190.961,0.730000:3203725.262,
 	0.770000:3199308.547,0.810000:3195082.233,0.850000:3190890.959,
 	0.890000:3186855.615,0.930000:3182862.671,0.970000:3179046.003,
 	1.010000:3175246.063,1.050000:3171616.609,1.090000:3167996.417,
 	1.130000:3164525.885,1.170000:3161081.954,1.210000:3157788.126,
 	1.250000:3154526.854,1.290000:3151388.476,1.330000:3148278.558,
 	1.370000:3145295.559,1.410000:3142326.533,1.450000:3139472.419,
 	1.490000:3136647.910,1.530000:3133926.648,1.570000:3131232.297,
 	1.610000:3128633.641,1.650000:3126039.534,1.690000:3123553.945,
 	1.730000:3121084.367,1.770000:3118699.640,1.810000:3116328.095,
 	1.850000:3114044.623,1.890000:3111777.602,1.930000:3109598.486,
 	1.970000:3107447.988,2.010000:3105368.800,2.050000:3103310.706,
 	2.090000:3101328.928,2.130000:3099361.861,2.170000:3097466.219,
 	2.210000:3095579.317,2.250000:3093764.537,2.290000:3091958.327,
 	2.330000:3090210.096,2.370000:3088477.382,2.410000:3086801.584,
	2.450000:3085141.980,2.490000:3083548.093,2.530000:3081953.484,
 	2.570000:3080419.139,2.610000:3078890.058,2.650000:3077417.539,
 	2.690000:3075940.336,2.730000:3074518.833,2.770000:3073102.752,
 	2.810000:3071737.354,2.850000:3070375.711,2.890000:3069066.996,
 	2.930000:3067750.289,2.970000:3066488.732,3.010000:3065223.734,
 	3.050000:3064005.876,3.090000:3062795.255,3.130000:3061622.512,
 	3.170000:3060453.408,3.210000:3059327.681,3.250000:3058197.387,
 	3.290000:3057111.808,3.330000:3056024.072,3.370000:3054975.794,
 	3.410000:3053928.730,3.450000:3052917.566,3.490000:3051913.923,
 	3.530000:3050937.513,3.570000:3049966.418,3.610000:3049025.234,
 	3.650000:3048088.092,3.690000:3047182.246,3.730000:3046281.842,
 	3.770000:3045409.723,3.810000:3044538.725,3.850000:3043698.270,
 	3.890000:3042864.375,3.930000:3042052.131,3.970000:3041251.012,
 	4.010000:3040466.480,4.050000:3039689.004

And this is from Mellow SHT36v3 (I have motan dump data):

"reg_drive_current": 13,
"frequency": 40000000,

0.050000:4578576.422,0.090000:4575825.936,0.130000:4573142.320,
0.170000:4570556.760,0.210000:4568015.075,0.250000:4565487.093,
0.290000:4563005.125,0.330000:4560691.154,0.370000:4558294.630,
0.410000:4556012.809,0.450000:4553741.992,0.490000:4551516.980,
0.530000:4549341.309,0.570000:4547219.944,0.610000:4545115.888,
0.650000:4543049.538,0.690000:4541035.676,0.730000:4539148.426,
0.770000:4537193.561,0.810000:4535276.121,0.850000:4533417.147,
0.890000:4531587.130,0.930000:4529782.224,0.970000:4528010.100,
1.010000:4526275.915,1.050000:4524577.916,1.090000:4522910.827,
1.130000:4521262.652,1.170000:4519716.203,1.210000:4518116.999,
1.250000:4516566.497,1.290000:4515041.184,1.330000:4513534.170,
1.370000:4512047.219,1.410000:4510588.044,1.450000:4509137.338,
1.490000:4507757.741,1.530000:4506375.319,1.570000:4505022.007,
1.610000:4503697.020,1.650000:4502380.001,1.690000:4501074.302,
1.730000:4499860.233,1.770000:4498571.289,1.810000:4497325.581,
1.850000:4496115.530,1.890000:4494903.135,1.930000:4493704.093,
1.970000:4492531.711,2.010000:4491372.764,2.050000:4490230.453,
2.090000:4489103.585,2.130000:4488000.160,2.170000:4486914.957,
2.210000:4485847.646,2.250000:4484783.095,2.290000:4483754.212,
2.330000:4482714.748,2.370000:4481688.416,2.410000:4480681.157,
2.450000:4479690.516,2.490000:4478707.534,2.530000:4477738.601,
2.570000:4476773.971,2.610000:4475817.204,2.650000:4474866.569,
2.690000:4473924.321,2.730000:4472984.666,2.770000:4472061.837,
2.810000:4471148.908,2.850000:4470249.438,2.890000:4469342.077,
2.930000:4468456.507,2.970000:4467570.764,3.010000:4466700.661,
3.050000:4465838.951,3.090000:4464984.989,3.130000:4464139.330,
3.170000:4463304.782,3.210000:4462458.003,3.250000:4461636.353,
3.290000:4460812.831,3.330000:4459998.322,3.370000:4459183.806,
3.410000:4458439.779,3.450000:4457647.508,3.490000:4456868.511,
3.530000:4456099.576,3.570000:4455346.155,3.610000:4454595.488,
3.650000:4453858.781,3.690000:4453120.929,3.730000:4452389.151,
3.770000:4451670.176,3.810000:4450962.388,3.850000:4450251.186,
3.890000:4449557.769,3.930000:4448872.119,3.970000:4448192.638,
4.010000:4447518.116,4.050000:4446856.356

How about something like the following?

I also want to adjust the frequency, this is one of the solutions here.
Generally, I wanted to just define raw2freq and freq2raw conversion coefficients.

self._raw2freq_conv = float(self.clock_freq * self.sensor_div) / (1<<28)
self._freq2raw_conv = (1<<28) / float(self.clock_freq * self.sensor_div)

Ah, you have already incorporated something like this.

About division enable logic, IDK. In perfect scenario we can try to get the frequency during the current calibration.
But in the context where we only have ~3 devices to support any hack should work.

Cheers,
-Timofey

@nefelim4ag nefelim4ag force-pushed the btt-eddy-reduce-noise branch 2 times, most recently from a6dee04 to b9ff94b Compare January 4, 2026 04:00
@KevinOConnor
Copy link
Collaborator

Thanks. I'll commit this when you are ready.

And this is from Mellow SHT36v3

Ah, okay, so some known sensors go as high as 4.5Mhz then.

About division enable logic, IDK. In perfect scenario we can try to get the frequency during the current calibration.
But in the context where we only have ~3 devices to support any hack should work.

Agreed; it isn't worth spending a lot of effort on.

One minor advantage of:

MAX_SENSOR_FREQ = 5000000.
...
self.sensor_div = int(math.ceil(4.*MAX_SENSOR_FREQ / self.clock_freq))

is that it hints at why we're doing this (spec says "VALID ƒINx RANGE: < ƒREFx /4"). It's not a big deal either way though.

Cheers,
-Kevin

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jan 4, 2026

As a slight tangent, if I'm reading table 43 of the spec correctly, the SHT36v3 should be setting FREF_DIVIDER0=2 (as 40Mhz is above the 35Mhz max Fref in single channel mode).

self.ref_clock_div = int(math.ceil(nom_clock_freq/35000000.))
self.clock_freq = nom_clock_freq // self.ref_clock_div

?

-Kevin

@nefelim4ag
Copy link
Collaborator Author

nefelim4ag commented Jan 4, 2026

is that it hints at why we're doing this (spec says "VALID ƒINx RANGE: < ƒREFx /4"). It's not a big deal either way though.

I agree here.
Probably, for now, it can be a comment?

From my overall experience with LDC, I think we can add LDC_VERIFY_SENSOR something.
(And an appropriate step in the documentation).
Which can verify ODR, and by so input frequency.
The sensor will work with the wrong frequency settings 1.
It is possible to live-adjust the settings2.
And by the same command, just set the divider into the config as we do with IDRIVE current.

As a slight tangent, if I'm reading table 43 of the spec correctly, the SHT36v3 should be setting FREF_DIVIDER0=2 (as 40Mhz is above the 35Mhz max Fref in single channel mode).

This is correct, it is required by the datasheet, but from the data that I have seen, it seems to work fine 3

Also, I did some local testing before with the divider and internal clock reference source:
#6734 (comment)

At least for my internal clock of ~46MHz it changes nothing4.

That said,
I would suggest being conservative here for now, unless we have data that 40MHz input with a single channel causes issues.
It may happen that it would require both divs, because 40/2 = 20Mhz and coil frequency of 4.5MHz is now close to 1/4 boundary.

I asked the person who has SHT36v3 on hands (and whom data I use), so we can collect some data before/after the divider:
https://discord.com/channels/431557959978450984/801826273227177984/1457420362630561889

-Timofey


Patch updated with the comment.

Footnotes

  1. Examples of wrong frequency settings: discord_1 SHT36v3, discord_2 sovol's eddy

  2. I did live calibration for internal reference clock

  3. https://discord.com/channels/431557959978450984/801826273227177984/1445130833026482257

  4. Data is noisy with an internal reference clock, so I don't think it is useful in practice. I had an idea that it could help BTT Eddy, before FIN_DIV.

BTT Eddy uses 12MHz clock in frequency.
Coil is oscillating at 3+MHz.
Which is out of spec for LDC1612 sensors.
Division of coil frequency seems to reduce output noise.

Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
@nefelim4ag nefelim4ag force-pushed the btt-eddy-reduce-noise branch from b9ff94b to f793225 Compare January 4, 2026 17:41
@KevinOConnor
Copy link
Collaborator

Okay, thanks. That makes sense to me.

-Kevin

@nefelim4ag
Copy link
Collaborator Author

nefelim4ag commented Jan 4, 2026

So, if you don't mind, then I would suggest merging this.

Probably, it can make sense to add change log note that BTT Eddy may require recalibration after this.
Because overall sensor range has changed #7160 (comment) 41444.358 -> 46938.665, and probably curve now is also distorted.

I would rebase and slightly adjust the #6813 right after that, because now I can treat F_IN > 1/4 F_REF as invalid data.

Cheers,
-Timofey

@KevinOConnor KevinOConnor merged commit abda66d into Klipper3d:master Jan 4, 2026
1 check passed
@KevinOConnor
Copy link
Collaborator

Okay, thanks.

-Kevin

@nefelim4ag nefelim4ag deleted the btt-eddy-reduce-noise branch January 4, 2026 21:18
@nefelim4ag
Copy link
Collaborator Author

I duplicate data here, because otherwise it will be lost in the discord purgatory.
SHT36v3

Without any frequency hacks:

// z_offset: 3.010 # noise 0.000704mm, MAD_Hz=16.045
// z_offset: 2.010 # noise 0.001198mm, MAD_Hz=34.839
// z_offset: 1.010 # noise 0.001036mm, MAD_Hz=44.060
// z_offset: 0.530 # noise 0.001025mm, MAD_Hz=54.789
// z_offset: 0.290 # noise 0.000806mm, MAD_Hz=48.590
// Total frequency range: 132183.778 Hz
// probe_eddy_current: noise 0.000945mm, MAD_Hz=31.805 in 2525 queries

// z_offset: 3.010 # noise 0.001168mm, MAD_Hz=26.715
// z_offset: 2.010 # noise 0.001203mm, MAD_Hz=34.839
// z_offset: 1.010 # noise 0.001208mm, MAD_Hz=51.517
// z_offset: 0.530 # noise 0.000997mm, MAD_Hz=53.924
// z_offset: 0.290 # noise 0.001035mm, MAD_Hz=62.418
// Total frequency range: 132176.912 Hz
// probe_eddy_current: noise 0.001063mm, MAD_Hz=35.620 in 2525 queries

// z_offset: 3.010 # noise 0.001069mm, MAD_Hz=24.277
// z_offset: 2.010 # noise 0.001261mm, MAD_Hz=36.621
// z_offset: 1.010 # noise 0.000986mm, MAD_Hz=41.652
// z_offset: 0.530 # noise 0.000940mm, MAD_Hz=50.420
// z_offset: 0.290 # noise 0.000887mm, MAD_Hz=53.673
// Total frequency range: 131843.984 Hz
// probe_eddy_current: noise 0.000939mm, MAD_Hz=31.717 in 2527 queries

With F_REFERECE_DIV = 2:

// z_offset: 3.010 # noise 0.000818mm, MAD_Hz=18.551
// z_offset: 2.010 # noise 0.000822mm, MAD_Hz=23.779
// z_offset: 1.010 # noise 0.000691mm, MAD_Hz=29.445
// z_offset: 0.530 # noise 0.000843mm, MAD_Hz=45.305
// z_offset: 0.290 # noise 0.000883mm, MAD_Hz=53.060
// Total frequency range: 131911.710 Hz
// probe_eddy_current: noise 0.001014mm, MAD_Hz=33.368 in 2522 queries

// z_offset: 3.010 # noise 0.001371mm, MAD_Hz=31.143
// z_offset: 2.010 # noise 0.001261mm, MAD_Hz=36.559
// z_offset: 1.010 # noise 0.001245mm, MAD_Hz=52.569
// z_offset: 0.530 # noise 0.001154mm, MAD_Hz=61.939
// z_offset: 0.290 # noise 0.000877mm, MAD_Hz=53.331
// Total frequency range: 131990.752 Hz
// probe_eddy_current: noise 0.001009mm, MAD_Hz=33.484 in 2522 queries

// z_offset: 3.010 # noise 0.000939mm, MAD_Hz=21.240
// z_offset: 2.010 # noise 0.001008mm, MAD_Hz=29.212
// z_offset: 1.010 # noise 0.000960mm, MAD_Hz=40.856
// z_offset: 0.530 # noise 0.001005mm, MAD_Hz=53.907
// z_offset: 0.290 # noise 0.000929mm, MAD_Hz=56.479
// Total frequency range: 131654.587 Hz
// probe_eddy_current: noise 0.001009mm, MAD_Hz=33.865 in 2525 queries

With dummy sensor hack1 nefelim4ag@5d4b82d:

// z_offset: 3.010 # noise 0.001182mm, MAD_Hz=26.986
// z_offset: 2.010 # noise 0.000717mm, MAD_Hz=20.617
// z_offset: 1.010 # noise 0.001009mm, MAD_Hz=41.893
// z_offset: 0.530 # noise 0.001080mm, MAD_Hz=56.210
// z_offset: 0.290 # noise 0.000826mm, MAD_Hz=48.726
// Total frequency range: 129925.778 Hz
// probe_eddy_current: noise 0.000832mm, MAD_Hz=27.460 in 2525 queries

// z_offset: 3.010 # noise 0.001145mm, MAD_Hz=26.182
// z_offset: 2.010 # noise 0.000546mm, MAD_Hz=15.732
// z_offset: 1.010 # noise 0.000539mm, MAD_Hz=22.444
// z_offset: 0.530 # noise 0.000790mm, MAD_Hz=41.432
// z_offset: 0.290 # noise 0.000746mm, MAD_Hz=44.093
// Total frequency range: 130026.468 Hz
// probe_eddy_current: noise 0.000844mm, MAD_Hz=27.623 in 2525 queries

// z_offset: 3.010 # noise 0.000763mm, MAD_Hz=17.395
// z_offset: 2.010 # noise 0.000504mm, MAD_Hz=14.544
// z_offset: 1.010 # noise 0.000727mm, MAD_Hz=30.589
// z_offset: 0.530 # noise 0.000710mm, MAD_Hz=37.277
// z_offset: 0.290 # noise 0.000950mm, MAD_Hz=56.532
// Total frequency range: 130357.245 Hz
// probe_eddy_current: noise 0.000835mm, MAD_Hz=27.290 in 2526 queries

Footnotes

  1. https://e2e.ti.com/support/sensors-group/sensors/f/sensors-forum/1260319/ldc1612-the-output-of-ldc1612

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants