ADS1115 config issues

Basic Information:

Printer Model: Custom
MCU: BTT Manta M8P V2.0 (STM32H723)
Host: CM4

klippy.log (318.8 KB)

I am attempting to add an ADS1115 ADC board (2 actually) to my printer utilizing the I2C header on a BTT Manta M8P V2.0 to add additional thermistors. I’ve gotten it wired in and communicating with klipper via an “ADS1x1x” config section, however, I get a “ADS1X1X temperature check failed” anytime I set the ‘pga’ value to an option higher than the ‘adc_voltage’ option.
I am running the ADS1115 boards at 5v, as that is what is available at the Manta’s I2C header. My thermistor pull-up resistors are 4.7k to 5v, thermistors to grd. If I set the ‘pga’ value at default (4.096V) and ‘adc_voltage’ @ 5.0, I get no errors but the temps are completely wrong, and don’t change when heating/cooling the thermistor.

I changed the boards to run at 3.3v, and changed the appropriate config sections (pga = 4.096V, adc_voltage = 3.3v) and the error came right back.

I confirmed my thermistor circuit is correct via multimeter at the input pin of the ADS1115 board, it reads the expected voltage. I verified the ADS1115 board is working with a quick test sketch on an Arduino, it reports back all the correct data via i2c to the Arduino. Tried multiple ADS1115 boards and thermistors

Reading through all the documentation, I am at a lost as to what could be the issue. Can anyone shed any light on the situation?

Thanks.

I did not use that chip (or any adc except the one built into the mcu), but assuming you made the Arduino sketch, you are more or less familiar with it.
I may try to guide you by the code.

This is a code where calculations happen:

# klippy/extras/ads1x1x.py

    def _process_sample(self, eventtime):
        sample = self.chip.sample(self)
        if sample is not None:
            # The sample is encoded in the top 12 or full 16 bits
            # Value's meaning is defined by ADS1X1X_REG_CONFIG['PGA_MASK']
            if isADS101X(self.chip.chip):
                sample >>= 4
                target_value = sample / ADS101X_RESOLUTION
            else:
                target_value = sample / ADS111X_RESOLUTION

            # Thermistors expect a value between 0 and 1 to work. If we use a
            # PGA with 4.096V but supply only 3.3V, the reference voltage for
            # voltage divider is only 3.3V, not 4.096V. So we remap the range
            # from what the PGA allows as range to end up between 0 and 1 for
            # the thermistor logic to work as expected.
            target_value = target_value * (ADS1X1X_PGA_VALUE[self.chip.pga] / \
                                           self.chip.adc_voltage)

            if target_value > self.maxval or target_value < self.minval:
                self.invalid_count = self.invalid_count + 1
                logging.warning("ADS1X1X: temperature outside range")
                self.check_invalid()
            else:
                self.invalid_count = 0

            # Publish result
            measured_time = self._reactor.monotonic()
            self.callback(self.chip.mcu.estimated_print_time(measured_time),
                        target_value)
        else:
            self.invalid_count = self.invalid_count + 1
            self.check_invalid()

        return eventtime + self.report_time

    def check_invalid(self):
        if self.invalid_count > self.range_check_count:
            self.chip._printer.invoke_shutdown(
                "ADS1X1X temperature check failed")

So, an example computation here will look like:

[ads1x1x z_motor_temp_board]
chip = ADS1115
pga = 6.144V
adc_voltage = 5
i2c_mcu = mcu
i2c_bus = i2c3_PA8_PC9
i2c_address = 72
target_value = target_value * (ADS1X1X_PGA_VALUE[self.chip.pga] / \
                                           self.chip.adc_voltage)
sample = 8192
target_value = sample / 32767.0
0.30 = target_value * (6.144 / 5)

The min/max filter is provided by the defined limits in the temperature_sensor, which is omitted in your configuration, so I think they should be 0…1

If you need to, you can print out a sample value by logging.info(sample) in the code above.
Like checking the expected value from the sensor.

Thermistors are inversely mapped from that range, using thermistor data points and pull-up resistance (4.7k by default).

Hope it helps.

This was very helpful. I was able to find the issue by adding the “logging.info” lines you suggested. Turns out, one of the pins I was sampling has a bad (open) thermistor connected.

I didn’t swap all the thermistors I was using, just 1 of them, then assumed all the other ones were ok. Turns out, 1 is not.

Thank You!

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.