mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-29 23:07:42 +00:00
Laser Coolant Flow Meter / Safety Shutdown (#21431)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
8f509b0ae0
commit
ccdbffbf3f
@ -204,6 +204,20 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Laser Coolant Flow Meter
|
||||||
|
//
|
||||||
|
//#define LASER_COOLANT_FLOW_METER
|
||||||
|
#if ENABLED(LASER_COOLANT_FLOW_METER)
|
||||||
|
#define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21)
|
||||||
|
#define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin
|
||||||
|
#define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds
|
||||||
|
#define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
#define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thermal Protection provides additional protection to your printer from damage
|
* Thermal Protection provides additional protection to your printer from damage
|
||||||
* and fire. Marlin always includes safe min and max temperature ranges which
|
* and fire. Marlin always includes safe min and max temperature ranges which
|
||||||
@ -1539,6 +1553,7 @@
|
|||||||
#define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating
|
#define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating
|
||||||
//#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active
|
//#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active
|
||||||
//#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling
|
//#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling
|
||||||
|
//#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow
|
||||||
//#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap
|
//#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap
|
||||||
//#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap
|
//#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap
|
||||||
//#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames
|
//#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames
|
||||||
|
@ -130,6 +130,7 @@
|
|||||||
#define STR_COUNT_A " Count A:"
|
#define STR_COUNT_A " Count A:"
|
||||||
#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required."
|
#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required."
|
||||||
#define STR_ERR_KILLED "Printer halted. kill() called!"
|
#define STR_ERR_KILLED "Printer halted. kill() called!"
|
||||||
|
#define STR_FLOWMETER_FAULT "Coolant flow fault. Flowmeter safety is active. Attention required."
|
||||||
#define STR_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
|
#define STR_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
|
||||||
#define STR_ERR_SERIAL_MISMATCH "Serial status mismatch"
|
#define STR_ERR_SERIAL_MISMATCH "Serial status mismatch"
|
||||||
#define STR_BUSY_PROCESSING "busy: processing"
|
#define STR_BUSY_PROCESSING "busy: processing"
|
||||||
|
@ -27,11 +27,21 @@
|
|||||||
#include "cooler.h"
|
#include "cooler.h"
|
||||||
Cooler cooler;
|
Cooler cooler;
|
||||||
|
|
||||||
uint16_t Cooler::flowrate; // Flow meter reading in liters, 0 will result in shutdown if equiped
|
uint8_t Cooler::mode = 0;
|
||||||
uint8_t Cooler::mode = 0; // 0 = CO2 Liquid cooling, 1 = Laser Diode TEC Heatsink Cooling
|
uint16_t Cooler::capacity;
|
||||||
uint16_t Cooler::capacity; // Cooling capacity in watts
|
uint16_t Cooler::load;
|
||||||
uint16_t Cooler::load; // Cooling load in watts
|
bool Cooler::enabled = false;
|
||||||
bool Cooler::flowmeter = false;
|
|
||||||
bool Cooler::state = false; // on = true, off = false
|
|
||||||
|
|
||||||
|
#if ENABLED(LASER_COOLANT_FLOW_METER)
|
||||||
|
bool Cooler::flowmeter = false;
|
||||||
|
millis_t Cooler::flowmeter_next_ms; // = 0
|
||||||
|
volatile uint16_t Cooler::flowpulses;
|
||||||
|
float Cooler::flowrate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
bool Cooler::flowsafety_enabled = true;
|
||||||
|
bool Cooler::fault = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // HAS_COOLER
|
||||||
|
@ -21,30 +21,91 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#define _MSG_COOLER(M) MSG_COOLER_##M
|
#ifndef FLOWMETER_PPL
|
||||||
#define MSG_COOLER(M) _MSG_COOLER(M)
|
#define FLOWMETER_PPL 5880 // Pulses per liter
|
||||||
|
#endif
|
||||||
|
#ifndef FLOWMETER_INTERVAL
|
||||||
|
#define FLOWMETER_INTERVAL 1000 // milliseconds
|
||||||
|
#endif
|
||||||
|
|
||||||
// Cooling device
|
// Cooling device
|
||||||
|
|
||||||
class Cooler {
|
class Cooler {
|
||||||
public:
|
public:
|
||||||
static uint16_t flowrate; // Flow meter reading in liters, 0 will result in shutdown if equiped
|
|
||||||
static uint8_t mode; // 0 = CO2 Liquid cooling, 1 = Laser Diode TEC Heatsink Cooling
|
|
||||||
static uint16_t capacity; // Cooling capacity in watts
|
static uint16_t capacity; // Cooling capacity in watts
|
||||||
static uint16_t load; // Cooling load in watts
|
static uint16_t load; // Cooling load in watts
|
||||||
static bool flowmeter;
|
|
||||||
static bool state; // on = true, off = false
|
|
||||||
|
|
||||||
static bool is_enabled() { return state; }
|
static bool enabled;
|
||||||
static void enable() { state = true; }
|
static void enable() { enabled = true; }
|
||||||
static void disable() { state = false; }
|
static void disable() { enabled = false; }
|
||||||
|
static void toggle() { enabled = !enabled; }
|
||||||
|
|
||||||
|
static uint8_t mode; // 0 = CO2 Liquid cooling, 1 = Laser Diode TEC Heatsink Cooling
|
||||||
static void set_mode(const uint8_t m) { mode = m; }
|
static void set_mode(const uint8_t m) { mode = m; }
|
||||||
static void set_flowmeter(const bool sflag) { flowmeter = sflag; }
|
|
||||||
static uint16_t get_flowrate() { return flowrate; }
|
#if ENABLED(LASER_COOLANT_FLOW_METER)
|
||||||
static void update_flowrate(uint16_t flow) { flowrate = flow; }
|
static float flowrate; // Flow meter reading in liters-per-minute.
|
||||||
//static void init() { set_state(false); }
|
static bool flowmeter; // Flag to monitor the flow
|
||||||
|
static volatile uint16_t flowpulses; // Flowmeter IRQ pulse count
|
||||||
|
static millis_t flowmeter_next_ms; // Next time at which to calculate flow
|
||||||
|
|
||||||
|
static void set_flowmeter(const bool sflag) {
|
||||||
|
if (flowmeter != sflag) {
|
||||||
|
flowmeter = sflag;
|
||||||
|
if (sflag) {
|
||||||
|
flowpulses = 0;
|
||||||
|
flowmeter_next_ms = millis() + FLOWMETER_INTERVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To calculate flow we only need to count pulses
|
||||||
|
static void flowmeter_ISR() { flowpulses++; }
|
||||||
|
|
||||||
|
// Enable / Disable the flow meter interrupt
|
||||||
|
static void flowmeter_interrupt_enable() {
|
||||||
|
attachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN), flowmeter_ISR, RISING);
|
||||||
|
}
|
||||||
|
static void flowmeter_interrupt_disable() {
|
||||||
|
detachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable / Disable the flow meter interrupt
|
||||||
|
static void flowmeter_enable() { set_flowmeter(true); flowpulses = 0; flowmeter_interrupt_enable(); }
|
||||||
|
static void flowmeter_disable() { set_flowmeter(false); flowmeter_interrupt_disable(); flowpulses = 0; }
|
||||||
|
|
||||||
|
// Get the total flow (in liters per minute) since the last reading
|
||||||
|
static void calc_flowrate() {
|
||||||
|
//flowmeter_interrupt_disable();
|
||||||
|
// const uint16_t pulses = flowpulses;
|
||||||
|
//flowmeter_interrupt_enable();
|
||||||
|
flowrate = flowpulses * 60.0f * (1000.0f / (FLOWMETER_INTERVAL)) * (1000.0f / (FLOWMETER_PPL));
|
||||||
|
flowpulses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Userland task to update the flow meter
|
||||||
|
static void flowmeter_task(const millis_t ms=millis()) {
|
||||||
|
if (!flowmeter) // !! The flow meter must always be on !!
|
||||||
|
flowmeter_enable(); // Init and prime
|
||||||
|
if (ELAPSED(ms, flowmeter_next_ms)) {
|
||||||
|
calc_flowrate();
|
||||||
|
flowmeter_next_ms = ms + FLOWMETER_INTERVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
static bool fault; // Flag that the cooler is in a fault state
|
||||||
|
static bool flowsafety_enabled; // Flag to disable the cutter if flow rate is too low
|
||||||
|
static void flowsafety_toggle() { flowsafety_enabled = !flowsafety_enabled; }
|
||||||
|
static bool check_flow_too_low() {
|
||||||
|
const bool too_low = flowsafety_enabled && flowrate < (FLOWMETER_MIN_LITERS_PER_MINUTE);
|
||||||
|
if (too_low) fault = true;
|
||||||
|
return too_low;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Cooler cooler;
|
extern Cooler cooler;
|
||||||
|
@ -215,7 +215,6 @@ public:
|
|||||||
static inline void disable() { isReady = false; set_enabled(false); }
|
static inline void disable() { isReady = false; set_enabled(false); }
|
||||||
|
|
||||||
#if HAS_LCD_MENU
|
#if HAS_LCD_MENU
|
||||||
|
|
||||||
static inline void enable_with_dir(const bool reverse) {
|
static inline void enable_with_dir(const bool reverse) {
|
||||||
isReady = true;
|
isReady = true;
|
||||||
const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255);
|
const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255);
|
||||||
@ -245,8 +244,8 @@ public:
|
|||||||
* If not set defaults to 80% power
|
* If not set defaults to 80% power
|
||||||
*/
|
*/
|
||||||
static inline void test_fire_pulse() {
|
static inline void test_fire_pulse() {
|
||||||
enable_forward(); // Turn Laser on (Spindle speak but same funct)
|
|
||||||
TERN_(USE_BEEPER, buzzer.tone(30, 3000));
|
TERN_(USE_BEEPER, buzzer.tone(30, 3000));
|
||||||
|
enable_forward(); // Turn Laser on (Spindle speak but same funct)
|
||||||
delay(testPulse); // Delay for time set by user in pulse ms menu screen.
|
delay(testPulse); // Delay for time set by user in pulse ms menu screen.
|
||||||
disable(); // Turn laser off
|
disable(); // Turn laser off
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,10 @@ GcodeSuite gcode;
|
|||||||
#include "../feature/spindle_laser.h"
|
#include "../feature/spindle_laser.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
#include "../feature/cooler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(PASSWORD_FEATURE)
|
#if ENABLED(PASSWORD_FEATURE)
|
||||||
#include "../feature/password/password.h"
|
#include "../feature/password/password.h"
|
||||||
#endif
|
#endif
|
||||||
@ -278,6 +282,13 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
if (cooler.fault) {
|
||||||
|
SERIAL_ECHO_MSG(STR_FLOWMETER_FAULT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Handle a known G, M, or T
|
// Handle a known G, M, or T
|
||||||
switch (parser.command_letter) {
|
switch (parser.command_letter) {
|
||||||
case 'G': switch (parser.codenum) {
|
case 'G': switch (parser.codenum) {
|
||||||
|
@ -1895,6 +1895,10 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
|||||||
#error "TEMP_SENSOR_COOLER requires LASER_FEATURE and TEMP_COOLER_PIN."
|
#error "TEMP_SENSOR_COOLER requires LASER_FEATURE and TEMP_COOLER_PIN."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(LASER_COOLANT_FLOW_METER) && !(PIN_EXISTS(FLOWMETER) && ENABLED(LASER_FEATURE))
|
||||||
|
#error "LASER_COOLANT_FLOW_METER requires FLOWMETER_PIN and LASER_FEATURE."
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(CHAMBER_FAN) && !(defined(CHAMBER_FAN_MODE) && WITHIN(CHAMBER_FAN_MODE, 0, 2))
|
#if ENABLED(CHAMBER_FAN) && !(defined(CHAMBER_FAN_MODE) && WITHIN(CHAMBER_FAN_MODE, 0, 2))
|
||||||
#error "CHAMBER_FAN_MODE must be between 0 and 2."
|
#error "CHAMBER_FAN_MODE must be between 0 and 2."
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
#include "../../gcode/parser.h"
|
#include "../../gcode/parser.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_COOLER || HAS_FLOWMETER
|
||||||
|
#include "../../feature/cooler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||||
#include "../../feature/bedlevel/bedlevel.h"
|
#include "../../feature/bedlevel/bedlevel.h"
|
||||||
#endif
|
#endif
|
||||||
@ -517,6 +521,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
|
|||||||
lcd_put_u8str(value);
|
lcd_put_u8str(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) {
|
FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) {
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0);
|
const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0);
|
||||||
@ -550,6 +555,43 @@ FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAS_COOLER
|
||||||
|
FORCE_INLINE void _draw_cooler_status(const char prefix, const bool blink) {
|
||||||
|
const float t1 = thermalManager.degCooler(), t2 = thermalManager.degTargetCooler();
|
||||||
|
|
||||||
|
if (prefix >= 0) lcd_put_wchar(prefix);
|
||||||
|
|
||||||
|
lcd_put_u8str(i16tostr3rj(t1 + 0.5));
|
||||||
|
lcd_put_wchar('/');
|
||||||
|
|
||||||
|
#if !HEATER_IDLE_HANDLER
|
||||||
|
UNUSED(blink);
|
||||||
|
#else
|
||||||
|
if (!blink && thermalManager.heater_idle[thermalManager.idle_index_for_id(heater_id)].timed_out) {
|
||||||
|
lcd_put_wchar(' ');
|
||||||
|
if (t2 >= 10) lcd_put_wchar(' ');
|
||||||
|
if (t2 >= 100) lcd_put_wchar(' ');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
lcd_put_u8str(i16tostr3left(t2 + 0.5));
|
||||||
|
|
||||||
|
if (prefix >= 0) {
|
||||||
|
lcd_put_wchar(LCD_STR_DEGREE[0]);
|
||||||
|
lcd_put_wchar(' ');
|
||||||
|
if (t2 < 10) lcd_put_wchar(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
FORCE_INLINE void _draw_flowmeter_status() {
|
||||||
|
lcd_put_u8str("~ ");
|
||||||
|
lcd_put_u8str(ftostr11ns(cooler.flowrate));
|
||||||
|
lcd_put_wchar('L');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
FORCE_INLINE void _draw_bed_status(const bool blink) {
|
FORCE_INLINE void _draw_bed_status(const bool blink) {
|
||||||
_draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink);
|
_draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink);
|
||||||
}
|
}
|
||||||
@ -747,6 +789,7 @@ void MarlinUI::draw_status_screen() {
|
|||||||
//
|
//
|
||||||
// Hotend 0 Temperature
|
// Hotend 0 Temperature
|
||||||
//
|
//
|
||||||
|
#if HAS_HOTEND
|
||||||
_draw_heater_status(H_E0, -1, blink);
|
_draw_heater_status(H_E0, -1, blink);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -759,12 +802,14 @@ void MarlinUI::draw_status_screen() {
|
|||||||
lcd_moveto(8, 0);
|
lcd_moveto(8, 0);
|
||||||
_draw_bed_status(blink);
|
_draw_bed_status(blink);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#else // LCD_WIDTH >= 20
|
#else // LCD_WIDTH >= 20
|
||||||
|
|
||||||
//
|
//
|
||||||
// Hotend 0 Temperature
|
// Hotend 0 Temperature
|
||||||
//
|
//
|
||||||
|
#if HAS_HOTEND
|
||||||
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);
|
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -777,6 +822,14 @@ void MarlinUI::draw_status_screen() {
|
|||||||
lcd_moveto(10, 0);
|
lcd_moveto(10, 0);
|
||||||
_draw_bed_status(blink);
|
_draw_bed_status(blink);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_COOLER
|
||||||
|
_draw_cooler_status('*', blink);
|
||||||
|
#endif
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
_draw_flowmeter_status();
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // LCD_WIDTH >= 20
|
#endif // LCD_WIDTH >= 20
|
||||||
|
|
||||||
|
@ -77,9 +77,12 @@
|
|||||||
#ifndef STATUS_CUTTER_WIDTH
|
#ifndef STATUS_CUTTER_WIDTH
|
||||||
#define STATUS_CUTTER_WIDTH 0
|
#define STATUS_CUTTER_WIDTH 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef STATUS_CUTTER_BYTEWIDTH
|
||||||
|
#define STATUS_CUTTER_BYTEWIDTH BW(STATUS_CUTTER_WIDTH)
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Laser Cooler
|
// Laser cooler
|
||||||
//
|
//
|
||||||
#if !STATUS_COOLER_WIDTH && HAS_COOLER
|
#if !STATUS_COOLER_WIDTH && HAS_COOLER
|
||||||
#include "status/cooler.h"
|
#include "status/cooler.h"
|
||||||
@ -87,6 +90,24 @@
|
|||||||
#ifndef STATUS_COOLER_WIDTH
|
#ifndef STATUS_COOLER_WIDTH
|
||||||
#define STATUS_COOLER_WIDTH 0
|
#define STATUS_COOLER_WIDTH 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef STATUS_COOLER_BYTEWIDTH
|
||||||
|
#define STATUS_COOLER_BYTEWIDTH BW(STATUS_COOLER_WIDTH)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Laser Flowmeter
|
||||||
|
//
|
||||||
|
#if !STATUS_FLOWMETER_WIDTH && HAS_FLOWMETER
|
||||||
|
#include "status/cooler.h"
|
||||||
|
#endif
|
||||||
|
#ifndef STATUS_FLOWMETER_WIDTH
|
||||||
|
#define STATUS_FLOWMETER_WIDTH 0
|
||||||
|
#endif
|
||||||
|
#ifndef STATUS_FLOWMETER_BYTEWIDTH
|
||||||
|
#define STATUS_FLOWMETER_BYTEWIDTH BW(STATUS_FLOWMETER_WIDTH)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bed
|
// Bed
|
||||||
@ -425,9 +446,7 @@
|
|||||||
//
|
//
|
||||||
// Cutter Bitmap Properties
|
// Cutter Bitmap Properties
|
||||||
//
|
//
|
||||||
#ifndef STATUS_CUTTER_BYTEWIDTH
|
#if HAS_CUTTER
|
||||||
#define STATUS_CUTTER_BYTEWIDTH BW(STATUS_CUTTER_WIDTH)
|
|
||||||
#endif
|
|
||||||
#if STATUS_CUTTER_WIDTH
|
#if STATUS_CUTTER_WIDTH
|
||||||
|
|
||||||
#ifndef STATUS_CUTTER_X
|
#ifndef STATUS_CUTTER_X
|
||||||
@ -466,6 +485,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Chamber Bitmap Properties
|
// Chamber Bitmap Properties
|
||||||
@ -511,9 +531,7 @@
|
|||||||
//
|
//
|
||||||
// Cooler Bitmap Properties
|
// Cooler Bitmap Properties
|
||||||
//
|
//
|
||||||
#ifndef STATUS_COOLER_BYTEWIDTH
|
#if HAS_COOLER
|
||||||
#define STATUS_COOLER_BYTEWIDTH BW(STATUS_COOLER_WIDTH)
|
|
||||||
#endif
|
|
||||||
#if STATUS_COOLER_WIDTH
|
#if STATUS_COOLER_WIDTH
|
||||||
|
|
||||||
#ifndef STATUS_COOLER_X
|
#ifndef STATUS_COOLER_X
|
||||||
@ -521,11 +539,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STATUS_COOLER_HEIGHT
|
#ifndef STATUS_COOLER_HEIGHT
|
||||||
#ifdef STATUS_COOLER_ANIM
|
#define STATUS_COOLER_HEIGHT(S) (sizeof(status_cooler_bmp1) / (STATUS_COOLER_BYTEWIDTH))
|
||||||
#define STATUS_COOLER_HEIGHT(S) ((S) ? sizeof(status_cooler_on_bmp) / (STATUS_COOLER_BYTEWIDTH) : sizeof(status_cooler_bmp) / (STATUS_COOLER_BYTEWIDTH))
|
|
||||||
#else
|
|
||||||
#define STATUS_COOLER_HEIGHT(S) (sizeof(status_cooler_bmp) / (STATUS_COOLER_BYTEWIDTH))
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STATUS_COOLER_Y
|
#ifndef STATUS_COOLER_Y
|
||||||
@ -537,17 +551,53 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(status_cooler_bmp) == (STATUS_COOLER_BYTEWIDTH) * (STATUS_COOLER_HEIGHT(0)),
|
sizeof(status_cooler_bmp1) == (STATUS_COOLER_BYTEWIDTH) * (STATUS_COOLER_HEIGHT(0)),
|
||||||
"Status cooler bitmap (status_cooler_bmp) dimensions don't match data."
|
"Status cooler bitmap (status_cooler_bmp1) dimensions don't match data."
|
||||||
);
|
);
|
||||||
#ifdef STATUS_COOLER_ANIM
|
#ifdef STATUS_COOLER_ANIM
|
||||||
static_assert(
|
static_assert(
|
||||||
sizeof(status_cooler_on_bmp) == (STATUS_COOLER_BYTEWIDTH) * (STATUS_COOLER_HEIGHT(1)),
|
sizeof(status_cooler_bmp2) == (STATUS_COOLER_BYTEWIDTH) * (STATUS_COOLER_HEIGHT(1)),
|
||||||
"Status cooler bitmap (status_cooler_on_bmp) dimensions don't match data."
|
"Status cooler bitmap (status_cooler_bmp2) dimensions don't match data."
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flowmeter Bitmap Properties
|
||||||
|
//
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
#if STATUS_FLOWMETER_WIDTH
|
||||||
|
|
||||||
|
#ifndef STATUS_FLOWMETER_X
|
||||||
|
#define STATUS_FLOWMETER_X (LCD_PIXEL_WIDTH - (STATUS_FLOWMETER_BYTEWIDTH + STATUS_FAN_BYTEWIDTH + STATUS_CUTTER_BYTEWIDTH + STATUS_COOLER_BYTEWIDTH) * 8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STATUS_FLOWMETER_HEIGHT
|
||||||
|
#define STATUS_FLOWMETER_HEIGHT(S) (sizeof(status_flowmeter_bmp1) / (STATUS_FLOWMETER_BYTEWIDTH))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STATUS_FLOWMETER_Y
|
||||||
|
#define STATUS_FLOWMETER_Y(S) (20 - STATUS_FLOWMETER_HEIGHT(S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STATUS_FLOWMETER_TEXT_X
|
||||||
|
#define STATUS_FLOWMETER_TEXT_X (STATUS_FLOWMETER_X + 8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
sizeof(status_flowmeter_bmp1) == (STATUS_FLOWMETER_BYTEWIDTH) * STATUS_FLOWMETER_HEIGHT(0),
|
||||||
|
"Status flowmeter bitmap (status_flowmeter_bmp1) dimensions don't match data."
|
||||||
|
);
|
||||||
|
#ifdef STATUS_COOLER_ANIM
|
||||||
|
static_assert(
|
||||||
|
sizeof(status_flowmeter_bmp2) == (STATUS_FLOWMETER_BYTEWIDTH) * STATUS_FLOWMETER_HEIGHT(1),
|
||||||
|
"Status flowmeter bitmap (status_flowmeter_bmp2) dimensions don't match data."
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bed Bitmap Properties
|
// Bed Bitmap Properties
|
||||||
@ -639,6 +689,9 @@
|
|||||||
#if HAS_COOLER
|
#if HAS_COOLER
|
||||||
#define DO_DRAW_COOLER 1
|
#define DO_DRAW_COOLER 1
|
||||||
#endif
|
#endif
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
#define DO_DRAW_FLOWMETER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4
|
#if HAS_TEMP_CHAMBER && STATUS_CHAMBER_WIDTH && HOTENDS <= 4
|
||||||
#define DO_DRAW_CHAMBER 1
|
#define DO_DRAW_CHAMBER 1
|
||||||
@ -661,6 +714,9 @@
|
|||||||
#if BOTH(DO_DRAW_COOLER, STATUS_COOLER_ANIM)
|
#if BOTH(DO_DRAW_COOLER, STATUS_COOLER_ANIM)
|
||||||
#define ANIM_COOLER 1
|
#define ANIM_COOLER 1
|
||||||
#endif
|
#endif
|
||||||
|
#if BOTH(DO_DRAW_FLOWMETER, STATUS_FLOWMETER_ANIM)
|
||||||
|
#define ANIM_FLOWMETER 1
|
||||||
|
#endif
|
||||||
#if ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER || ANIM_CUTTER
|
#if ANIM_HOTEND || ANIM_BED || ANIM_CHAMBER || ANIM_CUTTER
|
||||||
#define ANIM_HBCC 1
|
#define ANIM_HBCC 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,12 +24,9 @@
|
|||||||
//
|
//
|
||||||
// lcd/dogm/status/cooler.h - Status Screen Laser Cooler bitmaps
|
// lcd/dogm/status/cooler.h - Status Screen Laser Cooler bitmaps
|
||||||
//
|
//
|
||||||
|
#if HAS_COOLER
|
||||||
#define STATUS_COOLER_WIDTH 16
|
#define STATUS_COOLER_WIDTH 16
|
||||||
|
const unsigned char status_cooler_bmp2[] PROGMEM = {
|
||||||
#ifdef STATUS_COOLER_ANIM
|
|
||||||
|
|
||||||
const unsigned char status_cooler_on_bmp[] PROGMEM = {
|
|
||||||
B00010000,B00001000,
|
B00010000,B00001000,
|
||||||
B00010010,B01001001,
|
B00010010,B01001001,
|
||||||
B01010100,B00101010,
|
B01010100,B00101010,
|
||||||
@ -47,10 +44,7 @@
|
|||||||
B00000010,B10100000,
|
B00000010,B10100000,
|
||||||
B00000100,B10010000
|
B00000100,B10010000
|
||||||
};
|
};
|
||||||
|
const unsigned char status_cooler_bmp1[] PROGMEM = {
|
||||||
#endif
|
|
||||||
|
|
||||||
const unsigned char status_cooler_bmp[] PROGMEM = {
|
|
||||||
B00010000,B00001000,
|
B00010000,B00001000,
|
||||||
B00010010,B01001001,
|
B00010010,B01001001,
|
||||||
B01010100,B00101010,
|
B01010100,B00101010,
|
||||||
@ -68,3 +62,53 @@ const unsigned char status_cooler_bmp[] PROGMEM = {
|
|||||||
B00000010,B10100000,
|
B00000010,B10100000,
|
||||||
B00000100,B10010000
|
B00000100,B10010000
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
#define STATUS_FLOWMETER_WIDTH 24
|
||||||
|
const unsigned char status_flowmeter_bmp2[] PROGMEM = {
|
||||||
|
B00000001,B11111000,B00000000,
|
||||||
|
B00000110,B00000110,B00000000,
|
||||||
|
B00001000,B01100001,B00000000,
|
||||||
|
B00010000,B01100000,B10000000,
|
||||||
|
B00100000,B01100000,B01000000,
|
||||||
|
B00100000,B01100000,B01000000,
|
||||||
|
B01000000,B01100000,B00100000,
|
||||||
|
B01000000,B01100000,B00100000,
|
||||||
|
B01011111,B11111111,B10100000,
|
||||||
|
B01011111,B11111111,B10100000,
|
||||||
|
B01000000,B01100000,B00100000,
|
||||||
|
B01000000,B01100000,B00100000,
|
||||||
|
B00100000,B01100000,B01000000,
|
||||||
|
B00100000,B01100000,B01000000,
|
||||||
|
B00010000,B01100000,B10000000,
|
||||||
|
B00001000,B01100001,B00000000,
|
||||||
|
B00000110,B00000110,B00000000,
|
||||||
|
B00000001,B11111000,B00000000,
|
||||||
|
B00000000,B01100000,B00000000,
|
||||||
|
B00011111,B11111111,B10000000
|
||||||
|
};
|
||||||
|
const unsigned char status_flowmeter_bmp1[] PROGMEM = {
|
||||||
|
B00000001,B11111000,B00000000,
|
||||||
|
B00000110,B00000110,B00000000,
|
||||||
|
B00001000,B00000001,B00000000,
|
||||||
|
B00010100,B00000010,B10000000,
|
||||||
|
B00101110,B00000111,B01000000,
|
||||||
|
B00100111,B00001110,B01000000,
|
||||||
|
B01000011,B10011100,B00100000,
|
||||||
|
B01000001,B11111000,B00100000,
|
||||||
|
B01000000,B11110000,B00100000,
|
||||||
|
B01000000,B11110000,B00100000,
|
||||||
|
B01000001,B11111000,B00100000,
|
||||||
|
B01000011,B10011100,B00100000,
|
||||||
|
B00100111,B00001110,B01000000,
|
||||||
|
B00101110,B00000111,B01000000,
|
||||||
|
B00010100,B00000010,B10000000,
|
||||||
|
B00001000,B00000001,B00000000,
|
||||||
|
B00000110,B00000110,B00000000,
|
||||||
|
B00000001,B11111000,B00000000,
|
||||||
|
B00000000,B01100000,B00000000,
|
||||||
|
B00011111,B11111111,B10000000
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
#include "../../feature/spindle_laser.h"
|
#include "../../feature/spindle_laser.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_COOLER || HAS_FLOWMETER
|
||||||
|
#include "../../feature/cooler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_POWER_MONITOR
|
#if HAS_POWER_MONITOR
|
||||||
#include "../../feature/power_monitor.h"
|
#include "../../feature/power_monitor.h"
|
||||||
#endif
|
#endif
|
||||||
@ -83,40 +87,34 @@
|
|||||||
|
|
||||||
#if ANIM_HBCC
|
#if ANIM_HBCC
|
||||||
enum HeatBits : uint8_t {
|
enum HeatBits : uint8_t {
|
||||||
HEATBIT_HOTEND,
|
DRAWBIT_HOTEND,
|
||||||
HEATBIT_BED = HOTENDS,
|
DRAWBIT_BED = HOTENDS,
|
||||||
HEATBIT_CHAMBER,
|
DRAWBIT_CHAMBER,
|
||||||
HEATBIT_COOLER,
|
DRAWBIT_CUTTER
|
||||||
HEATBIT_CUTTER
|
|
||||||
};
|
};
|
||||||
IF<(HEATBIT_CUTTER > 7), uint16_t, uint8_t>::type heat_bits;
|
IF<(DRAWBIT_CUTTER > 7), uint16_t, uint8_t>::type draw_bits;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ANIM_HOTEND
|
#if ANIM_HOTEND
|
||||||
#define HOTEND_ALT(N) TEST(heat_bits, HEATBIT_HOTEND + N)
|
#define HOTEND_ALT(N) TEST(draw_bits, DRAWBIT_HOTEND + N)
|
||||||
#else
|
#else
|
||||||
#define HOTEND_ALT(N) false
|
#define HOTEND_ALT(N) false
|
||||||
#endif
|
#endif
|
||||||
#if ANIM_BED
|
#if ANIM_BED
|
||||||
#define BED_ALT() TEST(heat_bits, HEATBIT_BED)
|
#define BED_ALT() TEST(draw_bits, DRAWBIT_BED)
|
||||||
#else
|
#else
|
||||||
#define BED_ALT() false
|
#define BED_ALT() false
|
||||||
#endif
|
#endif
|
||||||
#if ANIM_CHAMBER
|
#if ANIM_CHAMBER
|
||||||
#define CHAMBER_ALT() TEST(heat_bits, HEATBIT_CHAMBER)
|
#define CHAMBER_ALT() TEST(draw_bits, DRAWBIT_CHAMBER)
|
||||||
#else
|
#else
|
||||||
#define CHAMBER_ALT() false
|
#define CHAMBER_ALT() false
|
||||||
#endif
|
#endif
|
||||||
#if ANIM_CUTTER
|
#if ANIM_CUTTER
|
||||||
#define CUTTER_ALT(N) TEST(heat_bits, HEATBIT_CUTTER)
|
#define CUTTER_ALT(N) TEST(draw_bits, DRAWBIT_CUTTER)
|
||||||
#else
|
#else
|
||||||
#define CUTTER_ALT() false
|
#define CUTTER_ALT() false
|
||||||
#endif
|
#endif
|
||||||
#if ANIM_COOLER
|
|
||||||
#define COOLER_ALT(N) TEST(heat_bits, HEATBIT_COOLER)
|
|
||||||
#else
|
|
||||||
#define COOLER_ALT() false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DO_DRAW_HOTENDS
|
#if DO_DRAW_HOTENDS
|
||||||
#define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE)))
|
#define MAX_HOTEND_DRAW _MIN(HOTENDS, ((LCD_PIXEL_WIDTH - (STATUS_LOGO_BYTEWIDTH + STATUS_FAN_BYTEWIDTH) * 8) / (STATUS_HEATERS_XSPACE)))
|
||||||
@ -194,6 +192,15 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
|
|||||||
lcd_put_wchar(LCD_STR_DEGREE[0]);
|
lcd_put_wchar(LCD_STR_DEGREE[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DO_DRAW_FLOWMETER
|
||||||
|
FORCE_INLINE void _draw_centered_flowrate(const float flow, const uint8_t tx, const uint8_t ty) {
|
||||||
|
const char *str = ftostr11ns(flow);
|
||||||
|
const uint8_t len = str[0] != ' ' ? 3 : str[1] != ' ' ? 2 : 1;
|
||||||
|
lcd_put_u8str(tx - len * (INFO_FONT_WIDTH) / 2 + 1, ty, &str[3-len]);
|
||||||
|
lcd_put_u8str("L");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DO_DRAW_HOTENDS
|
#if DO_DRAW_HOTENDS
|
||||||
|
|
||||||
// Draw hotend bitmap with current and target temperatures
|
// Draw hotend bitmap with current and target temperatures
|
||||||
@ -384,6 +391,13 @@ FORCE_INLINE void _draw_centered_temp(const celsius_t temp, const uint8_t tx, co
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if DO_DRAW_FLOWMETER
|
||||||
|
FORCE_INLINE void _draw_flowmeter_status() {
|
||||||
|
if (PAGE_CONTAINS(28 - INFO_FONT_ASCENT, 28 - 1))
|
||||||
|
_draw_centered_flowrate(cooler.flowrate, STATUS_FLOWMETER_TEXT_X, 28);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Before homing, blink '123' <-> '???'.
|
// Before homing, blink '123' <-> '???'.
|
||||||
// Homed but unknown... '123' <-> ' '.
|
// Homed but unknown... '123' <-> ' '.
|
||||||
@ -451,17 +465,14 @@ void MarlinUI::draw_status_screen() {
|
|||||||
#if ANIM_HBCC
|
#if ANIM_HBCC
|
||||||
uint8_t new_bits = 0;
|
uint8_t new_bits = 0;
|
||||||
#if ANIM_HOTEND
|
#if ANIM_HOTEND
|
||||||
HOTEND_LOOP() if (thermalManager.isHeatingHotend(e)) SBI(new_bits, HEATBIT_HOTEND + e);
|
HOTEND_LOOP() if (thermalManager.isHeatingHotend(e)) SBI(new_bits, DRAWBIT_HOTEND + e);
|
||||||
#endif
|
#endif
|
||||||
if (TERN0(ANIM_BED, thermalManager.isHeatingBed())) SBI(new_bits, HEATBIT_BED);
|
if (TERN0(ANIM_BED, thermalManager.isHeatingBed())) SBI(new_bits, DRAWBIT_BED);
|
||||||
#if DO_DRAW_CHAMBER && HAS_HEATED_CHAMBER
|
#if DO_DRAW_CHAMBER && HAS_HEATED_CHAMBER
|
||||||
if (thermalManager.isHeatingChamber()) SBI(new_bits, HEATBIT_CHAMBER);
|
if (thermalManager.isHeatingChamber()) SBI(new_bits, DRAWBIT_CHAMBER);
|
||||||
#endif
|
#endif
|
||||||
#if DO_DRAW_COOLER && HAS_COOLER
|
if (TERN0(ANIM_CUTTER, cutter.enabled())) SBI(new_bits, DRAWBIT_CUTTER);
|
||||||
if (thermalManager.isLaserCooling()) SBI(new_bits, HEATBIT_COOLER);
|
draw_bits = new_bits;
|
||||||
#endif
|
|
||||||
if (TERN0(ANIM_CUTTER, cutter.enabled())) SBI(new_bits, HEATBIT_CUTTER);
|
|
||||||
heat_bits = new_bits;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const xyz_pos_t lpos = current_position.asLogical();
|
const xyz_pos_t lpos = current_position.asLogical();
|
||||||
@ -646,17 +657,21 @@ void MarlinUI::draw_status_screen() {
|
|||||||
|
|
||||||
// Laser Cooler
|
// Laser Cooler
|
||||||
#if DO_DRAW_COOLER
|
#if DO_DRAW_COOLER
|
||||||
#if ANIM_COOLER
|
const uint8_t coolery = STATUS_COOLER_Y(status_cooler_bmp1),
|
||||||
#define COOLER_BITMAP(S) ((S) ? status_cooler_bmp : status_cooler_on_bmp)
|
coolerh = STATUS_COOLER_HEIGHT(status_cooler_bmp1);
|
||||||
#else
|
|
||||||
#define COOLER_BITMAP(S) status_cooler_bmp
|
|
||||||
#endif
|
|
||||||
const uint8_t coolery = STATUS_COOLER_Y(COOLER_ALT()),
|
|
||||||
coolerh = STATUS_COOLER_HEIGHT(COOLER_ALT());
|
|
||||||
if (PAGE_CONTAINS(coolery, coolery + coolerh - 1))
|
if (PAGE_CONTAINS(coolery, coolery + coolerh - 1))
|
||||||
u8g.drawBitmapP(STATUS_COOLER_X, coolery, STATUS_COOLER_BYTEWIDTH, coolerh, COOLER_BITMAP(COOLER_ALT()));
|
u8g.drawBitmapP(STATUS_COOLER_X, coolery, STATUS_COOLER_BYTEWIDTH, coolerh, blink && cooler.enabled ? status_cooler_bmp2 : status_cooler_bmp1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Laser Cooler Flow Meter
|
||||||
|
#if DO_DRAW_FLOWMETER
|
||||||
|
const uint8_t flowmetery = STATUS_FLOWMETER_Y(status_flowmeter_bmp1),
|
||||||
|
flowmeterh = STATUS_FLOWMETER_HEIGHT(status_flowmeter_bmp1);
|
||||||
|
if (PAGE_CONTAINS(flowmetery, flowmetery + flowmeterh - 1))
|
||||||
|
u8g.drawBitmapP(STATUS_FLOWMETER_X, flowmetery, STATUS_FLOWMETER_BYTEWIDTH, flowmeterh, blink && cooler.flowpulses ? status_flowmeter_bmp2 : status_flowmeter_bmp1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Heated Bed
|
// Heated Bed
|
||||||
TERN_(DO_DRAW_BED, _draw_bed_status(blink));
|
TERN_(DO_DRAW_BED, _draw_bed_status(blink));
|
||||||
|
|
||||||
@ -666,6 +681,9 @@ void MarlinUI::draw_status_screen() {
|
|||||||
// Cooler
|
// Cooler
|
||||||
TERN_(DO_DRAW_COOLER, _draw_cooler_status());
|
TERN_(DO_DRAW_COOLER, _draw_cooler_status());
|
||||||
|
|
||||||
|
// Flowmeter
|
||||||
|
TERN_(DO_DRAW_FLOWMETER, _draw_flowmeter_status());
|
||||||
|
|
||||||
// Fan, if a bitmap was provided
|
// Fan, if a bitmap was provided
|
||||||
#if DO_DRAW_FAN
|
#if DO_DRAW_FAN
|
||||||
if (PAGE_CONTAINS(STATUS_FAN_TEXT_Y - INFO_FONT_ASCENT, STATUS_FAN_TEXT_Y - 1)) {
|
if (PAGE_CONTAINS(STATUS_FAN_TEXT_Y - INFO_FONT_ASCENT, STATUS_FAN_TEXT_Y - 1)) {
|
||||||
|
@ -116,10 +116,10 @@ namespace Language_en {
|
|||||||
PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Toggle Laser");
|
PROGMEM Language_Str MSG_LASER_TOGGLE = _UxGT("Toggle Laser");
|
||||||
PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Test Pulse ms");
|
PROGMEM Language_Str MSG_LASER_PULSE_MS = _UxGT("Test Pulse ms");
|
||||||
PROGMEM Language_Str MSG_LASER_FIRE_PULSE = _UxGT("Fire Pulse");
|
PROGMEM Language_Str MSG_LASER_FIRE_PULSE = _UxGT("Fire Pulse");
|
||||||
|
PROGMEM Language_Str MSG_FLOWMETER_FAULT = _UxGT("Coolant Flow Fault");
|
||||||
PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Toggle Spindle");
|
PROGMEM Language_Str MSG_SPINDLE_TOGGLE = _UxGT("Toggle Spindle");
|
||||||
PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Spindle Forward");
|
PROGMEM Language_Str MSG_SPINDLE_FORWARD = _UxGT("Spindle Forward");
|
||||||
PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Spindle Reverse");
|
PROGMEM Language_Str MSG_SPINDLE_REVERSE = _UxGT("Spindle Reverse");
|
||||||
|
|
||||||
PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Switch Power On");
|
PROGMEM Language_Str MSG_SWITCH_PS_ON = _UxGT("Switch Power On");
|
||||||
PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Switch Power Off");
|
PROGMEM Language_Str MSG_SWITCH_PS_OFF = _UxGT("Switch Power Off");
|
||||||
PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrude");
|
PROGMEM Language_Str MSG_EXTRUDE = _UxGT("Extrude");
|
||||||
@ -278,6 +278,7 @@ namespace Language_en {
|
|||||||
PROGMEM Language_Str MSG_CHAMBER = _UxGT("Enclosure");
|
PROGMEM Language_Str MSG_CHAMBER = _UxGT("Enclosure");
|
||||||
PROGMEM Language_Str MSG_COOLER = _UxGT("Laser Coolant");
|
PROGMEM Language_Str MSG_COOLER = _UxGT("Laser Coolant");
|
||||||
PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Toggle Cooler");
|
PROGMEM Language_Str MSG_COOLER_TOGGLE = _UxGT("Toggle Cooler");
|
||||||
|
PROGMEM Language_Str MSG_FLOWMETER_SAFETY = _UxGT("Flow Safety");
|
||||||
PROGMEM Language_Str MSG_LASER = _UxGT("Laser");
|
PROGMEM Language_Str MSG_LASER = _UxGT("Laser");
|
||||||
PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Fan Speed");
|
PROGMEM Language_Str MSG_FAN_SPEED = _UxGT("Fan Speed");
|
||||||
PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Fan Speed ~");
|
PROGMEM Language_Str MSG_FAN_SPEED_N = _UxGT("Fan Speed ~");
|
||||||
|
@ -1513,6 +1513,12 @@ void MarlinUI::update() {
|
|||||||
TERN_(HAS_LCD_MENU, return_to_status());
|
TERN_(HAS_LCD_MENU, return_to_status());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarlinUI::flow_fault() {
|
||||||
|
LCD_ALERTMESSAGEPGM(MSG_FLOWMETER_FAULT);
|
||||||
|
TERN_(HAS_BUZZER, buzz(1000, 440));
|
||||||
|
TERN_(HAS_LCD_MENU, return_to_status());
|
||||||
|
}
|
||||||
|
|
||||||
#if ANY(PARK_HEAD_ON_PAUSE, SDSUPPORT)
|
#if ANY(PARK_HEAD_ON_PAUSE, SDSUPPORT)
|
||||||
#include "../gcode/queue.h"
|
#include "../gcode/queue.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,6 +43,10 @@
|
|||||||
#define HAS_ENCODER_ACTION 1
|
#define HAS_ENCODER_ACTION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_STATUS_MESSAGE
|
||||||
|
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if E_MANUAL > 1
|
#if E_MANUAL > 1
|
||||||
#define MULTI_MANUAL 1
|
#define MULTI_MANUAL 1
|
||||||
#endif
|
#endif
|
||||||
@ -311,6 +315,7 @@ public:
|
|||||||
static void abort_print();
|
static void abort_print();
|
||||||
static void pause_print();
|
static void pause_print();
|
||||||
static void resume_print();
|
static void resume_print();
|
||||||
|
static void flow_fault();
|
||||||
|
|
||||||
#if HAS_WIRED_LCD
|
#if HAS_WIRED_LCD
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include "../../module/motion.h"
|
#include "../../module/motion.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_COOLER
|
#if HAS_COOLER || HAS_FLOWMETER
|
||||||
#include "../../feature/cooler.h"
|
#include "../../feature/cooler.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -192,11 +192,19 @@ void menu_temperature() {
|
|||||||
// Cooler:
|
// Cooler:
|
||||||
//
|
//
|
||||||
#if HAS_COOLER
|
#if HAS_COOLER
|
||||||
editable.state = cooler.is_enabled();
|
bool cstate = cooler.enabled;
|
||||||
EDIT_ITEM(bool, MSG_COOLER(TOGGLE), &cooler.state, []{ if (editable.state) cooler.disable(); else cooler.enable(); });
|
EDIT_ITEM(bool, MSG_COOLER_TOGGLE, &cstate, cooler.toggle);
|
||||||
EDIT_ITEM_FAST(int3, MSG_COOLER, &thermalManager.temp_cooler.target, COOLER_MIN_TARGET, COOLER_MAX_TARGET, thermalManager.start_watching_cooler);
|
EDIT_ITEM_FAST(int3, MSG_COOLER, &thermalManager.temp_cooler.target, COOLER_MIN_TARGET, COOLER_MAX_TARGET, thermalManager.start_watching_cooler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flow Meter Safety Shutdown:
|
||||||
|
//
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
bool fstate = cooler.flowsafety_enabled;
|
||||||
|
EDIT_ITEM(bool, MSG_FLOWMETER_SAFETY, &fstate, cooler.flowsafety_toggle);
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Fan Speed:
|
// Fan Speed:
|
||||||
//
|
//
|
||||||
|
@ -177,6 +177,15 @@ const char* i16tostr4signrj(const int16_t i) {
|
|||||||
return &conv[3];
|
return &conv[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert unsigned float to string with 1.1 format
|
||||||
|
const char* ftostr11ns(const float &f) {
|
||||||
|
const long i = UINTFLOAT(f, 1);
|
||||||
|
conv[4] = DIGIMOD(i, 10);
|
||||||
|
conv[5] = '.';
|
||||||
|
conv[6] = DIGIMOD(i, 1);
|
||||||
|
return &conv[4];
|
||||||
|
}
|
||||||
|
|
||||||
// Convert unsigned float to string with 1.23 format
|
// Convert unsigned float to string with 1.23 format
|
||||||
const char* ftostr12ns(const float &f) {
|
const char* ftostr12ns(const float &f) {
|
||||||
const long i = UINTFLOAT(f, 2);
|
const long i = UINTFLOAT(f, 2);
|
||||||
|
@ -61,6 +61,9 @@ const char* i16tostr3left(const int16_t xx);
|
|||||||
// Convert signed int to rj string with _123, -123, _-12, or __-1 format
|
// Convert signed int to rj string with _123, -123, _-12, or __-1 format
|
||||||
const char* i16tostr4signrj(const int16_t x);
|
const char* i16tostr4signrj(const int16_t x);
|
||||||
|
|
||||||
|
// Convert unsigned float to string with 1.2 format
|
||||||
|
const char* ftostr11ns(const float &x);
|
||||||
|
|
||||||
// Convert unsigned float to string with 1.23 format
|
// Convert unsigned float to string with 1.23 format
|
||||||
const char* ftostr12ns(const float &x);
|
const char* ftostr12ns(const float &x);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include "endstops.h"
|
#include "endstops.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
|
|
||||||
#if HAS_COOLER
|
#if HAS_COOLER || HAS_FLOWMETER
|
||||||
#include "../feature/cooler.h"
|
#include "../feature/cooler.h"
|
||||||
#include "../feature/spindle_laser.h"
|
#include "../feature/spindle_laser.h"
|
||||||
#endif
|
#endif
|
||||||
@ -52,6 +52,10 @@
|
|||||||
#include "../lcd/extui/ui_api.h"
|
#include "../lcd/extui/ui_api.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
|
#include "../feature/host_actions.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// LIB_MAX31855 can be added to the build_flags in platformio.ini to use a user-defined library
|
// LIB_MAX31855 can be added to the build_flags in platformio.ini to use a user-defined library
|
||||||
#if LIB_USR_MAX31855
|
#if LIB_USR_MAX31855
|
||||||
#include <Adafruit_MAX31855.h>
|
#include <Adafruit_MAX31855.h>
|
||||||
@ -1506,7 +1510,7 @@ void Temperature::manage_heater() {
|
|||||||
|
|
||||||
static bool flag_cooler_state; // = false
|
static bool flag_cooler_state; // = false
|
||||||
|
|
||||||
if (cooler.is_enabled()) {
|
if (cooler.enabled) {
|
||||||
flag_cooler_state = true; // used to allow M106 fan control when cooler is disabled
|
flag_cooler_state = true; // used to allow M106 fan control when cooler is disabled
|
||||||
if (temp_cooler.target == 0) temp_cooler.target = COOLER_MIN_TARGET;
|
if (temp_cooler.target == 0) temp_cooler.target = COOLER_MIN_TARGET;
|
||||||
if (ELAPSED(ms, next_cooler_check_ms)) {
|
if (ELAPSED(ms, next_cooler_check_ms)) {
|
||||||
@ -1542,8 +1546,19 @@ void Temperature::manage_heater() {
|
|||||||
#if ENABLED(THERMAL_PROTECTION_COOLER)
|
#if ENABLED(THERMAL_PROTECTION_COOLER)
|
||||||
tr_state_machine[RUNAWAY_IND_COOLER].run(temp_cooler.celsius, temp_cooler.target, H_COOLER, THERMAL_PROTECTION_COOLER_PERIOD, THERMAL_PROTECTION_COOLER_HYSTERESIS);
|
tr_state_machine[RUNAWAY_IND_COOLER].run(temp_cooler.celsius, temp_cooler.target, H_COOLER, THERMAL_PROTECTION_COOLER_PERIOD, THERMAL_PROTECTION_COOLER_HYSTERESIS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // HAS_COOLER
|
#endif // HAS_COOLER
|
||||||
|
|
||||||
|
#if HAS_FLOWMETER
|
||||||
|
cooler.flowmeter_task(ms);
|
||||||
|
#if ENABLED(FLOWMETER_SAFETY)
|
||||||
|
if (cutter.enabled() && cooler.check_flow_too_low()) {
|
||||||
|
cutter.disable();
|
||||||
|
ui.flow_fault();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
UNUSED(ms);
|
UNUSED(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +167,26 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" "$3"
|
|||||||
#opt_enable LCM1602
|
#opt_enable LCM1602
|
||||||
#exec_test $1 $2 "Stuff" "$3"
|
#exec_test $1 $2 "Stuff" "$3"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test Laser features with 12864 LCD
|
||||||
|
#
|
||||||
|
restore_configs
|
||||||
|
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 EXTRUDERS 0 TEMP_SENSOR_1 0
|
||||||
|
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
|
||||||
|
LASER_FEATURE LASER_COOLANT_FLOW_METER
|
||||||
|
|
||||||
|
exec_test $1 $2 "REPRAP MEGA2560 RAMPS | Laser Feature | Cooler | Flowmeter | 12864 LCD " "$3"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test Laser features with 44780 LCD
|
||||||
|
#
|
||||||
|
restore_configs
|
||||||
|
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 EXTRUDERS 0 TEMP_SENSOR_1 0
|
||||||
|
opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
|
||||||
|
LASER_FEATURE LASER_COOLANT_FLOW_METER
|
||||||
|
|
||||||
|
exec_test $1 $2 "REPRAP MEGA2560 RAMPS | Laser Feature | Cooler | Flowmeter | 44780 LCD " "$3"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Language files test with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
# Language files test with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
||||||
#
|
#
|
||||||
|
@ -82,6 +82,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
|
|||||||
-<src/feature/caselight.cpp> -<src/gcode/feature/caselight>
|
-<src/feature/caselight.cpp> -<src/gcode/feature/caselight>
|
||||||
-<src/feature/closedloop.cpp>
|
-<src/feature/closedloop.cpp>
|
||||||
-<src/feature/controllerfan.cpp> -<src/gcode/feature/controllerfan>
|
-<src/feature/controllerfan.cpp> -<src/gcode/feature/controllerfan>
|
||||||
|
-<src/feature/cooler.cpp> -<src/gcode/temp/M143_M193.cpp>
|
||||||
-<src/feature/dac> -<src/feature/digipot>
|
-<src/feature/dac> -<src/feature/digipot>
|
||||||
-<src/feature/direct_stepping.cpp> -<src/gcode/motion/G6.cpp>
|
-<src/feature/direct_stepping.cpp> -<src/gcode/motion/G6.cpp>
|
||||||
-<src/feature/e_parser.cpp>
|
-<src/feature/e_parser.cpp>
|
||||||
@ -198,7 +199,6 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
|
|||||||
-<src/gcode/sd/M32.cpp>
|
-<src/gcode/sd/M32.cpp>
|
||||||
-<src/gcode/sd/M808.cpp>
|
-<src/gcode/sd/M808.cpp>
|
||||||
-<src/gcode/temp/M104_M109.cpp>
|
-<src/gcode/temp/M104_M109.cpp>
|
||||||
-<src/gcode/temp/M143_M193.cpp>
|
|
||||||
-<src/gcode/temp/M155.cpp>
|
-<src/gcode/temp/M155.cpp>
|
||||||
-<src/gcode/units/G20_G21.cpp>
|
-<src/gcode/units/G20_G21.cpp>
|
||||||
-<src/gcode/units/M149.cpp>
|
-<src/gcode/units/M149.cpp>
|
||||||
@ -411,7 +411,7 @@ SDSUPPORT = src_filter=+<src/sd/cardreader.cpp> +<src/sd/Sd2Card.c
|
|||||||
HAS_MEDIA_SUBCALLS = src_filter=+<src/gcode/sd/M32.cpp>
|
HAS_MEDIA_SUBCALLS = src_filter=+<src/gcode/sd/M32.cpp>
|
||||||
GCODE_REPEAT_MARKERS = src_filter=+<src/feature/repeat.cpp> +<src/gcode/sd/M808.cpp>
|
GCODE_REPEAT_MARKERS = src_filter=+<src/feature/repeat.cpp> +<src/gcode/sd/M808.cpp>
|
||||||
HAS_EXTRUDERS = src_filter=+<src/gcode/temp/M104_M109.cpp> +<src/gcode/config/M221.cpp>
|
HAS_EXTRUDERS = src_filter=+<src/gcode/temp/M104_M109.cpp> +<src/gcode/config/M221.cpp>
|
||||||
HAS_COOLER = src_filter=-<src/gcode/temp/M143_M193.cpp>
|
HAS_COOLER = src_filter=+<src/feature/cooler.cpp> +<src/gcode/temp/M143_M193.cpp>
|
||||||
AUTO_REPORT_TEMPERATURES = src_filter=+<src/gcode/temp/M155.cpp>
|
AUTO_REPORT_TEMPERATURES = src_filter=+<src/gcode/temp/M155.cpp>
|
||||||
INCH_MODE_SUPPORT = src_filter=+<src/gcode/units/G20_G21.cpp>
|
INCH_MODE_SUPPORT = src_filter=+<src/gcode/units/G20_G21.cpp>
|
||||||
TEMPERATURE_UNITS_SUPPORT = src_filter=+<src/gcode/units/M149.cpp>
|
TEMPERATURE_UNITS_SUPPORT = src_filter=+<src/gcode/units/M149.cpp>
|
||||||
|
Loading…
Reference in New Issue
Block a user