Pārlūkot izejas kodu

Add laser control menu (#12883)

InsanityAutomation 6 gadus atpakaļ
vecāks
revīzija
a1cf49935d

+ 72
- 42
Marlin/src/gcode/control/M3-M5.cpp Parādīt failu

@@ -27,6 +27,8 @@
27 27
 #include "../gcode.h"
28 28
 #include "../../module/stepper.h"
29 29
 
30
+uint8_t spindle_laser_power; // = 0
31
+
30 32
 /**
31 33
  * M3: Spindle Clockwise
32 34
  * M4: Spindle Counter-clockwise
@@ -59,10 +61,10 @@
59 61
  */
60 62
 
61 63
 // Wait for spindle to come up to speed
62
-inline void delay_for_power_up() { gcode.dwell(SPINDLE_LASER_POWERUP_DELAY); }
64
+inline void delay_for_power_up() { safe_delay(SPINDLE_LASER_POWERUP_DELAY); }
63 65
 
64 66
 // Wait for spindle to stop turning
65
-inline void delay_for_power_down() { gcode.dwell(SPINDLE_LASER_POWERDOWN_DELAY); }
67
+inline void delay_for_power_down() { safe_delay(SPINDLE_LASER_POWERDOWN_DELAY); }
66 68
 
67 69
 /**
68 70
  * ocr_val_mode() is used for debugging and to get the points needed to compute the RPM vs ocr_val line
@@ -70,26 +72,72 @@ inline void delay_for_power_down() { gcode.dwell(SPINDLE_LASER_POWERDOWN_DELAY);
70 72
  * it accepts inputs of 0-255
71 73
  */
72 74
 
73
-inline void ocr_val_mode() {
74
-  uint8_t spindle_laser_power = parser.value_byte();
75
+inline void set_spindle_laser_ocr(const uint8_t ocr) {
75 76
   WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low)
76
-  if (SPINDLE_LASER_PWM_INVERT) spindle_laser_power = 255 - spindle_laser_power;
77
-  analogWrite(SPINDLE_LASER_PWM_PIN, spindle_laser_power);
77
+  analogWrite(SPINDLE_LASER_PWM_PIN, (SPINDLE_LASER_PWM_INVERT) ? 255 - ocr : ocr);
78 78
 }
79 79
 
80
-void GcodeSuite::M3_M4(bool is_M3) {
80
+#if ENABLED(SPINDLE_LASER_PWM)
81 81
 
82
-  planner.synchronize();   // wait until previous movement commands (G0/G0/G2/G3) have completed before playing with the spindle
83
-  #if SPINDLE_DIR_CHANGE
84
-    const bool rotation_dir = (is_M3 != SPINDLE_INVERT_DIR);
85
-    if (SPINDLE_STOP_ON_DIR_CHANGE \
86
-       && READ(SPINDLE_LASER_ENABLE_PIN) == SPINDLE_LASER_ENABLE_INVERT \
87
-       && READ(SPINDLE_DIR_PIN) != rotation_dir
88
-    ) {
89
-      WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);  // turn spindle off
82
+  void update_spindle_laser_power() {
83
+    if (spindle_laser_power == 0) {
84
+      WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);                      // turn spindle off (active low)
85
+      analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0);             // only write low byte
86
+      delay_for_power_down();
87
+    }
88
+    else {                                                                                // Convert RPM to PWM duty cycle
89
+      constexpr float inv_slope = 1.0f / (SPEED_POWER_SLOPE),
90
+                      min_ocr = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * inv_slope,  // Minimum allowed
91
+                      max_ocr = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * inv_slope;  // Maximum allowed
92
+      int16_t ocr_val;
93
+           if (spindle_laser_power <= SPEED_POWER_MIN) ocr_val = min_ocr;                 // Use minimum if set below
94
+      else if (spindle_laser_power >= SPEED_POWER_MAX) ocr_val = max_ocr;                 // Use maximum if set above
95
+      else ocr_val = (spindle_laser_power - (SPEED_POWER_INTERCEPT)) * inv_slope;         // Use calculated OCR value
96
+      set_spindle_laser_ocr(ocr_val & 0xFF);                                              // ...limited to Atmel PWM max
97
+      delay_for_power_up();
98
+    }
99
+  }
100
+
101
+#endif // SPINDLE_LASER_PWM
102
+
103
+bool spindle_laser_enabled() {
104
+  return !!spindle_laser_power; // READ(SPINDLE_LASER_ENABLE_PIN) == SPINDLE_LASER_ENABLE_INVERT;
105
+}
106
+
107
+void set_spindle_laser_enabled(const bool enable) {
108
+  // Enabled by PWM setting elsewhere
109
+  spindle_laser_power = enable ? 255 : 0;
110
+  #if ENABLED(SPINDLE_LASER_PWM)
111
+    update_spindle_laser_power();
112
+  #else
113
+    if (enable) {
114
+      WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT);
115
+      delay_for_power_up();
116
+    }
117
+    else {
118
+      WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);
90 119
       delay_for_power_down();
91 120
     }
92
-    WRITE(SPINDLE_DIR_PIN, rotation_dir);
121
+  #endif
122
+}
123
+
124
+#if SPINDLE_DIR_CHANGE
125
+
126
+  void set_spindle_direction(const bool reverse_dir) {
127
+    const bool dir_state = (reverse_dir == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted
128
+    if (SPINDLE_STOP_ON_DIR_CHANGE && spindle_laser_enabled() && READ(SPINDLE_DIR_PIN) != dir_state)
129
+      set_spindle_laser_enabled(false);
130
+    WRITE(SPINDLE_DIR_PIN, dir_state);
131
+  }
132
+
133
+#endif
134
+
135
+void GcodeSuite::M3_M4(const bool is_M4) {
136
+
137
+  planner.synchronize();   // wait until previous movement commands (G0/G0/G2/G3) have completed before playing with the spindle
138
+
139
+  #if SPINDLE_DIR_CHANGE
140
+    set_spindle_direction(is_M4);
93 141
   #endif
94 142
 
95 143
   /**
@@ -98,30 +146,16 @@ void GcodeSuite::M3_M4(bool is_M3) {
98 146
    * Then needed to AND the uint16_t result with 0x00FF to make sure we only wrote the byte of interest.
99 147
    */
100 148
   #if ENABLED(SPINDLE_LASER_PWM)
101
-    if (parser.seen('O')) ocr_val_mode();
149
+    if (parser.seen('O')) {
150
+      spindle_laser_power = parser.value_byte();
151
+      set_spindle_laser_ocr(spindle_laser_power);
152
+    }
102 153
     else {
103
-      const float spindle_laser_power = parser.floatval('S');
104
-      if (spindle_laser_power == 0) {
105
-        WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);                                    // turn spindle off (active low)
106
-        analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0);                           // only write low byte
107
-        delay_for_power_down();
108
-      }
109
-      else {
110
-        int16_t ocr_val = (spindle_laser_power - (SPEED_POWER_INTERCEPT)) * (1.0f / (SPEED_POWER_SLOPE));  // convert RPM to PWM duty cycle
111
-        NOMORE(ocr_val, 255);                                                                             // limit to max the Atmel PWM will support
112
-        if (spindle_laser_power <= SPEED_POWER_MIN)
113
-          ocr_val = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * (1.0f / (SPEED_POWER_SLOPE));            // minimum setting
114
-        if (spindle_laser_power >= SPEED_POWER_MAX)
115
-          ocr_val = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * (1.0f / (SPEED_POWER_SLOPE));            // limit to max RPM
116
-        if (SPINDLE_LASER_PWM_INVERT) ocr_val = 255 - ocr_val;
117
-        WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT);                                     // turn spindle on (active low)
118
-        analogWrite(SPINDLE_LASER_PWM_PIN, ocr_val & 0xFF);                                               // only write low byte
119
-        delay_for_power_up();
120
-      }
154
+      spindle_laser_power = parser.intval('S', 255);
155
+      update_spindle_laser_power();
121 156
     }
122 157
   #else
123
-    WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) if spindle speed option not enabled
124
-    delay_for_power_up();
158
+    set_spindle_laser_enabled(true);
125 159
   #endif
126 160
 }
127 161
 
@@ -130,11 +164,7 @@ void GcodeSuite::M3_M4(bool is_M3) {
130 164
  */
131 165
 void GcodeSuite::M5() {
132 166
   planner.synchronize();
133
-  WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);
134
-  #if ENABLED(SPINDLE_LASER_PWM)
135
-    analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0);
136
-  #endif
137
-  delay_for_power_down();
167
+  set_spindle_laser_enabled(false);
138 168
 }
139 169
 
140 170
 #endif // SPINDLE_LASER_ENABLE

+ 2
- 2
Marlin/src/gcode/gcode.cpp Parādīt failu

@@ -285,8 +285,8 @@ void GcodeSuite::process_parsed_command(
285 285
       #endif
286 286
 
287 287
       #if ENABLED(SPINDLE_LASER_ENABLE)
288
-        case 3: M3_M4(true ); break;                              // M3: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CW
289
-        case 4: M3_M4(false); break;                              // M4: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CCW
288
+        case 3: M3_M4(false); break;                              // M3: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CW
289
+        case 4: M3_M4(true ); break;                              // M4: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CCW
290 290
         case 5: M5(); break;                                      // M5 - turn spindle/laser off
291 291
       #endif
292 292
 

+ 1
- 1
Marlin/src/gcode/gcode.h Parādīt failu

@@ -437,7 +437,7 @@ private:
437 437
   #endif
438 438
 
439 439
   #if ENABLED(SPINDLE_LASER_ENABLE)
440
-    static void M3_M4(bool is_M3);
440
+    static void M3_M4(const bool is_M4);
441 441
     static void M5();
442 442
   #endif
443 443
 

+ 15
- 0
Marlin/src/lcd/language/language_en.h Parādīt failu

@@ -169,6 +169,21 @@
169 169
 #ifndef MSG_COOLDOWN
170 170
   #define MSG_COOLDOWN                        _UxGT("Cooldown")
171 171
 #endif
172
+#ifndef MSG_LASER
173
+  #define MSG_LASER                           _UxGT("Laser")
174
+#endif
175
+#ifndef MSG_LASER_OFF
176
+  #define MSG_LASER_OFF                       MSG_LASER _UxGT(" Off")
177
+#endif
178
+#ifndef MSG_LASER_ON
179
+  #define MSG_LASER_ON                        MSG_LASER _UxGT(" On")
180
+#endif
181
+#ifndef MSG_LASER_POWER
182
+  #define MSG_LASER_POWER                     MSG_LASER _UxGT(" power")
183
+#endif
184
+#ifndef MSG_SPINDLE_REVERSE
185
+  #define MSG_SPINDLE_REVERSE                 _UxGT("Spindle Reverse")
186
+#endif
172 187
 #ifndef MSG_SWITCH_PS_ON
173 188
   #define MSG_SWITCH_PS_ON                    _UxGT("Switch power on")
174 189
 #endif

+ 45
- 0
Marlin/src/lcd/menu/menu_temperature.cpp Parādīt failu

@@ -303,6 +303,47 @@ void _lcd_preheat(const int16_t endnum, const int16_t temph, const int16_t tempb
303 303
 
304 304
 #endif // HAS_TEMP_HOTEND || HAS_HEATED_BED
305 305
 
306
+#if ENABLED(SPINDLE_LASER_ENABLE)
307
+
308
+  extern uint8_t spindle_laser_power;
309
+  bool spindle_laser_enabled();
310
+  void set_spindle_laser_enabled(const bool enabled);
311
+  #if ENABLED(SPINDLE_LASER_PWM)
312
+    void update_spindle_laser_power();
313
+  #endif
314
+
315
+  inline void _lcd_spindle_laser_off() { set_spindle_laser_enabled(false); }
316
+  inline void _lcd_spindle_laser_on(const bool is_M4) {
317
+    #if SPINDLE_DIR_CHANGE
318
+      set_spindle_direction(is_M4);
319
+    #endif
320
+    set_spindle_laser_enabled(true);
321
+  }
322
+  inline void _lcd_spindle_laser_on() { _lcd_spindle_laser_on(false); }
323
+  #if SPINDLE_DIR_CHANGE
324
+    inline void _lcd_spindle_on_reverse() { _lcd_spindle_laser_on(true); }
325
+  #endif
326
+
327
+  void menu_spindle_laser() {
328
+    START_MENU();
329
+    MENU_BACK(MSG_MAIN);
330
+    if (spindle_laser_enabled()) {
331
+      #if ENABLED(SPINDLE_LASER_PWM)
332
+        MENU_ITEM_EDIT_CALLBACK(int3, MSG_LASER_POWER, &spindle_laser_power, SPEED_POWER_MIN, SPEED_POWER_MAX, update_spindle_laser_power);
333
+      #endif
334
+      MENU_ITEM(function, MSG_LASER_OFF, _lcd_spindle_laser_off);
335
+    }
336
+    else {
337
+      MENU_ITEM(function, MSG_LASER_ON, _lcd_spindle_laser_on);
338
+      #if SPINDLE_DIR_CHANGE
339
+        MENU_ITEM(function, MSG_SPINDLE_REVERSE, _lcd_spindle_on_reverse);
340
+      #endif
341
+    }
342
+    END_MENU();
343
+  }
344
+
345
+#endif // SPINDLE_LASER_ENABLE
346
+
306 347
 void menu_temperature() {
307 348
   START_MENU();
308 349
   MENU_BACK(MSG_MAIN);
@@ -391,6 +432,10 @@ void menu_temperature() {
391 432
 
392 433
   #endif // HAS_TEMP_HOTEND
393 434
 
435
+  #if ENABLED(SPINDLE_LASER_ENABLE)
436
+    MENU_ITEM(submenu, MSG_LASER_MENU, menu_spindle_laser);
437
+  #endif
438
+
394 439
   END_MENU();
395 440
 }
396 441
 

Notiek ielāde…
Atcelt
Saglabāt