Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laser.cooler.flowmeter #21431

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ec50d3d
Laser percent power
thinkyhead Dec 9, 2020
98799b5
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Dec 14, 2020
74367bc
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Dec 29, 2020
4a2dab7
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Jan 25, 2021
aa713a1
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Feb 1, 2021
2cc4d48
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Feb 2, 2021
8db0a77
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Mar 3, 2021
9dbc82f
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Mar 5, 2021
329e211
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Mar 12, 2021
80c48b0
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into bugfix-2.0.x
descipher Mar 16, 2021
3b81904
Flowmeter and more laser feature updates.
descipher Mar 24, 2021
485e63f
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into laser.coole…
descipher Mar 24, 2021
32a6301
Update Configuration_adv.h
descipher Mar 24, 2021
f35118b
Update marlinui_HD44780.cpp
descipher Mar 24, 2021
5c83786
git
descipher Mar 24, 2021
6de7f8f
Merge branch 'laser.cooler.flowmeter' of https://github.com/descipher…
descipher Mar 24, 2021
206799a
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into pr/21431
thinkyhead Mar 24, 2021
511ce67
Update Configuration_adv.h
descipher Mar 24, 2021
311b7a0
Update language.h
descipher Mar 24, 2021
d2db7e2
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into laser.coole…
descipher Mar 24, 2021
7c0eda1
Merge branch 'laser.cooler.flowmeter' of https://github.com/descipher…
descipher Mar 24, 2021
4ff2a55
Buzzer conditional
descipher Mar 24, 2021
233df26
Keep PWM255 default
descipher Mar 24, 2021
526c0b7
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into laser.coole…
descipher Mar 24, 2021
dfdb5d9
Update status_screen_DOGM.cpp
descipher Mar 24, 2021
a96154f
Moved conditional to ui header file
descipher Mar 24, 2021
b3e5414
Merge branch 'laser.cooler.flowmeter' of https://github.com/descipher…
descipher Mar 24, 2021
55dcfa7
Add def conditional for FLOWMETER_INTERVAL
descipher Mar 24, 2021
1c5eada
Sanity added and Feature condition cleanup
descipher Mar 24, 2021
274a98a
Cleaned
descipher Mar 24, 2021
4f1130a
Comment FLOWMETER_FEATURE
descipher Mar 24, 2021
87286aa
Update language_en.h
descipher Mar 25, 2021
1aa6114
Merge remote-tracking branch 'upstream/bugfix-2.0.x' into laser.coole…
descipher Mar 26, 2021
ddec5cd
mega2560 Tests
descipher Mar 26, 2021
25459b0
+mega2560 Tests
descipher Mar 26, 2021
f3f8f51
Improved test decription.
descipher Mar 26, 2021
4517668
Added 44780 Test
descipher Mar 26, 2021
f4583cd
cleanup
thinkyhead Mar 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,20 @@
#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
* and fire. Marlin always includes safe min and max temperature ranges which
Expand Down Expand Up @@ -1539,6 +1553,7 @@
#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_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_FAN_BITMAP // Use the alternative fan bitmap
//#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/core/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
#define STR_COUNT_A " Count A:"
#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required."
#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_SERIAL_MISMATCH "Serial status mismatch"
#define STR_BUSY_PROCESSING "busy: processing"
Expand Down
22 changes: 16 additions & 6 deletions Marlin/src/feature/cooler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@
#include "cooler.h"
Cooler cooler;

uint16_t Cooler::flowrate; // Flow meter reading in liters, 0 will result in shutdown if equiped
uint8_t Cooler::mode = 0; // 0 = CO2 Liquid cooling, 1 = Laser Diode TEC Heatsink Cooling
uint16_t Cooler::capacity; // Cooling capacity in watts
uint16_t Cooler::load; // Cooling load in watts
bool Cooler::flowmeter = false;
bool Cooler::state = false; // on = true, off = false
uint8_t Cooler::mode = 0;
uint16_t Cooler::capacity;
uint16_t Cooler::load;
bool Cooler::enabled = 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

#if ENABLED(FLOWMETER_SAFETY)
bool Cooler::flowsafety_enabled = true;
bool Cooler::fault = false;
#endif

#endif // HAS_COOLER
97 changes: 79 additions & 18 deletions Marlin/src/feature/cooler.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,91 @@
*/
#pragma once

#include <stdint.h>
#include "../inc/MarlinConfigPre.h"

#define _MSG_COOLER(M) MSG_COOLER_##M
#define MSG_COOLER(M) _MSG_COOLER(M)
#ifndef FLOWMETER_PPL
#define FLOWMETER_PPL 5880 // Pulses per liter
#endif
#ifndef FLOWMETER_INTERVAL
#define FLOWMETER_INTERVAL 1000 // milliseconds
#endif

// Cooling device

class Cooler {
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 load; // Cooling load in watts
static bool flowmeter;
static bool state; // on = true, off = false

static bool is_enabled() { return state; }
static void enable() { state = true; }
static void disable() { state = false; }
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; }
static void update_flowrate(uint16_t flow) { flowrate = flow; }
//static void init() { set_state(false); }
static uint16_t capacity; // Cooling capacity in watts
static uint16_t load; // Cooling load in watts

static bool enabled;
static void enable() { enabled = true; }
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; }

#if ENABLED(LASER_COOLANT_FLOW_METER)
static float flowrate; // Flow meter reading in liters-per-minute.
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;
5 changes: 2 additions & 3 deletions Marlin/src/feature/spindle_laser.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ class SpindleLaser {
static inline void disable() { isReady = false; set_enabled(false); }

#if HAS_LCD_MENU

static inline void enable_with_dir(const bool reverse) {
static inline void enable_with_dir(const bool reverse) {
isReady = true;
const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255);
if (menuPower)
Expand Down Expand Up @@ -245,8 +244,8 @@ class SpindleLaser {
* If not set defaults to 80% power
*/
static inline void test_fire_pulse() {
enable_forward(); // Turn Laser on (Spindle speak but same funct)
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.
disable(); // Turn laser off
}
Expand Down
11 changes: 11 additions & 0 deletions Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ GcodeSuite gcode;
#include "../feature/spindle_laser.h"
#endif

#if ENABLED(FLOWMETER_SAFETY)
#include "../feature/cooler.h"
#endif

#if ENABLED(PASSWORD_FEATURE)
#include "../feature/password/password.h"
#endif
Expand Down Expand Up @@ -278,6 +282,13 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
}
#endif

#if ENABLED(FLOWMETER_SAFETY)
if (cooler.fault) {
SERIAL_ECHO_MSG(STR_FLOWMETER_FAULT);
return;
}
#endif

// Handle a known G, M, or T
switch (parser.command_letter) {
case 'G': switch (parser.codenum) {
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -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."
#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))
#error "CHAMBER_FAN_MODE must be between 0 and 2."
#endif
Expand Down
95 changes: 74 additions & 21 deletions Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#include "../../gcode/parser.h"
#endif

#if HAS_COOLER || HAS_FLOWMETER
#include "../../feature/cooler.h"
#endif

#if ENABLED(AUTO_BED_LEVELING_UBL)
#include "../../feature/bedlevel/bedlevel.h"
#endif
Expand Down Expand Up @@ -517,6 +521,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
lcd_put_u8str(value);
}


FORCE_INLINE void _draw_heater_status(const heater_id_t heater_id, const char prefix, const bool blink) {
#if HAS_HEATED_BED
const bool isBed = TERN(HAS_HEATED_CHAMBER, heater_id == H_BED, heater_id < 0);
Expand Down Expand Up @@ -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) {
_draw_heater_status(H_BED, TERN0(HAS_LEVELING, blink && planner.leveling_active) ? '_' : LCD_STR_BEDTEMP[0], blink);
}
Expand Down Expand Up @@ -747,35 +789,46 @@ void MarlinUI::draw_status_screen() {
//
// Hotend 0 Temperature
//
_draw_heater_status(H_E0, -1, blink);

//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(8, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(8, 0);
_draw_bed_status(blink);
#if HAS_HOTEND
_draw_heater_status(H_E0, -1, blink);

//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(8, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(8, 0);
_draw_bed_status(blink);
#endif
#endif

#else // LCD_WIDTH >= 20

//
// Hotend 0 Temperature
//
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);
#if HAS_HOTEND
_draw_heater_status(H_E0, LCD_STR_THERMOMETER[0], blink);

//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(10, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(10, 0);
_draw_bed_status(blink);
#endif
#endif

//
// Hotend 1 or Bed Temperature
//
#if HAS_MULTI_HOTEND
lcd_moveto(10, 0);
_draw_heater_status(H_E1, LCD_STR_THERMOMETER[0], blink);
#elif HAS_HEATED_BED
lcd_moveto(10, 0);
_draw_bed_status(blink);
#if HAS_COOLER
_draw_cooler_status('*', blink);
#endif
#if HAS_FLOWMETER
_draw_flowmeter_status();
#endif

#endif // LCD_WIDTH >= 20
Expand Down