I’ve just added a servo to my V-Core 3 (BTT Octopus v1.1, Huvud toolboard with CAN) and have started getting shutdowns of the Octopus board, where the servo’s attached. I’m typically able to control the servo as expected, by setting the angle, but I’ve observed instances – occasionally when attempting to set a negative angle, but not always – where the mcu shuts down while commanding the servo move. This evening while attempting a first print after adding @protoloft’s z_calibration extra I’ve consistently got the mcu shutting down in the last stages of my START_PRINT macro. In this case the servo is not stopping at the commanded position (4°) and is in fact shooting clockwise over 0° to more like -45°.
Log attached. The crash happens during the execution of CALIBRATE_Z in START_PRINT, while the DEPLOY_PROBE macro is being invoked by z_calibration.before_switch_gcode. I’ll play around with it more tomorrow. klippy.log.zip (372.2 KB)
I have checked my log. That macro has been in use for months, long before I added the custom extra. The timeout occurs before the toolhead has even moved into the position where the assertion in the macro is checked, so the mcu has already crashed at that point.
action_raise_error is what’s causing the macro to error out in the previous case; should that be killing the mcu?
Just reproduced the shutdown merely by sending SET_SERVO commands. I removed the extra from the klipper source tree, and removed the config entry. Restarted klipper. Started sending SET_SERVO commands.
Note the console output is bottom-up. I can’t tell if the SET_SERVO SERVO=euclid width=0 command was processed before the error.
You are using extra modules which do not belong to the official Klipper main line.
No developer will consider looking at modified sources that have an unknown effect on overall stability / functionality.
I reproduced the mcu crash, although through brute force.
No extras, clean tree:
pi@vcore3:~/ksrc $ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
pi@vcore3:~/ksrc $ git rev-parse HEAD
24a1b50e512f3038a51060e3cc8ce2a847b9fafa
pi@vcore3:~/ksrc $ git ls-files --other | grep -E -v '^out/|\.pyc$'
.config
.config.old
klippy/chelper/c_helper.so
lib/hidflash/hid-flash
lib/hidflash/hid-libusb.o
lib/hidflash/main.o
lib/hidflash/rs232.o
macro to exercise the servo:
[gcode_macro servo_loop]
gcode:
M117 start loop
{% for _ in range(0, 10) %}
M117 reset sweep
SET_SERVO SERVO=euclid ANGLE=90
G4 P750
{% for a in range(85, 0, -5) %}
M117 moving to { a }
SET_SERVO SERVO=euclid ANGLE={ a }
G4 P750
{% endfor %}
{% endfor %}
M117 end loop
Strange indeed. Seems to work for a while and then error out. Have you tried a longer delay in between the steps?
Otherwise no further idea, how to debug this. Maybe @koconnor could jump in.
I’ve tried longer and shorter delays with this loop. Sometimes it’ll run for a few complete sweeps before crashing, as it did here, other times it crashes after 5-6 steps.
Since this seems to be happening when moving the servo, be sure to look for frayed / crimped wires on, near, or in the servo. A good test would be to physically disconnect the servo and see if the commands still cause a failure.
Interestingly, with the servo disconnected I’m not able to reproduce the problem, yet. How could that be? The servo’s just PWM-controlled, right? Why would it being connected or not affect the MCU?
As soon as I reconnect the servo I’m able to reproduce the crash. Disconnecting it and the loop completes. If I increase the time between servo moves to 3000ms the loop will run to completion, but even as low as 2000ms and the mcu crashes.
[time passes]
And switching to a different servo with a much longer cable (the one I was originally using when I discovered this problem), I can reproduce the crash with a delay as long as 5s. 6s seems to make it more reliable, but sometimes the servo doesn’t respond to a commanded move for some time (> 1s or more).
[more time passes]
Even with a 6s delay the mcu eventually crashed with the long-cabled servo attached.
Indeed interesting. The servo has no back-channel, so no information are transferred back to the MCU. Basically it is just an electrical load. Tried a different servo?
IIRC not really PWM. Servos operate with pulses between 1ms and 2ms with ~1.5ms is the neutral position. So the 90° working range are positioned with the length of the pulse. If I’m not mistaken, this does not need a PWM pin on the MCU, basically every GPIO can drive a servo.
I just edited my last post. Yes, I’ve tried two servos, with vastly different cable lengths. The longer one is more flaky, but even the short-cabled servo is problematic.