Laser Coolant Flow Meter / Safety Shutdown (#21431)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Mike La Spina
2021-03-29 01:41:56 -05:00
committed by GitHub
parent 8f509b0ae0
commit ccdbffbf3f
20 changed files with 512 additions and 173 deletions

View File

@ -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

View File

@ -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 uint16_t capacity; // Cooling capacity in watts
static uint16_t load; // Cooling load in watts
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 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;

View File

@ -215,8 +215,7 @@ public:
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)
@ -245,8 +244,8 @@ public:
* 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
}