From d75e7784e50dad2b9f598ef559958e9015e64550 Mon Sep 17 00:00:00 2001 From: schmttc <89831403+schmttc@users.noreply.github.com> Date: Wed, 24 Nov 2021 08:52:18 +1100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20EasyThreeD=20ET4000+=20board=20and?= =?UTF-8?q?=20UI=20(#23080)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/Configuration.h | 5 + Marlin/src/MarlinCore.cpp | 10 + Marlin/src/feature/easythreed_ui.cpp | 236 ++++++++++++++++++ Marlin/src/feature/easythreed_ui.h | 35 +++ Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h | 50 +++- ini/features.ini | 1 + platformio.ini | 1 + 7 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 Marlin/src/feature/easythreed_ui.cpp create mode 100644 Marlin/src/feature/easythreed_ui.h diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 060c07bbbc..71a9211330 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2825,6 +2825,11 @@ //#define REPRAPWORLD_KEYPAD //#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press +// +// EasyThreeD ET-4000+ with button input and status LED +// +//#define EASYTHREED_UI + //============================================================================= //=============================== Extra Features ============================== //============================================================================= diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index ea486abfcd..5132d07e87 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -248,6 +248,10 @@ #include "feature/power.h" #endif +#if ENABLED(EASYTHREED_UI) + #include "feature/easythreed_ui.h" +#endif + PGMSTR(M112_KILL_STR, "M112 Shutdown"); MarlinState marlin_state = MF_INITIALIZING; @@ -637,6 +641,8 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) { #endif #endif + TERN_(EASYTHREED_UI, easythreed_ui.run()); + TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down TERN_(AUTO_POWER_CONTROL, powerManager.check(!ui.on_status_screen() || printJobOngoing() || printingIsPaused())); @@ -1609,6 +1615,10 @@ void setup() { SETUP_RUN(ui.check_touch_calibration()); #endif + #if ENABLED(EASYTHREED_UI) + SETUP_RUN(easythreed_ui.init()); + #endif + marlin_state = MF_RUNNING; SETUP_LOG("setup() completed."); diff --git a/Marlin/src/feature/easythreed_ui.cpp b/Marlin/src/feature/easythreed_ui.cpp new file mode 100644 index 0000000000..3eff233c01 --- /dev/null +++ b/Marlin/src/feature/easythreed_ui.cpp @@ -0,0 +1,236 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(EASYTHREED_UI) + +#include "easythreed_ui.h" +#include "pause.h" +#include "../module/temperature.h" +#include "../module/printcounter.h" +#include "../sd/cardreader.h" +#include "../gcode/queue.h" +#include "../module/motion.h" +#include "../module/planner.h" +#include "../MarlinCore.h" + +EasythreedUI easythreed_ui; + +#define BTN_DEBOUNCE_MS 20 + +void EasythreedUI::init() { + SET_INPUT_PULLUP(BTN_HOME); SET_OUTPUT(BTN_HOME_GND); + SET_INPUT_PULLUP(BTN_FEED); SET_OUTPUT(BTN_FEED_GND); + SET_INPUT_PULLUP(BTN_RETRACT); SET_OUTPUT(BTN_RETRACT_GND); + SET_INPUT_PULLUP(BTN_PRINT); + SET_OUTPUT(EASYTHREED_LED_PIN); +} + +void EasythreedUI::run() { + blinkLED(); + loadButton(); + printButton(); +} + +enum LEDInterval : uint16_t { + LED_OFF = 0, + LED_ON = 4000, + LED_BLINK_0 = 2500, + LED_BLINK_1 = 1500, + LED_BLINK_2 = 1000, + LED_BLINK_3 = 800, + LED_BLINK_4 = 500, + LED_BLINK_5 = 300, + LED_BLINK_6 = 150, + LED_BLINK_7 = 50 +}; + +uint16_t blink_interval_ms = LED_ON; // Status LED on Start button + +void EasythreedUI::blinkLED() { + static millis_t prev_blink_interval_ms = 0, blink_start_ms = 0; + + if (blink_interval_ms == LED_OFF) { WRITE(EASYTHREED_LED_PIN, HIGH); return; } // OFF + if (blink_interval_ms >= LED_ON) { WRITE(EASYTHREED_LED_PIN, LOW); return; } // ON + + const millis_t ms = millis(); + if (prev_blink_interval_ms != blink_interval_ms) { + prev_blink_interval_ms = blink_interval_ms; + blink_start_ms = ms; + } + if (PENDING(ms, blink_start_ms + blink_interval_ms)) + WRITE(EASYTHREED_LED_PIN, LOW); + else if (PENDING(ms, blink_start_ms + 2 * blink_interval_ms)) + WRITE(EASYTHREED_LED_PIN, HIGH); + else + blink_start_ms = ms; +} + +// +// Filament Load/Unload Button +// Load/Unload buttons are a 3 position switch with a common center ground. +// +void EasythreedUI::loadButton() { + if (printingIsActive()) return; + + enum FilamentStatus : uint8_t { FS_IDLE, FS_PRESS, FS_CHECK, FS_PROCEED }; + static uint8_t filament_status = FS_IDLE; + static millis_t filament_time = 0; + + switch (filament_status) { + + case FS_IDLE: + if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) { // If feed/retract switch is toggled... + filament_status++; // ...proceed to next test. + filament_time = millis(); + } + break; + + case FS_PRESS: + if (ELAPSED(millis(), filament_time + BTN_DEBOUNCE_MS)) { // After a short debounce delay... + if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) { // ...if switch still toggled... + thermalManager.setTargetHotend(EXTRUDE_MINTEMP + 10, 0); // Start heating up + blink_interval_ms = LED_BLINK_7; // Set the LED to blink fast + filament_status++; + } + else + filament_status = FS_IDLE; // Switch not toggled long enough + } + break; + + case FS_CHECK: + if (READ(BTN_RETRACT) && READ(BTN_FEED)) { // Switch in center position (stop) + blink_interval_ms = LED_ON; // LED on steady + filament_status = FS_IDLE; + thermalManager.disable_all_heaters(); + } + else if (thermalManager.hotEnoughToExtrude(0)) { // Is the hotend hot enough to move material? + filament_status++; // Proceed to feed / retract. + blink_interval_ms = LED_BLINK_5; // Blink ~3 times per second + } + break; + + case FS_PROCEED: { + // Feed or Retract just once. Hard abort all moves and return to idle on swicth release. + static bool flag = false; + if (READ(BTN_RETRACT) && READ(BTN_FEED)) { // Switch in center position (stop) + flag = false; // Restore flag to false + filament_status = FS_IDLE; // Go back to idle state + quickstop_stepper(); // Hard-stop all the steppers ... now! + thermalManager.disable_all_heaters(); // And disable all the heaters + blink_interval_ms = LED_ON; + } + else if (!flag) { + flag = true; + queue.inject(!READ(BTN_RETRACT) ? F("G91\nG0 E10 F180\nG0 E-120 F180\nM104 S0") : F("G91\nG0 E100 F120\nM104 S0")); + } + } break; + } + +} + +#if HAS_STEPPER_RESET + void disableStepperDrivers(); +#endif + +// +// Print Start/Pause/Resume Button +// +void EasythreedUI::printButton() { + enum KeyStatus : uint8_t { KS_IDLE, KS_PRESS, KS_PROCEED }; + static uint8_t key_status = KS_IDLE; + static millis_t key_time = 0; + + enum PrintFlag : uint8_t { PF_START, PF_PAUSE, PF_RESUME }; + static PrintFlag print_key_flag = PF_START; + + const millis_t ms = millis(); + + switch (key_status) { + case KS_IDLE: + if (!READ(BTN_PRINT)) { // Print/Pause/Resume button pressed? + key_time = ms; // Save start time + key_status++; // Go to debounce test + } + break; + + case KS_PRESS: + if (ELAPSED(ms, key_time + BTN_DEBOUNCE_MS)) // Wait for debounce interval to expire + key_status = READ(BTN_PRINT) ? KS_IDLE : KS_PROCEED; // Proceed if still pressed + break; + + case KS_PROCEED: + if (!READ(BTN_PRINT)) break; // Wait for the button to be released + key_status = KS_IDLE; // Ready for the next press + if (PENDING(ms, key_time + 1200 - BTN_DEBOUNCE_MS)) { // Register a press < 1.2 seconds + switch (print_key_flag) { + case PF_START: { // The "Print" button starts an SD card print + if (printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?') + blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals + print_key_flag = PF_PAUSE; // The "Print" button now pauses the print + card.mount(); // Force SD card to mount - now! + if (!card.isMounted) { // Failed to mount? + blink_interval_ms = LED_OFF; // Turn off LED + print_key_flag = PF_START; + return; // Bail out + } + card.ls(); // List all files to serial output + const uint16_t filecnt = card.countFilesInWorkDir(); // Count printable files in cwd + if (filecnt == 0) return; // None are printable? + card.selectFileByIndex(filecnt); // Select the last file according to current sort options + card.openAndPrintFile(card.filename); // Start printing it + break; + } + case PF_PAUSE: { // Pause printing (not currently firing) + if (!printingIsActive()) break; + blink_interval_ms = LED_ON; // Set indicator to steady ON + queue.inject(F("M25")); // Queue Pause + print_key_flag = PF_RESUME; // The "Print" button now resumes the print + break; + } + case PF_RESUME: { // Resume printing + if (printingIsActive()) break; + blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals + queue.inject(F("M24")); // Queue resume + print_key_flag = PF_PAUSE; // The "Print" button now pauses the print + break; + } + } + } + else { // Register a longer press + if (print_key_flag == PF_START && !printingIsActive()) { // While not printing, this moves Z up 10mm + blink_interval_ms = LED_ON; + queue.inject(F("G91\nG0 Z10 F600\nG90")); // Raise Z soon after returning to main loop + } + else { // While printing, cancel print + card.abortFilePrintSoon(); // There is a delay while the current steps play out + blink_interval_ms = LED_OFF; // Turn off LED + } + planner.synchronize(); // Wait for commands already in the planner to finish + TERN_(HAS_STEPPER_RESET, disableStepperDrivers()); // Disable all steppers - now! + print_key_flag = PF_START; // The "Print" button now starts a new print + } + break; + } +} +#endif // EASYTHREED_UI diff --git a/Marlin/src/feature/easythreed_ui.h b/Marlin/src/feature/easythreed_ui.h new file mode 100644 index 0000000000..af9ad2d090 --- /dev/null +++ b/Marlin/src/feature/easythreed_ui.h @@ -0,0 +1,35 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +class EasythreedUI { + public: + static void init(); + static void run(); + + private: + static void blinkLED(); + static void loadButton(); + static void printButton(); +}; + +extern EasythreedUI easythreed_ui; diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h index 94f7313996..9f33d4392a 100644 --- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h +++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h @@ -79,31 +79,51 @@ #define FIL_RUNOUT_PIN PB8 // MT_DET +/** ------ + * (BEEPER) PD2 |10 9 | PB3 (BTN_ENC) + * (BTN_EN1) PB5 | 8 7 | PA11 (RESET?) + * (BTN_EN2) PB4 6 5 | PC1 (LCD_D4) + * (LCD_RS) PC3 | 4 3 | PC2 (LCD_EN) + * GND | 2 1 | 5V + * ------ + * "E3" EXP1 + */ +#define E3_EXP1_01_PIN -1 // 5V +#define E3_EXP1_02_PIN -1 // GND +#define E3_EXP1_03_PIN PC2 +#define E3_EXP1_04_PIN PC3 +#define E3_EXP1_05_PIN PC1 +#define E3_EXP1_06_PIN PB4 +#define E3_EXP1_07_PIN PA11 // RESET? +#define E3_EXP1_08_PIN PB5 +#define E3_EXP1_09_PIN PB3 +#define E3_EXP1_10_PIN PD2 + // // LCD Pins // #if HAS_WIRED_LCD - #define BEEPER_PIN PD2 - #define BTN_ENC PB3 - #define LCD_PINS_RS PC3 + #define BEEPER_PIN E3_EXP1_10_PIN + #define BTN_ENC E3_EXP1_09_PIN + #define LCD_PINS_RS E3_EXP1_04_PIN - #define BTN_EN1 PB5 - #define BTN_EN2 PB4 + #define BTN_EN1 E3_EXP1_08_PIN + #define BTN_EN2 E3_EXP1_06_PIN - #define LCD_PINS_ENABLE PC2 + #define LCD_PINS_ENABLE E3_EXP1_03_PIN #if ENABLED(MKS_MINI_12864) #define LCD_BACKLIGHT_PIN -1 #define LCD_RESET_PIN -1 - #define DOGLCD_A0 PC1 - #define DOGLCD_CS PC2 + #define DOGLCD_A0 E3_EXP1_05_PIN + #define DOGLCD_CS E3_EXP1_03_PIN #define DOGLCD_SCK PB13 #define DOGLCD_MOSI PB15 #else // !MKS_MINI_12864 - #define LCD_PINS_D4 PC1 + #define LCD_PINS_D4 E3_EXP1_05_PIN #if IS_ULTIPANEL #define LCD_PINS_D5 -1 #define LCD_PINS_D6 -1 @@ -141,3 +161,15 @@ #define SD_MISO_PIN PB14 #define SD_MOSI_PIN PB15 #define SD_SS_PIN PA15 + +// EXP1 replace LCD with keys for EasyThreeD ET4000+ Mainboard +#if ENABLED(EASYTHREED_UI) + #define BTN_HOME E3_EXP1_04_PIN // INPUT_PULLUP (unused) + #define BTN_FEED E3_EXP1_09_PIN // Run E Forward + #define BTN_RETRACT E3_EXP1_08_PIN // Run E Backward + #define BTN_PRINT E3_EXP1_07_PIN // Start File Print + #define BTN_HOME_GND E3_EXP1_03_PIN // OUTPUT (LOW) + #define BTN_FEED_GND E3_EXP1_06_PIN // OUTPUT (LOW) + #define BTN_RETRACT_GND E3_EXP1_05_PIN // OUTPUT (LOW) + #define EASYTHREED_LED_PIN E3_EXP1_10_PIN // Indicator LED +#endif diff --git a/ini/features.ini b/ini/features.ini index bd8b748d6c..b56565b154 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -112,6 +112,7 @@ HAS_COOLER|LASER_COOLANT_FLOW_METER = src_filter=+ HAS_MOTOR_CURRENT_DAC = src_filter=+ DIRECT_STEPPING = src_filter=+ + EMERGENCY_PARSER = src_filter=+ - +EASYTHREED_UI = src_filter=+ I2C_POSITION_ENCODERS = src_filter=+ IIC_BL24CXX_EEPROM = src_filter=+ HAS_SPI_FLASH = src_filter=+ diff --git a/platformio.ini b/platformio.ini index ce148ce082..1b4effcf25 100644 --- a/platformio.ini +++ b/platformio.ini @@ -110,6 +110,7 @@ default_src_filter = + - - + - - - - - + - - - - -