Direct Acting Bed PID

Basic Information:

Printer Model: Creality K1 Max
MCU / Printerboard: Creality
Host / SBC: Klipper/Mainsail

Describe your issue:

Installed Mandala Rose Works bed with new Keenovo heater on my K1Max last night. Got home from work tonight, buttoned everything up and put power to the printer to test. Bed heater came up as normal, albeit a bit quicker with this heater. Temp stabilized at 100C and I held it there for about an hour to heat soak everything. Ran some bed mesh scans to see where things netted out with new bed and decided to print some spacers to get everything dialed in. Mid print the printer shut down on bed not heating properly. It appeared to have dropped below 90C. I restarted the printer and the bed heated back up as normal. I restarted the spacer print and noticed that while the bed was heating, the PID was reversed. Meaning when 100% power was applied, the temp would drop and as the PID would correct with a lower value, say 50-20% the temp would increase. It was very inefficient with that type of control and could only maintain temp to 98-99 degrees.

I’ve since run the BEDPID macro in Fluuid and the heater performed flawlessly. Setpoint 100C and it would cycle between setpoint of 95 and 100 to tune. 100% PID output would heat fast
klippy.log (7.4 MB)
and anything less would cool. When tune process was completed, it saved the values and restarted Klipper. Upon restart, heater is doing the same thing. 100% PID output and bed cools, anything less than 100% will heat, but because it appears reversed it can never quite get to the 100C setpoint. Any ideas? TIA

You have no “SAVE_CONFIG” section at the bottom of your Printer.cfg so it didn’t save the settings. You have to run “SAVE_CONFIG” when it’s done per the message when auto tune is complete.

Also, you’ve got some weird error somewhere but I have no idea what.

Webhooks is spitting out a ton of garbage with every possible gcode request.
I’m no expert in that section so no idea, it’s just a lot of spam.

[INFO] 2024-04-12 10:11:06,785 [root] [webhooks:_handle_query:554] _handle_query after complete.wait:

and then like 100 lines of spam

Also, I don’t mean to be nosy but unless you live in Central Asia your clock might be wrong. (Making an assumption since Mandela Roseworks is in the U.S. and you seem like a native English speaker)

Thanks for the reply!
So after the BEDPID tune, Klipper says it’s saving the new PID settings and restarts automagically. I was assuming it was saving because after the autotune the PID values are commented out in the printer.cfg file. Is there an auto-restart feature that can be disabled so I can manually call the SAVE_CONFIG?
Also, no idea about the webhooks…maybe Creality is sending my search history back to the Mainland?
I’ve also changed the clock to match my location. Forgot after resetting back to default and re-rooting earlier this evening in hopes of figuring this out.
Thanks again.

I’m re-running PID_CALIBRATE HEATER=heater_bed TARGET=50 instead of the macro and will call SAVE_CONFIG manually to see if that helps.

That didn’t work. Still cooling at 100% and heating at lower %. Unable to maintain setpoint reliably. Video link attached.


Paste your new Klippy.log after you ran the PID tuning with the actual command and not the macro.

Also, That’s super interesting about the webhooks and sending data back comment.

@Sineos - This seems to be your cup of tea. Check out their Klipper log in the original post and the spamming of the webhooks.

I made an offhand comment that their webhook clock was +6 GMT or so which seemed odd considering they seemed to be an English speaker buying parts in the U.S.

They mentioned maybe Creality is sending data back. Don’t they have their own fork of Klipper? I’m kind of curious to what it’s doing now and what they’re collecting.

Edit: The clock being on China time makes sense due to it being Creality. That didn’t click when I first read the post. Still interesting on the webhooks side.

1 Like

I do not really like to comment on these Creality machines, as they are using modified Klipper versions and are violating its license.

Maybe for some reason, the pin controlling the heater is reversed. Try setting

heater_pin = PC8


heater_pin = !PC8

Edit: Mixed up extruder with bed. Corrected now


Thanks, @TheFuzzyGiggler. I’ll re-run and post my log tonight after work. Day job always seems to get in the way of printing

Thanks, @Sineos. I’ll make this change and test tonight. For my understanding, could you explain what exactly the ! is reversing on the pin?

What are your thoughts on the PID operation in my video? This was taken during “normal” operation. Like I said in the original post, during BEDPID tuning, the PID acts completely normal. 100% = heating, Less than 100% = cooling. (I have confirmed this with voltage readings on the controller.) Once the BEDPID is complete though, the PID returns to the seemingly reverse operation shown in the video.

As for Creality, I believe they were actually in violation of the Klipper license. They had created their own fork and the proceeded to lock it down. The community called them on it and they have since opened up root access. As far as I know, the Klipper install we are all using is the full version

Here is my latest .log with BEDPID run from the command line and manually calling SAVE_CONFIG.
klippy.log (1.2 MB)

Unfortunately this drove the heater to heat in the OFF state with a SP of 0.

One thing I see is that creality did some weirdness with the heater bed class.

        self.max_temp = config.getfloat('max_temp', above=0.0)
    def cmd_M140(self, gcmd, wait=False):
        # Set Bed Temperature
        temp = gcmd.get_float('S', 0.)
        if temp > self.max_temp - 15.0:
            temp = self.max_temp - 15.0

The bed temp will ALWAYS be at least 15 degrees cooler than the “max temp”.

The bed will be 15 degrees cooler than the max temp is there is an attempt to set the temp higher than the max temp.

Plus it looks like there are macros that are setting the bed max temp in them

[gcode_macro G29]
gcode = 
	{% if 'PROBE_COUNT' in params|upper %}
	{% set get_count = ('PROBE_COUNT' + params.PROBE_COUNT) %}
	{%else %}
	{% set get_count = "" %}
	{% endif %}
	{% set bed_temp = printer.custom_macro.default_bed_temp %}
	{% set extruder_temp = printer.custom_macro.g28_ext_temp %}
	{% set nozzle_clear_temp = printer.custom_macro.default_extruder_temp %}
	{% if 'BED_TEMP' in params|upper %}
	{% set bed_temp = params.BED_TEMP %}
	{% endif %}
	{% if 'EXTRUDER_TEMP' in params|upper %}
	{% set nozzle_clear_temp = params.EXTRUDER_TEMP %}
	{% endif %}
{nozzle_clear_temp} **BED_MAX_TEMP**={bed_temp}
	M204 S5000
	{% set y_park = printer.toolhead.axis_maximum.y/2 %}
	{% set x_park = printer.toolhead.axis_maximum.x|float - 10.0 %}
	G1 X{x_park} Y{y_park} F2000

By their own code whatever that max temp is will always be 15 degrees cooler. If it’s setting your bed temp to something lower than it later commands it’ll drop the temp by 15 additional degrees.

The big issue with this is

self.max_temp = config.getfloat('max_temp', above=0.0)

Since temp is a floating point number, and floating point numbers are notorious for rounding oddities, the following situation could occur

(exaggerated but possible)
Bed Temp Max: 100.000000000001
Bed Temp Set: 100.000000000002

Now your actual bed temp is 85 because of the heater bed code above.

Another edit:

Here’s the fun part, elsewhere in your gcode is…

default_bed_temp = 50
default_extruder_temp = 240
g28_ext_temp = 140

which is used here

	{% set **bed_temp** = **printer.custom_macro.default_bed_temp** %}
	{% set extruder_temp = printer.custom_macro.g28_ext_temp %}
	{% set nozzle_clear_temp = printer.custom_macro.default_extruder_temp %}
	{% if 'BED_TEMP' in params|upper %}
	{% set bed_temp = params.BED_TEMP %}
	{% endif %}
	{% if 'EXTRUDER_TEMP' in params|upper %}
	{% set nozzle_clear_temp = params.EXTRUDER_TEMP %}
	{% endif %}
{nozzle_clear_temp} **BED_MAX_TEMP**={**bed_temp**}

It MUST be setting that somewhere else as well. It seems like they’re jacked up and trying to set the temp and they’re setting the MAX temp. MAX temp should never change. I don’t know why you’d change it in macros. That’s what the config section is for?

This is 10000000% up to you, but have you considered flashing the NON-CREALITY Klipper to your machine? They’ve edited so much stuff and added so much junk I don’t know where to begin.

1 Like

@TheFuzzyGiggler, Thanks for the insight. That is definitely weird. What do you think the reasoning behind it is? Thermal runaway or to prevent damage?
Still trying to understand why the BEDPID macro would heat as intended and then during normal print heating, the PID wonks out. What do you recommend?

Here’s a video link of the BEDPID tuning process for comparison to my video I sent last night. As you can see here, it’s definitely acting like it should minus the slight overshoot during the tuning process.

I’m all for whatever works!. Just not sure why it doesn’t work now after just installing a new heater and bed… I was under the assumption that this was the official Klipper, but I’m surely wrong. I have been using the helper script to help facilitate the install.

Any advice on how to proceed with geting the official Klipper?

It’s the “Creality Official Klipper” aka Klipper with their tweaks.

What do you think the reasoning behind it is? Thermal runaway or to prevent damage?

I think the “idea” was to prevent the user from getting anywhere near the max temp, which is not a horrible idea but then they went and incorporated changes into the macros that changed the max temp. I think it’s a matter of unintended consequences.

Or… Trying to word this as diplomatically as possible… From my experience products that are made in China tend to be less well thought out and robust and more whatever gets them “out the door” quickly and “good enough”. Not only that, there always tends to be a distinct lack of actual understanding of the product their producing. Be it in the code, or the hardware design, or the electronics.

That doesn’t apply to Taiwan (if you controversially consider Taiwan a part of China). I’ve always looked at anything of Chinese manufacturing as a “kit” that are “assembly required” in the sense of you’re going to have to tweak things and possibly replace the crappiest parts to get a good working product.

/rant over

Any advice on how to proceed with geting the official Klipper?

I’ll have to look, but let me look at your cfg a bit more, maybe we can make it work without you having to change things too dramatically.

I don’t want you to install the “Real” Klipper and then have to go through a ton of NEW tweaks and end up saying “Damn you TheFuzzyGiggler! This was the worst idea ever!”


Do you know how to start an SSH connection as described here:

You’ll also need root access as described here

Then we can try something before you go and reinstall everything

1 Like

Apologies for the delay. I apparently hit my daily post cap as a new user. 1hr delay.
I have root and SSH.
In the meantime, I reverted back to Creality’s original OS to test and am still seeing the PID issue here. Wondering now if the new heater didn’t somehow bork something on the main board? Granted the thermistor is slightly different, but both are still a 100K. So they SHOULD react similarly.
I’m willing to try anything at this point.
I really appreciate all of you help with this!

Okay, SSH in and follow the directions here…

Also, In your [heater_bed] config section


sensor_type = NTC 100K beta 3950


sensor_type: EPCOS 100K B57560G104F

That beta 3950 sensor is deprecated in newer Klipper updates, I don’t think it was meant to be used actually.

That Github will replace your Creality heater bed file with the regular Klipper one to do away with that “Bed temp - 15 degree” weirdness and we can see if that fixes it

If installing from that repository gives you any errors let me know, I quickly threw it together based on a template I had from another respository. So I might have miskeyed something.

1 Like

I had another closer look at your video and in fact I do believe that this is intended behavior.
What is happening:

  1. The bed’s target is at 100°C
  2. Klipper heats up to 100°C with matching PID values
  3. The bed’s target snaps to 95°C
  4. PID goes to 0 since it needs to cool down

I’m actually doing something similar with my printers as some kind of “heat soaking”, i.e. I overshoot the bed temp intentionally since your bed’s printing surface always is lower than your intended target temperature due to the design / location of the bed’s temperature probe.

Might be some macro or Klipper modification that Creality has put in place (did not bother to hunt for it).

This is exactly the reason why we do not want to deal with modified Klipper versions, as the modifications can be anything from good to bad, but essentially they are all unknown to us.
This means hunting down unexpected behavior is burning a lot of time and often is a major PITA.
Especially since we are then doing this free of charge for a company who

  1. Earned a good share of money with their product (read: with Klipper)
  2. Often is not even respecting Klipper’s license (AFAIK they are still not fully compliant, despite releasing something)