Start/Config failure "Thermocouple reader fault" using MAX31865 on EBB36 v1.2 with BIQU H2 V2S Revo Extruder

Short:

  • Question: How do you configure BTT EBB36 v1.2 with MAX31865 to accurately, reliably measure temp from NTC100K thermistor like the one in a BIQU H2 V2S Revo. Asked for my V1 Engineering MP3DP v4 Repeat build.
  • Answer: Don’t. Use TH0 connector instead. MAX31865 is NOT meant for NTC100K thermistors. MAX31865 is meant for platinum based PT100 and PT1000 thermistors/thermo-couples, @Sineos’s posts has details.

Long:
Anyone able to share working config using MAX31865 on EBB36-v1.2, ideally with BIQU H2 V2S Revo, or some other 40W Revo hotend? Cheers!

Basic Information:

Printer Model: V1 Engineering MP3DP v4 Repeat
MCU / Printerboard: Octopus v1.1, EBB36 v1.2 with MAX31865, BIQU H2 V2S Revo Extruder
klippy.log (uploaded to github, pasted fragment at end of this post)
Shared my printer.cfg on github.

60 sec build montage. Tagged by 3D printing legends at the end…

Describe your issue:

Start fails with Klipper reports: SHUTDOWN, MCU ‘EBBCan’ shutdown: Thermocouple reader fault

Klippy log contains… MCU ‘EBBCan’ shutdown: Thermocouple reader fault, log line above has Fault = 129

  • Couldn’t find same/related issues in BTT’s EBB repo

  • Tried verifying my understanding of temp settings by temporarily using Generic 3950 and commenting out the Max31865 related settings. This works, but won’t be as accurate I guess. Am even considering using that as a work around if I can’t figure out the correct magic combination of Max31865 settings needed. Will requires moving 2 thermostat wires to EBB’s TH0 connector.

    sensor_type: Generic 3950
    sensor_pin: EBBCan: PA3
    

Physical layout :

Fragment from klippy.log

Receive: 93 37.930785 37.658936 17: seq: 1d, thermocouple_result oid=8 next_clock=2905037956 value=65535 fault=129
Receive: 94 38.021595 38.021319 8: seq: 1f, stepper_position oid=9 pos=0
Receive: 95 38.028713 38.024522 18: seq: 10, tmcuart_response oid=4 read=b'\n\xfaO-\x80\x00\x02\x08\xa5\xac'
Receive: 96 38.230834 38.024522 17: seq: 10, thermocouple_result oid=8 next_clock=2924237956 value=65535 fault=129
Receive: 97 38.492199 38.491783 11: seq: 12, clock clock=2921761932
Receive: 98 38.531265 38.491783 17: seq: 12, thermocouple_result oid=8 next_clock=2943437956 value=65535 fault=129
Receive: 99 38.532093 38.491783 12: seq: 12, shutdown clock=2924240736 static_string_id=Thermocouple reader fault
Transition to shutdown state: MCU 'EBBCan' shutdown: Thermocouple reader fault
Dumping gcode input 0 blocks
gcode state: absolute_coord=True absolute_extrude=True base_position=[0.0, 0.0, 0.0, 0.0] last_position=[0.0, 0.0, 0.0, 0.0] homing_position=[0.0, 0.0, 0.0, 0.0] speed_factor=0.016666666666666666 extrude_factor=1.0 speed=25.0
Reactor garbage collection: (36.520441182, 0.0, 0.0)
MCU 'mcu' shutdown: Command request
clocksync state: mcu_freq=180000000 last_clock=8080895315 clock_est=(35.554 7686589297 180010647.809) min_half_rtt=0.000110 min_rtt_time=35.670 time_avg=35.554(0.236) clock_avg=7686589297.247(42500198.138) pred_variance=22402647097.532
Dumping serial stats: bytes_write=2683 bytes_read=6461 bytes_retransmit=0 bytes_invalid=0 send_seq=232 receive_seq=232 retransmit_seq=0 srtt=0.000 rttvar=0.000 rto=0.025 ready_bytes=0 upcoming_bytes=0
Dumping send queue 100 messages
static void
thermocouple_handle_max31865(struct thermocouple_spi *spi
                             , uint32_t next_begin_time, uint8_t oid)
{
    uint8_t msg[4] = { MAX31865_RTDMSB_REG, 0x00, 0x00, 0x00 };
    spidev_transfer(spi->spi, 1, 3, msg);
    uint32_t value;
    memcpy(&value, msg, sizeof(value));
    value = (be32_to_cpu(value) >> 8) & 0xffff;
    // Read faults
    msg[0] = MAX31865_FAULTSTAT_REG;
    msg[1] = 0x00;
    spidev_transfer(spi->spi, 1, 2, msg);
    uint8_t fault = (msg[1] & ~0x03) | (value & 0x0001);
    thermocouple_respond(spi, next_begin_time, value, fault, oid);
}

...

static void
thermocouple_respond(struct thermocouple_spi *spi, uint32_t next_begin_time
                     , uint32_t value, uint8_t fault, uint8_t oid)
{
    sendf("thermocouple_result oid=%c next_clock=%u value=%u fault=%c",
          oid, next_begin_time, value, fault);
    /* check the result and stop if below or above allowed range */
    if (fault || value < spi->min_value || value > spi->max_value) {
        spi->invalid_count++;
        if (spi->invalid_count < spi->max_invalid)
            return;
        try_shutdown("Thermocouple reader fault");
    }
    spi->invalid_count = 0;
}

Cheers!

Edit: Digging through spec for fault codes/causes MAX31865 RTD-to-Digital Converter - Analog Devices https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31865.pdf (fault detection logic flow is described on p12). New to this, but maybe fault 129 == 0x81 is measured resistance being higher than threshold. Double checked DIP switches, and checked their continuity in on/off positions.

I’m a bit confused regarding your issue. The MAX31865 is specifically and only designed to handle PT100 / PT1000 probes. It will never work with a NTC. What do you want to achieve?

1 Like

:man_facepalming:

Thank you @Sineos. Am learning, sorry for my ignorance. Am trying to get my EBB36 and BIQU H2 V2S Revo Extruder setup. When ordering the EBB36, the marketing blurb led me to believe MAX31865 was a good thing for reliable, stable readings.

I was clueless about the NTC thermistor not being compatible with MAX31865. Sounds like you’re expecting I just plug into EBB36’s TH0 and don’t bother with MAX31865?

fwiw MAX31865 spec does contain “Other resistive sensors, such as thermistors (NTCs or PTCs) may be used”.

That said, am happy not using MAX31865 for my build if that’s the guidance from you/forum. LOL, despite the misplaced emotional attachment having paid more, and despite spending time figuring out the fault logic/spec/code, and related library code even :man_facepalming:

Was going to tweak thermocouple.c to better understand what’s happening. Ditching that though, and moving on to the next setup step…

1 Like

Exactly.
Some words of explanation: The temperature measurement works by measuring a voltage drop over the probe’s resistance and converting it to a digital value.

A NTC100K has a resistance of around 100 000 Ohm (depending on the temperature) and as such it is easy to measure a voltage drop

Because the resistance of the PT100 (=100 Ohm) or PT1000 (=1000 Ohm) is so small, you need a dedicated amplifier for the measurement, which is e.g. the MAX31865

1 Like

Thanks for the info. That helps explain why I was seeing the same behavior with 100k resistor earlier during my deluded attempt at eliminating the hotend thermistor and wiring from the equation, was trying to root cause. Not knowing PT100 is just 100 Ohm, LOL.

image

You saved me a bunch of time. I was potentially going to burn time reading/writing the high/low fault threshold registers :slight_smile:

Cheers!

1 Like

In our company we have a saying, the roughly goes like: “Experience is what you get, when you do not get what you want”

So, even if it was just a learning experience, I appreciate your systematical approach and the fact that you tried to really dig into it before blindly crying for help :slight_smile:

3 Likes