Browse Source

Add LIN_ADVANCE

Sebastianv650 8 years ago
parent
commit
fb8e880734
6 changed files with 178 additions and 3 deletions
  1. 9
    0
      Marlin/Configuration_adv.h
  2. 16
    0
      Marlin/Marlin_main.cpp
  3. 12
    0
      Marlin/planner.cpp
  4. 4
    0
      Marlin/planner.h
  5. 111
    2
      Marlin/stepper.cpp
  6. 26
    1
      Marlin/stepper.h

+ 9
- 0
Marlin/Configuration_adv.h View File

@@ -457,6 +457,15 @@
457 457
   #define MESH_MAX_Y (Y_MAX_POS - (MESH_INSET))
458 458
 #endif
459 459
 
460
+//Implementation of a linear pressure control
461
+//Assumption: advance = k * (delta velocity)
462
+//K=0 means advance disabled. A good value for a gregs wade extruder will be around K=75
463
+#define LIN_ADVANCE
464
+
465
+#if ENABLED(LIN_ADVANCE)
466
+  #define LIN_K 75
467
+#endif
468
+
460 469
 // @section extras
461 470
 
462 471
 // Arc interpretation settings:

+ 16
- 0
Marlin/Marlin_main.cpp View File

@@ -6468,6 +6468,16 @@ inline void gcode_M503() {
6468 6468
 
6469 6469
 #endif // DUAL_X_CARRIAGE
6470 6470
 
6471
+#if ENABLED(LIN_ADVANCE)
6472
+/**
6473
+ * M905: Set advance factor
6474
+ */
6475
+inline void gcode_M905() {
6476
+  stepper.synchronize();
6477
+  stepper.advance_M905();
6478
+}
6479
+#endif
6480
+
6471 6481
 /**
6472 6482
  * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
6473 6483
  */
@@ -7339,6 +7349,12 @@ void process_next_command() {
7339 7349
           gcode_M605();
7340 7350
           break;
7341 7351
       #endif // DUAL_X_CARRIAGE
7352
+      
7353
+      #if ENABLED(LIN_ADVANCE)
7354
+        case 905: // M905 Set advance factor.
7355
+          gcode_M905();
7356
+          break;
7357
+      #endif
7342 7358
 
7343 7359
       case 907: // M907 Set digital trimpot motor current using axis codes.
7344 7360
         gcode_M907();

+ 12
- 0
Marlin/planner.cpp View File

@@ -1045,6 +1045,18 @@ void Planner::check_axes_activity() {
1045 1045
   // the maximum junction speed and may always be ignored for any speed reduction checks.
1046 1046
   block->nominal_length_flag = (block->nominal_speed <= v_allowable);
1047 1047
   block->recalculate_flag = true; // Always calculate trapezoid for new block
1048
+  
1049
+  #ifdef LIN_ADVANCE
1050
+    //bse = allsteps: A problem occures if there is a very tiny move before a retract.
1051
+    //In this case, the retract and the move will be executed together. This leads to an enormus amount advance steps due to a hughe e_acceleration.
1052
+    //The math is correct, but you don't want a retract move done with advance! This situation has to be filtered out.
1053
+    if ((!bse || (!bsx && !bsy && !bsz)) || (stepper.get_advance_k() == 0) || (bse == allsteps)) {
1054
+      block->use_advance_lead = false;
1055
+    } else {
1056
+      block->use_advance_lead = true;
1057
+      block->e_speed_multiplier8 = (block->steps[E_AXIS] << 8) / block->step_event_count;
1058
+    }
1059
+  #endif
1048 1060
 
1049 1061
   // Update previous path unit_vector and nominal speed
1050 1062
   for (int i = 0; i < NUM_AXIS; i++) previous_speed[i] = current_speed[i];

+ 4
- 0
Marlin/planner.h View File

@@ -70,6 +70,10 @@ typedef struct {
70 70
     volatile long final_advance;
71 71
     float advance;
72 72
   #endif
73
+  #ifdef LIN_ADVANCE
74
+    bool use_advance_lead;
75
+    int e_speed_multiplier8; //factorised by 2^8 to avoid float
76
+  #endif
73 77
 
74 78
   // Fields used by the motion planner to manage acceleration
75 79
   float nominal_speed,                               // The nominal speed for this block in mm/sec

+ 111
- 2
Marlin/stepper.cpp View File

@@ -351,6 +351,22 @@ void Stepper::isr() {
351 351
           e_steps[current_block->active_extruder] += motor_direction(E_AXIS) ? -1 : 1;
352 352
         }
353 353
       #endif //ADVANCE
354
+      
355
+      #if ENABLED(LIN_ADVANCE)
356
+        counter_E += current_block->steps[E_AXIS];
357
+        if (counter_E > 0) {
358
+          counter_E -= current_block->step_event_count;
359
+          count_position[_AXIS(E)] += count_direction[_AXIS(E)];
360
+          e_steps[current_block->active_extruder] += motor_direction(E_AXIS) ? -1 : 1;
361
+        }
362
+        
363
+        if (current_block->use_advance_lead){
364
+          int delta_adv_steps; //Maybe a char would be enough?
365
+          delta_adv_steps = (((long)extruder_advance_k * current_estep_rate[current_block->active_extruder]) >> 9) - current_adv_steps[current_block->active_extruder];
366
+          e_steps[current_block->active_extruder] += delta_adv_steps;
367
+          current_adv_steps[current_block->active_extruder] += delta_adv_steps;
368
+        }
369
+      #endif //LIN_ADVANCE
354 370
 
355 371
       #define _COUNTER(AXIS) counter_## AXIS
356 372
       #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
@@ -363,7 +379,7 @@ void Stepper::isr() {
363 379
       STEP_ADD(X);
364 380
       STEP_ADD(Y);
365 381
       STEP_ADD(Z);
366
-      #if DISABLED(ADVANCE)
382
+      #if (DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE))
367 383
         STEP_ADD(E);
368 384
       #endif
369 385
 
@@ -377,7 +393,7 @@ void Stepper::isr() {
377 393
       STEP_IF_COUNTER(X);
378 394
       STEP_IF_COUNTER(Y);
379 395
       STEP_IF_COUNTER(Z);
380
-      #if DISABLED(ADVANCE)
396
+      #if (DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE))
381 397
         STEP_IF_COUNTER(E);
382 398
       #endif
383 399
 
@@ -398,6 +414,12 @@ void Stepper::isr() {
398 414
       timer = calc_timer(acc_step_rate);
399 415
       OCR1A = timer;
400 416
       acceleration_time += timer;
417
+      
418
+      #if ENABLED(LIN_ADVANCE)
419
+        if (current_block->use_advance_lead){
420
+          current_estep_rate[current_block->active_extruder] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8;
421
+        }
422
+      #endif
401 423
 
402 424
       #if ENABLED(ADVANCE)
403 425
 
@@ -424,6 +446,12 @@ void Stepper::isr() {
424 446
       timer = calc_timer(step_rate);
425 447
       OCR1A = timer;
426 448
       deceleration_time += timer;
449
+      
450
+      #if ENABLED(LIN_ADVANCE)
451
+        if (current_block->use_advance_lead){
452
+          current_estep_rate[current_block->active_extruder] = ((unsigned long)step_rate * current_block->e_speed_multiplier8) >> 8;
453
+        }
454
+      #endif
427 455
 
428 456
       #if ENABLED(ADVANCE)
429 457
         advance -= advance_rate * step_loops;
@@ -436,6 +464,12 @@ void Stepper::isr() {
436 464
       #endif //ADVANCE
437 465
     }
438 466
     else {
467
+      #ifdef LIN_ADVANCE
468
+        if (current_block->use_advance_lead){
469
+          current_estep_rate[current_block->active_extruder] = final_estep_rate;
470
+        }
471
+      #endif
472
+      
439 473
       OCR1A = OCR1A_nominal;
440 474
       // ensure we're running at the correct step rate, even if we just came off an acceleration
441 475
       step_loops = step_loops_nominal;
@@ -491,6 +525,55 @@ void Stepper::isr() {
491 525
 
492 526
 #endif // ADVANCE
493 527
 
528
+#if ENABLED(LIN_ADVANCE)
529
+unsigned char old_OCR0A;
530
+// Timer interrupt for E. e_steps is set in the main routine;
531
+// Timer 0 is shared with millies
532
+ISR(TIMER0_COMPA_vect) { stepper.advance_isr(); }
533
+
534
+void Stepper::advance_isr() {
535
+  old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz) war 52
536
+  OCR0A = old_OCR0A;
537
+
538
+#define STEP_E_ONCE(INDEX) \
539
+  if (e_steps[INDEX] != 0) { \
540
+    E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); \
541
+    if (e_steps[INDEX] < 0) { \
542
+      E## INDEX ##_DIR_WRITE(INVERT_E## INDEX ##_DIR); \
543
+      e_steps[INDEX]++; \
544
+    } \
545
+    else if (e_steps[INDEX] > 0) { \
546
+      E## INDEX ##_DIR_WRITE(!INVERT_E## INDEX ##_DIR); \
547
+      e_steps[INDEX]--; \
548
+    } \
549
+    E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN); \
550
+  }
551
+
552
+  // Step all E steppers that have steps, up to 4 steps per interrupt
553
+  for (unsigned char i = 0; i < 4; i++) {
554
+    #if EXTRUDERS > 3
555
+      switch(current_block->active_extruder){case 3:STEP_E_ONCE(3);break;case 2:STEP_E_ONCE(2);break;case 1:STEP_E_ONCE(1);break;default:STEP_E_ONCE(0);}
556
+    #elif EXTRUDERS > 2
557
+      switch(current_block->active_extruder){case 2:STEP_E_ONCE(2);break;case 1:STEP_E_ONCE(1);break;default:STEP_E_ONCE(0);}
558
+    #elif EXTRUDERS > 1
559
+      #if DISABLED(DUAL_X_CARRIAGE)
560
+        if(current_block->active_extruder == 1){STEP_E_ONCE(1)}else{STEP_E_ONCE(0);}
561
+      #else
562
+        extern bool extruder_duplication_enabled;
563
+        if(extruder_duplication_enabled){
564
+          STEP_E_ONCE(0);
565
+          STEP_E_ONCE(1);
566
+        }else {
567
+          if(current_block->active_extruder == 1){STEP_E_ONCE(1)}else{STEP_E_ONCE(0);}
568
+        }
569
+      #endif
570
+    #else
571
+      STEP_E_ONCE(0);
572
+    #endif
573
+  }
574
+}
575
+#endif // LIN_ADVANCE
576
+
494 577
 void Stepper::init() {
495 578
 
496 579
   digipot_init(); //Initialize Digipot Motor Current
@@ -655,6 +738,18 @@ void Stepper::init() {
655 738
   OCR1A = 0x4000;
656 739
   TCNT1 = 0;
657 740
   ENABLE_STEPPER_DRIVER_INTERRUPT();
741
+  
742
+  #if ENABLED(LIN_ADVANCE)
743
+    for (int i = 0; i < EXTRUDERS; i++){
744
+      e_steps[i] = 0;
745
+      current_adv_steps[i] = 0;
746
+    }
747
+    #if defined(TCCR0A) && defined(WGM01)
748
+      CBI(TCCR0A, WGM01);
749
+      CBI(TCCR0A, WGM00);
750
+    #endif
751
+    SBI(TIMSK0, OCIE0A);
752
+  #endif //LIN_ADVANCE
658 753
 
659 754
   #if ENABLED(ADVANCE)
660 755
     #if defined(TCCR0A) && defined(WGM01)
@@ -1040,3 +1135,17 @@ void Stepper::microstep_readings() {
1040 1135
     SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
1041 1136
   #endif
1042 1137
 }
1138
+
1139
+#if ENABLED(LIN_ADVANCE)
1140
+  void Stepper::advance_M905() {
1141
+    if (code_seen('K')) extruder_advance_k = code_value();
1142
+    SERIAL_ECHO_START;
1143
+    SERIAL_ECHOPGM("Advance factor:");
1144
+    SERIAL_CHAR(' ');
1145
+    SERIAL_ECHOLN(extruder_advance_k);
1146
+  }
1147
+
1148
+  int Stepper::get_advance_k(){
1149
+    return extruder_advance_k;
1150
+  }
1151
+#endif

+ 26
- 1
Marlin/stepper.h View File

@@ -93,6 +93,10 @@ class Stepper {
93 93
     #if ENABLED(ADVANCE)
94 94
       static long e_steps[EXTRUDERS];
95 95
     #endif
96
+    
97
+    #if ENABLED(LIN_ADVANCE)
98
+      int extruder_advance_k = LIN_K;
99
+    #endif
96 100
 
97 101
   private:
98 102
 
@@ -111,6 +115,14 @@ class Stepper {
111 115
       static unsigned char old_OCR0A;
112 116
       static long advance_rate, advance, old_advance, final_advance;
113 117
     #endif
118
+    
119
+    #if ENABLED(LIN_ADVANCE)
120
+      unsigned char old_OCR0A;
121
+      volatile int e_steps[EXTRUDERS];
122
+      int final_estep_rate;
123
+      int current_estep_rate[EXTRUDERS]; //Actual extruder speed [steps/s]
124
+      int current_adv_steps[EXTRUDERS]; //The amount of current added esteps due to advance. Think of it as the current amount of pressure applied to the spring (=filament).
125
+    #endif
114 126
 
115 127
     static long acceleration_time, deceleration_time;
116 128
     //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
@@ -159,6 +171,12 @@ class Stepper {
159 171
     #if ENABLED(ADVANCE)
160 172
       static void advance_isr();
161 173
     #endif
174
+    
175
+    #if ENABLED(LIN_ADVANCE)
176
+      void advance_isr();
177
+      void advance_M905();
178
+      int get_advance_k();
179
+    #endif
162 180
 
163 181
     //
164 182
     // Block until all buffered steps are executed
@@ -315,6 +333,13 @@ class Stepper {
315 333
       acc_step_rate = current_block->initial_rate;
316 334
       acceleration_time = calc_timer(acc_step_rate);
317 335
       OCR1A = acceleration_time;
336
+      
337
+      #if ENABLED(LIN_ADVANCE)
338
+        if (current_block->use_advance_lead){
339
+          current_estep_rate[current_block->active_extruder] = ((unsigned long)acc_step_rate * current_block->e_speed_multiplier8) >> 8;
340
+          final_estep_rate = (current_block->nominal_rate * current_block->e_speed_multiplier8) >> 8;
341
+        }
342
+      #endif
318 343
 
319 344
       // SERIAL_ECHO_START;
320 345
       // SERIAL_ECHOPGM("advance :");
@@ -332,4 +357,4 @@ class Stepper {
332 357
 
333 358
 };
334 359
 
335
-#endif // STEPPER_H
360
+#endif // STEPPER_H

Loading…
Cancel
Save