Browse Source

✨ EasyThreeD ET4000+ board and UI (#23080)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
schmttc 2 years ago
parent
commit
d4c78edfe3
No account linked to committer's email address

+ 5
- 0
Marlin/Configuration.h View File

@@ -2825,6 +2825,11 @@
2825 2825
 //#define REPRAPWORLD_KEYPAD
2826 2826
 //#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press
2827 2827
 
2828
+//
2829
+// EasyThreeD ET-4000+ with button input and status LED
2830
+//
2831
+//#define EASYTHREED_UI
2832
+
2828 2833
 //=============================================================================
2829 2834
 //=============================== Extra Features ==============================
2830 2835
 //=============================================================================

+ 10
- 0
Marlin/src/MarlinCore.cpp View File

@@ -248,6 +248,10 @@
248 248
   #include "feature/power.h"
249 249
 #endif
250 250
 
251
+#if ENABLED(EASYTHREED_UI)
252
+  #include "feature/easythreed_ui.h"
253
+#endif
254
+
251 255
 PGMSTR(M112_KILL_STR, "M112 Shutdown");
252 256
 
253 257
 MarlinState marlin_state = MF_INITIALIZING;
@@ -637,6 +641,8 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
637 641
     #endif
638 642
   #endif
639 643
 
644
+  TERN_(EASYTHREED_UI, easythreed_ui.run());
645
+
640 646
   TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down
641 647
 
642 648
   TERN_(AUTO_POWER_CONTROL, powerManager.check(!ui.on_status_screen() || printJobOngoing() || printingIsPaused()));
@@ -1606,6 +1612,10 @@ void setup() {
1606 1612
     SETUP_RUN(ui.check_touch_calibration());
1607 1613
   #endif
1608 1614
 
1615
+  #if ENABLED(EASYTHREED_UI)
1616
+    SETUP_RUN(easythreed_ui.init());
1617
+  #endif
1618
+
1609 1619
   marlin_state = MF_RUNNING;
1610 1620
 
1611 1621
   SETUP_LOG("setup() completed.");

+ 236
- 0
Marlin/src/feature/easythreed_ui.cpp View File

@@ -0,0 +1,236 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../inc/MarlinConfigPre.h"
24
+
25
+#if ENABLED(EASYTHREED_UI)
26
+
27
+#include "easythreed_ui.h"
28
+#include "pause.h"
29
+#include "../module/temperature.h"
30
+#include "../module/printcounter.h"
31
+#include "../sd/cardreader.h"
32
+#include "../gcode/queue.h"
33
+#include "../module/motion.h"
34
+#include "../module/planner.h"
35
+#include "../MarlinCore.h"
36
+
37
+EasythreedUI easythreed_ui;
38
+
39
+#define BTN_DEBOUNCE_MS 20
40
+
41
+void EasythreedUI::init() {
42
+  SET_INPUT_PULLUP(BTN_HOME);     SET_OUTPUT(BTN_HOME_GND);
43
+  SET_INPUT_PULLUP(BTN_FEED);     SET_OUTPUT(BTN_FEED_GND);
44
+  SET_INPUT_PULLUP(BTN_RETRACT);  SET_OUTPUT(BTN_RETRACT_GND);
45
+  SET_INPUT_PULLUP(BTN_PRINT);
46
+  SET_OUTPUT(EASYTHREED_LED_PIN);
47
+}
48
+
49
+void EasythreedUI::run() {
50
+  blinkLED();
51
+  loadButton();
52
+  printButton();
53
+}
54
+
55
+enum LEDInterval : uint16_t {
56
+  LED_OFF     =    0,
57
+  LED_ON      = 4000,
58
+  LED_BLINK_0 = 2500,
59
+  LED_BLINK_1 = 1500,
60
+  LED_BLINK_2 = 1000,
61
+  LED_BLINK_3 =  800,
62
+  LED_BLINK_4 =  500,
63
+  LED_BLINK_5 =  300,
64
+  LED_BLINK_6 =  150,
65
+  LED_BLINK_7 =   50
66
+};
67
+
68
+uint16_t blink_interval_ms = LED_ON;   // Status LED on Start button
69
+
70
+void EasythreedUI::blinkLED() {
71
+  static millis_t prev_blink_interval_ms = 0, blink_start_ms = 0;
72
+
73
+  if (blink_interval_ms == LED_OFF) { WRITE(EASYTHREED_LED_PIN, HIGH); return; } // OFF
74
+  if (blink_interval_ms >= LED_ON)  { WRITE(EASYTHREED_LED_PIN,  LOW); return; } // ON
75
+
76
+  const millis_t ms = millis();
77
+  if (prev_blink_interval_ms != blink_interval_ms) {
78
+    prev_blink_interval_ms = blink_interval_ms;
79
+    blink_start_ms = ms;
80
+  }
81
+  if (PENDING(ms, blink_start_ms + blink_interval_ms))
82
+    WRITE(EASYTHREED_LED_PIN, LOW);
83
+  else if (PENDING(ms, blink_start_ms + 2 * blink_interval_ms))
84
+    WRITE(EASYTHREED_LED_PIN, HIGH);
85
+  else
86
+    blink_start_ms = ms;
87
+}
88
+
89
+//
90
+// Filament Load/Unload Button
91
+// Load/Unload buttons are a 3 position switch with a common center ground. 
92
+//
93
+void EasythreedUI::loadButton() {
94
+  if (printingIsActive()) return;
95
+
96
+  enum FilamentStatus : uint8_t { FS_IDLE, FS_PRESS, FS_CHECK, FS_PROCEED };
97
+  static uint8_t filament_status = FS_IDLE;
98
+  static millis_t filament_time = 0;
99
+
100
+  switch (filament_status) {
101
+
102
+    case FS_IDLE:
103
+      if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) {                  // If feed/retract switch is toggled...
104
+        filament_status++;                                          // ...proceed to next test.
105
+        filament_time = millis();
106
+      }
107
+      break;
108
+
109
+    case FS_PRESS:
110
+      if (ELAPSED(millis(), filament_time + BTN_DEBOUNCE_MS)) {     // After a short debounce delay...
111
+        if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) {                // ...if switch still toggled...
112
+          thermalManager.setTargetHotend(EXTRUDE_MINTEMP + 10, 0);  // Start heating up
113
+          blink_interval_ms = LED_BLINK_7;                          // Set the LED to blink fast
114
+          filament_status++;
115
+        }
116
+        else
117
+          filament_status = FS_IDLE;                                // Switch not toggled long enough
118
+      }
119
+      break;
120
+
121
+    case FS_CHECK:
122
+      if (READ(BTN_RETRACT) && READ(BTN_FEED)) {                    // Switch in center position (stop)
123
+        blink_interval_ms = LED_ON;                                 // LED on steady
124
+        filament_status = FS_IDLE;
125
+        thermalManager.disable_all_heaters();
126
+      }
127
+      else if (thermalManager.hotEnoughToExtrude(0)) {              // Is the hotend hot enough to move material?
128
+        filament_status++;                                          // Proceed to feed / retract.
129
+        blink_interval_ms = LED_BLINK_5;                            // Blink ~3 times per second
130
+      }
131
+      break;
132
+
133
+    case FS_PROCEED: {
134
+      // Feed or Retract just once. Hard abort all moves and return to idle on swicth release.
135
+      static bool flag = false;
136
+      if (READ(BTN_RETRACT) && READ(BTN_FEED)) {                    // Switch in center position (stop)
137
+        flag = false;                                               // Restore flag to false
138
+        filament_status = FS_IDLE;                                  // Go back to idle state
139
+        quickstop_stepper();                                        // Hard-stop all the steppers ... now!
140
+        thermalManager.disable_all_heaters();                       // And disable all the heaters
141
+        blink_interval_ms = LED_ON;
142
+      }
143
+      else if (!flag) {
144
+        flag = true;
145
+        queue.inject(!READ(BTN_RETRACT) ? F("G91\nG0 E10 F180\nG0 E-120 F180\nM104 S0") : F("G91\nG0 E100 F120\nM104 S0"));
146
+      }
147
+    } break;
148
+  }
149
+
150
+}
151
+
152
+#if HAS_STEPPER_RESET
153
+  void disableStepperDrivers();
154
+#endif
155
+
156
+//
157
+// Print Start/Pause/Resume Button
158
+//
159
+void EasythreedUI::printButton() {
160
+  enum KeyStatus : uint8_t { KS_IDLE, KS_PRESS, KS_PROCEED };
161
+  static uint8_t key_status = KS_IDLE;
162
+  static millis_t key_time = 0;
163
+
164
+  enum PrintFlag : uint8_t { PF_START, PF_PAUSE, PF_RESUME };
165
+  static PrintFlag print_key_flag = PF_START;
166
+
167
+  const millis_t ms = millis();
168
+
169
+  switch (key_status) {
170
+    case KS_IDLE:
171
+      if (!READ(BTN_PRINT)) {                                       // Print/Pause/Resume button pressed?
172
+        key_time = ms;                                              // Save start time
173
+        key_status++;                                               // Go to debounce test
174
+      }
175
+      break;
176
+
177
+    case KS_PRESS:
178
+      if (ELAPSED(ms, key_time + BTN_DEBOUNCE_MS))                  // Wait for debounce interval to expire
179
+        key_status = READ(BTN_PRINT) ? KS_IDLE : KS_PROCEED;        // Proceed if still pressed
180
+      break;
181
+
182
+    case KS_PROCEED:
183
+      if (!READ(BTN_PRINT)) break;                                  // Wait for the button to be released
184
+      key_status = KS_IDLE;                                         // Ready for the next press
185
+      if (PENDING(ms, key_time + 1200 - BTN_DEBOUNCE_MS)) {         // Register a press < 1.2 seconds
186
+        switch (print_key_flag) {
187
+          case PF_START: {                                          // The "Print" button starts an SD card print
188
+            if (printingIsActive()) break;                          // Already printing? (find another line that checks for 'is planner doing anything else right now?')
189
+            blink_interval_ms = LED_BLINK_2;                        // Blink the indicator LED at 1 second intervals
190
+            print_key_flag = PF_PAUSE;                              // The "Print" button now pauses the print
191
+            card.mount();                                           // Force SD card to mount - now!
192
+            if (!card.isMounted) {                                  // Failed to mount?
193
+                blink_interval_ms = LED_OFF;                        // Turn off LED
194
+                print_key_flag = PF_START;
195
+                return;                                             // Bail out
196
+            }
197
+            card.ls();                                            // List all files to serial output
198
+            const uint16_t filecnt = card.countFilesInWorkDir();  // Count printable files in cwd
199
+            if (filecnt == 0) return;                             // None are printable?
200
+            card.selectFileByIndex(filecnt);                      // Select the last file according to current sort options
201
+            card.openAndPrintFile(card.filename);                 // Start printing it
202
+            break;
203
+          }
204
+          case PF_PAUSE: {                                          // Pause printing (not currently firing)
205
+            if (!printingIsActive()) break;
206
+            blink_interval_ms = LED_ON;                             // Set indicator to steady ON
207
+            queue.inject(F("M25"));                                 // Queue Pause
208
+            print_key_flag = PF_RESUME;                             // The "Print" button now resumes the print
209
+            break;
210
+            }
211
+          case PF_RESUME: {                                         // Resume printing 
212
+            if (printingIsActive()) break;
213
+            blink_interval_ms = LED_BLINK_2;                        // Blink the indicator LED at 1 second intervals
214
+            queue.inject(F("M24"));                                 // Queue resume
215
+            print_key_flag = PF_PAUSE;                              // The "Print" button now pauses the print
216
+            break;
217
+          }
218
+        }
219
+      }
220
+      else {                                                        // Register a longer press
221
+        if (print_key_flag == PF_START && !printingIsActive())  {   // While not printing, this moves Z up 10mm
222
+          blink_interval_ms = LED_ON;
223
+          queue.inject(F("G91\nG0 Z10 F600\nG90"));                 // Raise Z soon after returning to main loop
224
+        }
225
+        else {                                                      // While printing, cancel print
226
+          card.abortFilePrintSoon();                                // There is a delay while the current steps play out
227
+          blink_interval_ms = LED_OFF;                              // Turn off LED
228
+        }
229
+        planner.synchronize();                                      // Wait for commands already in the planner to finish
230
+        TERN_(HAS_STEPPER_RESET, disableStepperDrivers());          // Disable all steppers - now!
231
+        print_key_flag = PF_START;                                  // The "Print" button now starts a new print
232
+      }
233
+      break;
234
+  }
235
+}
236
+#endif // EASYTHREED_UI

+ 35
- 0
Marlin/src/feature/easythreed_ui.h View File

@@ -0,0 +1,35 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+class EasythreedUI {
25
+  public:
26
+    static void init();
27
+    static void run();
28
+
29
+  private:
30
+    static void blinkLED();
31
+    static void loadButton();
32
+    static void printButton();
33
+};
34
+
35
+extern EasythreedUI easythreed_ui;

+ 41
- 9
Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h View File

@@ -79,31 +79,51 @@
79 79
 
80 80
 #define FIL_RUNOUT_PIN                      PB8   // MT_DET
81 81
 
82
+/**                ------
83
+ *   (BEEPER) PD2 |10  9 | PB3  (BTN_ENC)
84
+ *  (BTN_EN1) PB5 | 8  7 | PA11 (RESET?)
85
+ *  (BTN_EN2) PB4   6  5 | PC1  (LCD_D4)
86
+ *   (LCD_RS) PC3 | 4  3 | PC2  (LCD_EN)
87
+ *            GND | 2  1 | 5V
88
+ *                 ------
89
+ *               "E3" EXP1
90
+ */
91
+#define E3_EXP1_01_PIN                      -1    // 5V
92
+#define E3_EXP1_02_PIN                      -1    // GND
93
+#define E3_EXP1_03_PIN                      PC2
94
+#define E3_EXP1_04_PIN                      PC3
95
+#define E3_EXP1_05_PIN                      PC1
96
+#define E3_EXP1_06_PIN                      PB4
97
+#define E3_EXP1_07_PIN                      PA11  // RESET?
98
+#define E3_EXP1_08_PIN                      PB5
99
+#define E3_EXP1_09_PIN                      PB3
100
+#define E3_EXP1_10_PIN                      PD2
101
+
82 102
 //
83 103
 // LCD Pins
84 104
 //
85 105
 #if HAS_WIRED_LCD
86
-  #define BEEPER_PIN                        PD2
87
-  #define BTN_ENC                           PB3
88
-  #define LCD_PINS_RS                       PC3
106
+  #define BEEPER_PIN              E3_EXP1_10_PIN
107
+  #define BTN_ENC                 E3_EXP1_09_PIN
108
+  #define LCD_PINS_RS             E3_EXP1_04_PIN
89 109
 
90
-  #define BTN_EN1                           PB5
91
-  #define BTN_EN2                           PB4
110
+  #define BTN_EN1                 E3_EXP1_08_PIN
111
+  #define BTN_EN2                 E3_EXP1_06_PIN
92 112
 
93
-  #define LCD_PINS_ENABLE                   PC2
113
+  #define LCD_PINS_ENABLE         E3_EXP1_03_PIN
94 114
 
95 115
   #if ENABLED(MKS_MINI_12864)
96 116
 
97 117
     #define LCD_BACKLIGHT_PIN               -1
98 118
     #define LCD_RESET_PIN                   -1
99
-    #define DOGLCD_A0                       PC1
100
-    #define DOGLCD_CS                       PC2
119
+    #define DOGLCD_A0             E3_EXP1_05_PIN
120
+    #define DOGLCD_CS             E3_EXP1_03_PIN
101 121
     #define DOGLCD_SCK                      PB13
102 122
     #define DOGLCD_MOSI                     PB15
103 123
 
104 124
   #else                                           // !MKS_MINI_12864
105 125
 
106
-    #define LCD_PINS_D4                     PC1
126
+    #define LCD_PINS_D4           E3_EXP1_05_PIN
107 127
     #if IS_ULTIPANEL
108 128
       #define LCD_PINS_D5                   -1
109 129
       #define LCD_PINS_D6                   -1
@@ -141,3 +161,15 @@
141 161
 #define SD_MISO_PIN                         PB14
142 162
 #define SD_MOSI_PIN                         PB15
143 163
 #define SD_SS_PIN                           PA15
164
+
165
+// EXP1 replace LCD with keys for EasyThreeD ET4000+ Mainboard
166
+#if ENABLED(EASYTHREED_UI)
167
+  #define BTN_HOME                E3_EXP1_04_PIN  // INPUT_PULLUP (unused)
168
+  #define BTN_FEED                E3_EXP1_09_PIN  // Run E Forward
169
+  #define BTN_RETRACT             E3_EXP1_08_PIN  // Run E Backward
170
+  #define BTN_PRINT               E3_EXP1_07_PIN  // Start File Print
171
+  #define BTN_HOME_GND            E3_EXP1_03_PIN  // OUTPUT (LOW)
172
+  #define BTN_FEED_GND            E3_EXP1_06_PIN  // OUTPUT (LOW)
173
+  #define BTN_RETRACT_GND         E3_EXP1_05_PIN  // OUTPUT (LOW)
174
+  #define EASYTHREED_LED_PIN      E3_EXP1_10_PIN  // Indicator LED
175
+#endif

+ 1
- 0
ini/features.ini View File

@@ -111,6 +111,7 @@ HAS_COOLER|LASER_COOLANT_FLOW_METER    = src_filter=+<src/feature/cooler.cpp>
111 111
 HAS_MOTOR_CURRENT_DAC                  = src_filter=+<src/feature/dac>
112 112
 DIRECT_STEPPING                        = src_filter=+<src/feature/direct_stepping.cpp> +<src/gcode/motion/G6.cpp>
113 113
 EMERGENCY_PARSER                       = src_filter=+<src/feature/e_parser.cpp> -<src/gcode/control/M108_*.cpp>
114
+EASYTHREED_UI                          = src_filter=+<src/feature/easythreed_ui.cpp>
114 115
 I2C_POSITION_ENCODERS                  = src_filter=+<src/feature/encoder_i2c.cpp>
115 116
 IIC_BL24CXX_EEPROM                     = src_filter=+<src/libs/BL24CXX.cpp>
116 117
 HAS_SPI_FLASH                          = src_filter=+<src/libs/W25Qxx.cpp>

+ 1
- 0
platformio.ini View File

@@ -109,6 +109,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
109 109
   -<src/feature/dac> -<src/feature/digipot>
110 110
   -<src/feature/direct_stepping.cpp> -<src/gcode/motion/G6.cpp>
111 111
   -<src/feature/e_parser.cpp>
112
+  -<src/feature/easythreed_ui.cpp>
112 113
   -<src/feature/encoder_i2c.cpp>
113 114
   -<src/feature/ethernet.cpp> -<src/gcode/feature/network/M552-M554.cpp>
114 115
   -<src/feature/fancheck.cpp>

Loading…
Cancel
Save