Klipper does not shutdown pin when host is not reachable

Hello,

I want to switch off a pin of the mcu when the host is not reachable.
The shutdown value is set to “0” but the pin still remains “1” if i power off the PI.

If I active a heater and power off the Pi the pin is set to “0”.
I searched really long but could not find an answer. I think it has to do something with the safety feature for the heaters.

config_digital_out oid=%c pin=%u value=%c default_value=%c max_duration=%u : This command creates an internal micro-controller object for the given GPIO ‘pin’. The pin will be configured in digital output mode and set to an initial value as specified by ‘value’ (0 for low, 1 for high). Creating a digital_out object allows the host to schedule GPIO updates for the given pin at specified times (see the schedule_digital_out command described below). Should the micro-controller software go into shutdown mode then all configured digital_out objects will be set to ‘default_value’. The ‘max_duration’ parameter is used to implement a safety check - if it is non-zero then it is the maximum number of clock ticks that the host may set the given GPIO to a non-default value without further updates. For example, if the default_value is zero and the max_duration is 16000 then if the host sets the gpio to a value of one then it must schedule another update to the gpio pin (to either zero or one) within 16000 clock ticks. This safety feature can be used with heater pins to ensure the host does not enable the heater and then go off-line.

Why do I need this? The pin is connected to a relay which powers the rest of the printer so I want to shut down the PI (host unreachable) and then everything should go off.
Also it is a safety feature if the mcu goes to shutdown the main power should be turned off.

I dont know how to set up a pin that has the same hehaviour as a heater pin. Thank you very much for your help.

With a config like this, a configured mcu should set the pin PA13 to low when it shutdowns after loosing communication to the host:

[output_pin my_shutdown_pin]
pin: PA13
value: 1
shutdown_value: 0

However, when the mcu hasn’t been connected to the host since the last reset or power up, it cannot remember about the pin configuration and will use the default hardware configuration.
The solution is to set in make menuconfig: GPIO pins to set at micro-controller startup: !PA13 (then build and reflash). This instruct the mcu to set the pin low at startup before the configuration is received.

The pin might still get a transient high state during the interval between the mcu reset and standalone mcu initialization. I’d recommend a pin that is low at hardware initialization. But, for safety, I’d set the pin in the mcu’s build config anyway.

When there is no heaters activated, the mcu can take some time to realize that the communication is lost. Setting maximum_mcu_duration: 0.5 in [output_pin] will configure a watchdog, shortening the response time at the cost of more bandwidth usage.

Of course, the mcu that generate the relay signal have to be powered by a standby power source. This is not always the case since some people recommend disconnecting the USB 5V.

Thank you for your help.

The problem is if I trigger “STOP” then the pin PA13 in your example is low. So it works as expected.
If i disconnect the USB cable between MCU and host, the pin PA13 still stays “1”.

I just want to have the behaviour of a heater pin. Shutdown = 0 ; Host Connection Lost = 0;
I have also found the maximum_mcu_duration value but it says start_value and shutdown_value have to be the same value.

But I need a “1” at startup and a “0” when shutdown.
If everything fails i will take an arduino and write the simple code by myself.

It worked for me in the example above. What error message do you get?
It won’t work with static_value, you have to use a dynamic output_pin (value:)

Thank you, I am one step further. If i set a pin to start_value 0 and shutdown_value 0 and set it per gcode including the max_duration value then the pin is “0” if the host times out.

The error tells me that start_value and shutdown_value have to be the same.

Can you help me with static_value and dynamic output_pin?

Ah I know what you mean:

[static_digital_output]

[output_pin]

I am using the output_pin

Yes, but I need the exact error string to look it up in the code.

Right, but you also have use value: instead of static_value: in that output_pin section.

This worked in my tests:

[output_pin my_shutdown_pin]
pin: PA13
value: 1
shutdown_value: 0
maximum_mcu_duration: 2

Pin with max duration must have start value equal to shutdown value

Once the underlying issue is corrected, use the “RESTART”
command to reload the config and restart the host software.
Printer is halted

[output_pin power]
pin: PD15
shutdown_value: 0
value: 1
maximum_mcu_duration: 5

Everything is up to date :slight_smile:

My bad, that was actually my problem. I haven’t updated before testing…

Two week ago this commit added the check:

So it appears that it didn’t worked correctly in the past and, out of concerns, Kevin added the checks.
It seemed to work ok for me, but maybe I’ve missed a edge cases.

PWM pins (and thus heaters) have the same restriction. But the start value for heaters is always 0.0.

I guess you’ll have to comply to that restriction in [output_pin], and use a delayed gcode to set the pin:

[delayed_gcode set_power_enable]
initial_duration: 0.1
gcode:
   SET_PIN PIN=power VALUE=1

But this feels a bit hacky (initial_duration can’t be 0).

Really really thank you for your help.
I “wasted” about 10 hours for that problem because I thought it has to be possible.

I think I will use an arduino because it is easier for me ^^