From 1e44f3af3be2fdce1241d8681dc0e0ef73bbc8d0 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 10:05:31 +0100 Subject: [PATCH 1/7] [adc] Add support for HX71708 --- klippy/extras/hx71x.py | 25 ++++++++++++++++++++++++- src/sensor_hx71x.c | 35 +++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 00f62892c..3f68c93a5 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -25,12 +25,17 @@ def __init__( default_sample_rate, gain_options, default_gain, + sps_bits = {}, ): self.printer = printer = config.get_printer() self.name = config.get_name().split()[-1] self.last_error_count = 0 self.consecutive_fails = 0 self.sensor_type = sensor_type + if sensor_type == "hx71708": + self.gain_or_sps = 1 + else: + self.gain_or_sps = 0 # Chip options dout_pin_name = config.get("dout_pin") sclk_pin_name = config.get("sclk_pin") @@ -50,6 +55,9 @@ def __init__( self.sps = config.getchoice( "sample_rate", sample_rate_options, default=default_sample_rate ) + self.sps_bits = config.getchoice( + "sample_rate", sps_bits, default=default_sample_rate + ) # gain/channel choices self.gain_channel = int( config.getchoice("gain", gain_options, default=default_gain) @@ -196,4 +204,19 @@ def __init__(self, config): ) -HX71X_SENSOR_TYPES = {"hx711": HX711, "hx717": HX717} +class HX71708(HX71xBase): + def __init__(self, config): + super(HX71708, self).__init__( + config, + "hx71708", + # HX717 sps options + {320: 320, 80: 80, 20: 20, 10: 10}, + 320, + # HX717 gain/channel options + {"A-128": 1}, + "A-128", + {320: 4, 3: 80, 20: 2, 10: 1}, + ) + + +HX71X_SENSOR_TYPES = {"hx711": HX711, "hx717": HX717, "hx71708": HX71708} diff --git a/src/sensor_hx71x.c b/src/sensor_hx71x.c index f20d88072..f4d382603 100644 --- a/src/sensor_hx71x.c +++ b/src/sensor_hx71x.c @@ -17,6 +17,8 @@ struct hx71x_adc { struct timer timer; + uint8_t gain_or_sps; + uint8_t sps; uint8_t gain_channel; // the gain+channel selection (1-4) uint8_t flags; uint32_t rest_ticks; @@ -146,8 +148,15 @@ static void hx71x_read_adc(struct hx71x_adc *hx71x, uint8_t oid) { // Read from sensor - uint_fast8_t gain_channel = hx71x->gain_channel; - uint32_t adc = hx71x_raw_read(hx71x->dout, hx71x->sclk, 24 + gain_channel); + uint_fast8_t gain_or_sps = hx71x->gain_or_sps; + + uint_fast8_t extra_bits; + if (gain_or_sps == 1) { + extra_bits = hx71x->sps; + } else { + extra_bits = hx71x->gain_channel; + } + uint32_t adc = hx71x_raw_read(hx71x->dout, hx71x->sclk, 24 + extra_bits); // Clear pending flag (and note if an overflow occurred) irq_disable(); @@ -156,12 +165,12 @@ hx71x_read_adc(struct hx71x_adc *hx71x, uint8_t oid) irq_enable(); // Extract report from raw data - uint32_t counts = adc >> gain_channel; + uint32_t counts = adc >> extra_bits; if (counts & 0x800000) counts |= 0xFF000000; // Check for errors - uint_fast8_t extras_mask = (1 << gain_channel) - 1; + uint_fast8_t extras_mask = (1 << extra_bits) - 1; if ((adc & extras_mask) != extras_mask) { // Transfer did not complete correctly hx71x->last_error = SAMPLE_ERROR_DESYNC; @@ -186,17 +195,23 @@ command_config_hx71x(uint32_t *args) struct hx71x_adc *hx71x = oid_alloc(args[0] , command_config_hx71x, sizeof(*hx71x)); hx71x->timer.func = hx71x_event; - uint8_t gain_channel = args[1]; - if (gain_channel < 1 || gain_channel > 4) { + uint8_t gain_or_sps = args[1]; + uint8_t sps = args[2]; + uint8_t gain_channel = args[3]; + if (gain_or_sps == 0 && (gain_channel < 1 || gain_channel > 4)) { shutdown("HX71x gain/channel out of range 1-4"); } + if (gain_or_sps == 1 && (sps < 1 || sps > 4)) { + shutdown("HX71x sample_rate out of range 1-4"); + } + hx71x->gain_or_sps = gain_or_sps; + hx71x->sps = sps; hx71x->gain_channel = gain_channel; - hx71x->dout = gpio_in_setup(args[2], 1); - hx71x->sclk = gpio_out_setup(args[3], 0); + hx71x->dout = gpio_in_setup(args[4], 1); + hx71x->sclk = gpio_out_setup(args[5], 0); gpio_out_write(hx71x->sclk, 1); // put chip in power down state } -DECL_COMMAND(command_config_hx71x, "config_hx71x oid=%c gain_channel=%c" - " dout_pin=%u sclk_pin=%u"); +DECL_COMMAND(command_config_hx71x, "config_hx71x oid=%c gain_or_sps=%c sps=%c gain_channel=%c"" dout_pin=%u sclk_pin=%u"); // start/stop capturing ADC data void From ae320c660f63e080ade8d9b31cdcd385f4c17ca5 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 11:49:39 +0100 Subject: [PATCH 2/7] Fix config_cmd definition to accept new parameters --- klippy/extras/hx71x.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 3f68c93a5..5914ad704 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -78,8 +78,8 @@ def __init__( # Command Configuration self.query_hx71x_cmd = None mcu.add_config_cmd( - "config_hx71x oid=%d gain_channel=%d dout_pin=%s sclk_pin=%s" - % (self.oid, self.gain_channel, self.dout_pin, self.sclk_pin) + "config_hx71x oid=%d gain_or_sps=%d sps=%d gain_channel=%d dout_pin=%s sclk_pin=%s" + % (self.oid, self.gain_or_sps, self.sps_bits, self.gain_channel, self.dout_pin, self.sclk_pin) ) mcu.add_config_cmd( "query_hx71x oid=%d rest_ticks=0" % (self.oid,), on_restart=True From 03ab7da51a6a6b1ae2c867541562bee51ef0ee70 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 11:55:31 +0100 Subject: [PATCH 3/7] Ruff; add note on this adc --- klippy/extras/hx71x.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 5914ad704..de89172fa 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -25,17 +25,12 @@ def __init__( default_sample_rate, gain_options, default_gain, - sps_bits = {}, + sps_bits, ): self.printer = printer = config.get_printer() self.name = config.get_name().split()[-1] self.last_error_count = 0 self.consecutive_fails = 0 - self.sensor_type = sensor_type - if sensor_type == "hx71708": - self.gain_or_sps = 1 - else: - self.gain_or_sps = 0 # Chip options dout_pin_name = config.get("dout_pin") sclk_pin_name = config.get("sclk_pin") @@ -52,12 +47,19 @@ def __init__( self.dout_pin = dout_ppin["pin"] self.sclk_pin = sclk_ppin["pin"] # Samples per second choices + self.sensor_type = sensor_type + # HX71708 configures the sample rate instead of the gain/channel. + # We forward the sps bits to hx71x_read_adc so that it can read the extra bits required + if sensor_type == "hx71708": + self.gain_or_sps = 1 + self.sps_bits = config.getchoice( + "sample_rate", sps_bits, default=default_sample_rate + ) + else: + self.gain_or_sps = 0 self.sps = config.getchoice( "sample_rate", sample_rate_options, default=default_sample_rate ) - self.sps_bits = config.getchoice( - "sample_rate", sps_bits, default=default_sample_rate - ) # gain/channel choices self.gain_channel = int( config.getchoice("gain", gain_options, default=default_gain) From 7803864664a37c4063e80178447cfc5f1b0748d4 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 12:02:28 +0100 Subject: [PATCH 4/7] ruff: chop down if long --- klippy/extras/hx71x.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index de89172fa..02ed8697e 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -81,7 +81,14 @@ def __init__( self.query_hx71x_cmd = None mcu.add_config_cmd( "config_hx71x oid=%d gain_or_sps=%d sps=%d gain_channel=%d dout_pin=%s sclk_pin=%s" - % (self.oid, self.gain_or_sps, self.sps_bits, self.gain_channel, self.dout_pin, self.sclk_pin) + % ( + self.oid, + self.gain_or_sps, + self.sps_bits, + self.gain_channel, + self.dout_pin, + self.sclk_pin + ) ) mcu.add_config_cmd( "query_hx71x oid=%d rest_ticks=0" % (self.oid,), on_restart=True From 0584f22219fd0f9eeb9579a8d55bd72e2fc8af64 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 12:03:40 +0100 Subject: [PATCH 5/7] ruff: trailing param end --- klippy/extras/hx71x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 02ed8697e..31d7361dd 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -87,7 +87,7 @@ def __init__( self.sps_bits, self.gain_channel, self.dout_pin, - self.sclk_pin + self.sclk_pin, ) ) mcu.add_config_cmd( From ef6fc4f8955a5ae8953ebb9ffd07d80a21baec06 Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 12:25:12 +0100 Subject: [PATCH 6/7] Positional arg --- klippy/extras/hx71x.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 31d7361dd..3d56270ee 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -196,6 +196,7 @@ def __init__(self, config): # HX711 gain/channel options {"A-128": 1, "B-32": 2, "A-64": 3}, "A-128", + {}, ) @@ -210,6 +211,7 @@ def __init__(self, config): # HX717 gain/channel options {"A-128": 1, "B-64": 2, "A-64": 3, "B-8": 4}, "A-128", + {}, ) From b18455311f9fcbd21ad511abb022b54c8ab2baae Mon Sep 17 00:00:00 2001 From: Ella Fox Date: Thu, 29 Jan 2026 13:11:27 +0100 Subject: [PATCH 7/7] sps_bits in impl --- klippy/extras/hx71x.py | 12 +++++++----- src/sensor_hx71x.c | 16 ++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/klippy/extras/hx71x.py b/klippy/extras/hx71x.py index 3d56270ee..5a329db02 100644 --- a/klippy/extras/hx71x.py +++ b/klippy/extras/hx71x.py @@ -30,6 +30,7 @@ def __init__( self.printer = printer = config.get_printer() self.name = config.get_name().split()[-1] self.last_error_count = 0 + self.sensor_type = sensor_type self.consecutive_fails = 0 # Chip options dout_pin_name = config.get("dout_pin") @@ -47,7 +48,9 @@ def __init__( self.dout_pin = dout_ppin["pin"] self.sclk_pin = sclk_ppin["pin"] # Samples per second choices - self.sensor_type = sensor_type + self.sps = config.getchoice( + "sample_rate", sample_rate_options, default=default_sample_rate + ) # HX71708 configures the sample rate instead of the gain/channel. # We forward the sps bits to hx71x_read_adc so that it can read the extra bits required if sensor_type == "hx71708": @@ -57,9 +60,8 @@ def __init__( ) else: self.gain_or_sps = 0 - self.sps = config.getchoice( - "sample_rate", sample_rate_options, default=default_sample_rate - ) + self.sps_bits = 0 + # gain/channel choices self.gain_channel = int( config.getchoice("gain", gain_options, default=default_gain) @@ -80,7 +82,7 @@ def __init__( # Command Configuration self.query_hx71x_cmd = None mcu.add_config_cmd( - "config_hx71x oid=%d gain_or_sps=%d sps=%d gain_channel=%d dout_pin=%s sclk_pin=%s" + "config_hx71x oid=%d gain_or_sps=%d sps_bits=%d gain_channel=%d dout_pin=%s sclk_pin=%s" % ( self.oid, self.gain_or_sps, diff --git a/src/sensor_hx71x.c b/src/sensor_hx71x.c index f4d382603..a584cea02 100644 --- a/src/sensor_hx71x.c +++ b/src/sensor_hx71x.c @@ -18,7 +18,7 @@ struct hx71x_adc { struct timer timer; uint8_t gain_or_sps; - uint8_t sps; + uint8_t sps_bits; uint8_t gain_channel; // the gain+channel selection (1-4) uint8_t flags; uint32_t rest_ticks; @@ -79,7 +79,7 @@ hx71x_delay(void) // Read 'num_bits' from the sensor static uint32_t -hx71x_raw_read(struct gpio_in dout, struct gpio_out sclk, int num_bits) +hx71x_raw_read(struct gpio_in dout, struct gpio_out sclk, uint_fast8_t num_bits) { uint32_t bits_read = 0; while (num_bits--) { @@ -152,11 +152,11 @@ hx71x_read_adc(struct hx71x_adc *hx71x, uint8_t oid) uint_fast8_t extra_bits; if (gain_or_sps == 1) { - extra_bits = hx71x->sps; + extra_bits = hx71x->sps_bits; } else { extra_bits = hx71x->gain_channel; } - uint32_t adc = hx71x_raw_read(hx71x->dout, hx71x->sclk, 24 + extra_bits); + uint32_t adc = hx71x_raw_read(hx71x->dout, hx71x->sclk, 24u + extra_bits); // Clear pending flag (and note if an overflow occurred) irq_disable(); @@ -196,22 +196,22 @@ command_config_hx71x(uint32_t *args) , command_config_hx71x, sizeof(*hx71x)); hx71x->timer.func = hx71x_event; uint8_t gain_or_sps = args[1]; - uint8_t sps = args[2]; + uint8_t sps_bits = args[2]; uint8_t gain_channel = args[3]; if (gain_or_sps == 0 && (gain_channel < 1 || gain_channel > 4)) { shutdown("HX71x gain/channel out of range 1-4"); } - if (gain_or_sps == 1 && (sps < 1 || sps > 4)) { + if (gain_or_sps == 1 && (sps_bits < 1 || sps_bits > 4)) { shutdown("HX71x sample_rate out of range 1-4"); } hx71x->gain_or_sps = gain_or_sps; - hx71x->sps = sps; + hx71x->sps_bits = sps_bits; hx71x->gain_channel = gain_channel; hx71x->dout = gpio_in_setup(args[4], 1); hx71x->sclk = gpio_out_setup(args[5], 0); gpio_out_write(hx71x->sclk, 1); // put chip in power down state } -DECL_COMMAND(command_config_hx71x, "config_hx71x oid=%c gain_or_sps=%c sps=%c gain_channel=%c"" dout_pin=%u sclk_pin=%u"); +DECL_COMMAND(command_config_hx71x, "config_hx71x oid=%c gain_or_sps=%c sps_bits=%c gain_channel=%c"" dout_pin=%u sclk_pin=%u"); // start/stop capturing ADC data void