Ender 3 Pro で印刷しようとすると、しばしば以下の問題が発生する。
- 問題1
- 高温での印刷が必要な PETG や ABS を出力しようとすると、
Heating failed, system stopped! Heater_ID: 0 - Printer halted. kill() called!
というエラーメッセージが表示されてけたたましい警告音が流れる。この問題が発生すると、本体の再起動が必要になる。 - 問題2
- オートレベリング中に設定温度が0℃になり、印刷できなくなる。この問題が発生すると、印刷を中止する必要がある。
そのため、この問題を解決するべく Marlin の設定を色々調べたので、その結果を備忘録として記録することにした。
この問題は、Marlin の「Thermal Runaway Protection」という機能が原因で発生している。
Configuration.h
にこの機能の簡単な説明があり、そこでは、問題が起きたら Configuration_adv.h
を編集するよう指示されている。
//Configuration.h line: 578-597
//===========================================================================
//======================== Thermal Runaway Protection =======================
//===========================================================================
/**
* Thermal Protection provides additional protection to your printer from damage
* and fire. Marlin always includes safe min and max temperature ranges which
* protect against a broken or disconnected thermistor wire.
*
* The issue: If a thermistor falls out, it will report the much lower
* temperature of the air in the room, and the the firmware will keep
* the heater on.
*
* If you get "Thermal Runaway" or "Heating failed" errors the
* details can be tuned in Configuration_adv.h
*/
/**
* 翻訳
* サーマルプロテクションは、プリンタを損傷と火災から守るための追加の防御を提供します。Marlin は、サーミスタワイヤの故障や脱落に対抗して最小温度と最大温度の間で安全を守ります。
* 課題: サーミスタがフォールアウトした場合、室温より低い温度が報告され、ファームウェアはヒーターを温め続けます。
* もし、"Thermal Runaway" や "Heating failed" エラーに遭遇した場合、`Configuration_adv.h` を調整します。
*/
#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders
#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed
#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber
//Configuration_adv.h line:174-301
/**
* Thermal Protection provides additional protection to your printer from damage
* and fire. Marlin always includes safe min and max temperature ranges which
* protect against a broken or disconnected thermistor wire.
*
* The issue: If a thermistor falls out, it will report the much lower
* temperature of the air in the room, and the the firmware will keep
* the heater on.
*
* The solution: Once the temperature reaches the target, start observing.
* If the temperature stays too far below the target (hysteresis) for too
* long (period), the firmware will halt the machine as a safety precaution.
*
* If you get false positives for "Thermal Runaway", increase
* THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD
*/
/**
* 翻訳
* サーマルプロテクションは、プリンタを損傷と火災から守るための追加の防御を提供します。Marlin は、サーミスタワイヤの故障や脱落に対抗して最小温度と最大温度の間で安全を守ります。
*
* 課題: サーミスタがフォールアウトした場合、室温より低い温度が報告され、ファームウェアはヒーターを温め続けます。
*
* 解決策: いったん設定温度に達すると、監視が始まります。もし、温度が設定温度 ( hysteresis ) を設定した時間 (period) より長い時間下回っている場合、ファームウェアは安全措置として機械を停止させます。
*
* もし、"Thermal Runaway" の偽陽性に遭遇する場合、THERMAL_PROTECTION_HYSTERESIS と THERMAL_PROTECTION_PERIOD の両方または片方の値を増やしてください。
*/
/**
* Whenever an M104, M109, or M303 increases the target temperature, the
* firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature
* hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and
* requires a hard reset. This test restarts with any M104/M109/M303, but only
* if the current temperature is far enough below the target for a reliable
* test.
*
* If you get false positives for "Heating failed", increase WATCH_TEMP_PERIOD
* and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set
* below 2.
*/
/**
* 翻訳
* M104、M109 または M303 が設定温度を増加させるときはいつでも、ファームウェアは WATCH_TEMP_PERIOD が終了するのを待ちます。
* もし、温度が WATCH_TEMP_INCREASE の温度分だけ上昇しなかった場合、機械は停止され、ハードリセットを要求します。このテストは M104/M109/M303 を再起動しますが、現在の温度が設定温度から充分低いときだけ信頼できます。
*
* もし、"Heating failed" の偽陽性に遭遇する場合、WATCH_TEMP_PERIOD の増やすか、WATCH_TEMP_INCREASE を減らすか、またはその両方を行ってください。ただし、WATCH_TEMP_INCREASE を2以下にするべきではありません。
*/
また、エラーメッセージの Heating failed, system stopped! Heater_ID: 0 - Printer halted. kill() called!
の Heating failed
の部分は、language.h
で STR_T_HEATING_FAILED
定数として定義されている。
language.h
には "Thermal Runaway" というメッセージが STR_T_THERMAL_RUNAWAY
という定数で定義されていることから、私が遭遇したエラーは、上記のコメントにある「"Thermal Runaway" の偽陽性」と「"Heating failed" の偽陽性」のうち、「"Heating failed" の偽陽性」であると判明した。
次に、ホットエンドとベッドのどちらでエラーが発生しているかが問題となるが、エラーメッセージに Heater_ID: 0
と表示され、temperature.h
で定義されている heater_id_t
定数のコメントに「Heater identifiers. Positive values are hotends. Negative values are other heaters.」と記述されているため、エラーはホットエンドで発生していると思われる。
// temperature.h line:43-48
// Heater identifiers. Positive values are hotends. Negative values are other heaters.
typedef enum : int8_t {
INDEX_NONE = -5,
H_PROBE, H_REDUNDANT, H_CHAMBER, H_BED,
H_E0, H_E1, H_E2, H_E3, H_E4, H_E5, H_E6, H_E7
} heater_id_t;
この問題は、Marlin の "Hoten Idle Timeout" 機能が原因で発生している。問題が発生した時の OctoPrint の Terminal にも「Hotend Idle Timeout
」と出力されている。
この機能の説明は、Configuration_adv.h
にあるが、コメントには「Time without extruder movement to trigger protection」とあることから、オートレベリングでエクストルーダーが動いていれば発動しないように見える。
しかし、この機能の実装を hotend_idle.h
と hotend_idle.cpp
で確認すると、フィラメントが送り出されている状態を「エクストルーダーが動いている状態」と判定していた。よって、次のような流れで問題が発生したものと思われる。
- ホットエンドとベッドが室温とほぼ同じ温度になっている。
- その状態から、例えば、PETG 印刷のためにホットエンドを250℃、ベッドを80℃まで加熱しようとする。
- ホットエンドは速やかに目標温度に達するが、ベッドの加熱は遅いので、ホットエンドは目標温度に達してから印刷まで待たされることになる。
- ベッドが目標温度に到達してからオートレベリングが始まるが、BLTouch によるオートレベリングは2分以上かかる。
- ホットエンドはオートレベリングが始まる時点で待機状態にあるため、オートレベリング中に
HOTEND_IDLE_TIMEOUT_SEC
で設定した時間が経過し、時間切れとなってしまう。
//Configuration_adv.h line: 372-381
/**
* Hotend Idle Timeout
* Prevent filament in the nozzle from charring and causing a critical jam.
* (翻訳)ノズル内のフィラメントが焦げ付き、致命的な詰まりの原因となることを防ぐ。
*/
#define HOTEND_IDLE_TIMEOUT
#if ENABLED(HOTEND_IDLE_TIMEOUT)
#define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection
#define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection
#define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout
#define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout
#endif
// hotend_idle.h line: 25-35
class HotendIdleProtection {
public:
static void check();
private:
static constexpr millis_t hp_interval = SEC_TO_MS(HOTEND_IDLE_TIMEOUT_SEC);
static millis_t next_protect_ms;
static void check_hotends(const millis_t &ms);
static void check_e_motion(const millis_t &ms);
static void timed_out();
};
// hotend_idle.cpp line: 43-72
void HotendIdleProtection::check_hotends(const millis_t &ms) {
bool do_prot = false;
HOTEND_LOOP() {
if (thermalManager.degHotend(e) >= HOTEND_IDLE_MIN_TRIGGER) {
do_prot = true; break;
}
}
if (bool(next_protect_ms) != do_prot)
next_protect_ms = do_prot ? ms + hp_interval : 0;
}
void HotendIdleProtection::check_e_motion(const millis_t &ms) {
static float old_e_position = 0;
if (old_e_position != current_position.e) {
old_e_position = current_position.e; // Track filament motion
if (next_protect_ms) // If some heater is on then...
next_protect_ms = ms + hp_interval; // ...delay the timeout till later
}
}
void HotendIdleProtection::check() {
const millis_t ms = millis(); // Shared millis
check_hotends(ms); // Any hotends need protection?
check_e_motion(ms); // Motion will protect them
// Hot and not moving for too long...
if (next_protect_ms && ELAPSED(ms, next_protect_ms))
timed_out();
}
室温が低くて加熱中の温度の揺らぎで「指定時間内に指定した温度だけ冷めしまい、Heating failed の偽陽性と認識されてしまう」ことがエラーの原因なので、指定時間を延長するとともに指定温度を上げて、加熱中の温度の揺らぎでエラーが発生しないようにした。
// Configuration_adv.h
- #define WATCH_TEMP_PERIOD 20 // Seconds
- #define WATCH_TEMP_INCREASE 2 // Degrees Celsius
+ #define WATCH_TEMP_PERIOD 60 // Seconds
+ #define WATCH_TEMP_INCREASE 5 // Degrees Celsius
- #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius
+ #define WATCH_BED_TEMP_INCREASE 4 // Degrees Celsius
ホットエンドが設定温度に到達して待機状態に入ってから実際に印刷が始まるまでの時間が長く、タイムアウト時間を超過してしまうことがエラーの原因なので、タイムアウト時間を長くすることにした。
// Configuration_adv.h
- #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection
+ #define HOTEND_IDLE_TIMEOUT_SEC (10*60) // (seconds) Time without extruder movement to trigger protection