Browse Source

Add LIN_ADVANCE

Sebastianv650 9 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
   #define MESH_MAX_Y (Y_MAX_POS - (MESH_INSET))
457
   #define MESH_MAX_Y (Y_MAX_POS - (MESH_INSET))
458
 #endif
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
 // @section extras
469
 // @section extras
461
 
470
 
462
 // Arc interpretation settings:
471
 // Arc interpretation settings:

+ 16
- 0
Marlin/Marlin_main.cpp View File

6468
 
6468
 
6469
 #endif // DUAL_X_CARRIAGE
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
  * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
6482
  * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S
6473
  */
6483
  */
7339
           gcode_M605();
7349
           gcode_M605();
7340
           break;
7350
           break;
7341
       #endif // DUAL_X_CARRIAGE
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
       case 907: // M907 Set digital trimpot motor current using axis codes.
7359
       case 907: // M907 Set digital trimpot motor current using axis codes.
7344
         gcode_M907();
7360
         gcode_M907();

+ 12
- 0
Marlin/planner.cpp View File

1045
   // the maximum junction speed and may always be ignored for any speed reduction checks.
1045
   // the maximum junction speed and may always be ignored for any speed reduction checks.
1046
   block->nominal_length_flag = (block->nominal_speed <= v_allowable);
1046
   block->nominal_length_flag = (block->nominal_speed <= v_allowable);
1047
   block->recalculate_flag = true; // Always calculate trapezoid for new block
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
   // Update previous path unit_vector and nominal speed
1061
   // Update previous path unit_vector and nominal speed
1050
   for (int i = 0; i < NUM_AXIS; i++) previous_speed[i] = current_speed[i];
1062
   for (int i = 0; i < NUM_AXIS; i++) previous_speed[i] = current_speed[i];

+ 4
- 0
Marlin/planner.h View File

70
     volatile long final_advance;
70
     volatile long final_advance;
71
     float advance;
71
     float advance;
72
   #endif
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
   // Fields used by the motion planner to manage acceleration
78
   // Fields used by the motion planner to manage acceleration
75
   float nominal_speed,                               // The nominal speed for this block in mm/sec
79
   float nominal_speed,                               // The nominal speed for this block in mm/sec

+ 111
- 2
Marlin/stepper.cpp View File

351
           e_steps[current_block->active_extruder] += motor_direction(E_AXIS) ? -1 : 1;
351
           e_steps[current_block->active_extruder] += motor_direction(E_AXIS) ? -1 : 1;
352
         }
352
         }
353
       #endif //ADVANCE
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
       #define _COUNTER(AXIS) counter_## AXIS
371
       #define _COUNTER(AXIS) counter_## AXIS
356
       #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
372
       #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
363
       STEP_ADD(X);
379
       STEP_ADD(X);
364
       STEP_ADD(Y);
380
       STEP_ADD(Y);
365
       STEP_ADD(Z);
381
       STEP_ADD(Z);
366
-      #if DISABLED(ADVANCE)
382
+      #if (DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE))
367
         STEP_ADD(E);
383
         STEP_ADD(E);
368
       #endif
384
       #endif
369
 
385
 
377
       STEP_IF_COUNTER(X);
393
       STEP_IF_COUNTER(X);
378
       STEP_IF_COUNTER(Y);
394
       STEP_IF_COUNTER(Y);
379
       STEP_IF_COUNTER(Z);
395
       STEP_IF_COUNTER(Z);
380
-      #if DISABLED(ADVANCE)
396
+      #if (DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE))
381
         STEP_IF_COUNTER(E);
397
         STEP_IF_COUNTER(E);
382
       #endif
398
       #endif
383
 
399
 
398
       timer = calc_timer(acc_step_rate);
414
       timer = calc_timer(acc_step_rate);
399
       OCR1A = timer;
415
       OCR1A = timer;
400
       acceleration_time += timer;
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
       #if ENABLED(ADVANCE)
424
       #if ENABLED(ADVANCE)
403
 
425
 
424
       timer = calc_timer(step_rate);
446
       timer = calc_timer(step_rate);
425
       OCR1A = timer;
447
       OCR1A = timer;
426
       deceleration_time += timer;
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
       #if ENABLED(ADVANCE)
456
       #if ENABLED(ADVANCE)
429
         advance -= advance_rate * step_loops;
457
         advance -= advance_rate * step_loops;
436
       #endif //ADVANCE
464
       #endif //ADVANCE
437
     }
465
     }
438
     else {
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
       OCR1A = OCR1A_nominal;
473
       OCR1A = OCR1A_nominal;
440
       // ensure we're running at the correct step rate, even if we just came off an acceleration
474
       // ensure we're running at the correct step rate, even if we just came off an acceleration
441
       step_loops = step_loops_nominal;
475
       step_loops = step_loops_nominal;
491
 
525
 
492
 #endif // ADVANCE
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
 void Stepper::init() {
577
 void Stepper::init() {
495
 
578
 
496
   digipot_init(); //Initialize Digipot Motor Current
579
   digipot_init(); //Initialize Digipot Motor Current
655
   OCR1A = 0x4000;
738
   OCR1A = 0x4000;
656
   TCNT1 = 0;
739
   TCNT1 = 0;
657
   ENABLE_STEPPER_DRIVER_INTERRUPT();
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
   #if ENABLED(ADVANCE)
754
   #if ENABLED(ADVANCE)
660
     #if defined(TCCR0A) && defined(WGM01)
755
     #if defined(TCCR0A) && defined(WGM01)
1040
     SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
1135
     SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
1041
   #endif
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
     #if ENABLED(ADVANCE)
93
     #if ENABLED(ADVANCE)
94
       static long e_steps[EXTRUDERS];
94
       static long e_steps[EXTRUDERS];
95
     #endif
95
     #endif
96
+    
97
+    #if ENABLED(LIN_ADVANCE)
98
+      int extruder_advance_k = LIN_K;
99
+    #endif
96
 
100
 
97
   private:
101
   private:
98
 
102
 
111
       static unsigned char old_OCR0A;
115
       static unsigned char old_OCR0A;
112
       static long advance_rate, advance, old_advance, final_advance;
116
       static long advance_rate, advance, old_advance, final_advance;
113
     #endif
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
     static long acceleration_time, deceleration_time;
127
     static long acceleration_time, deceleration_time;
116
     //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
128
     //unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
159
     #if ENABLED(ADVANCE)
171
     #if ENABLED(ADVANCE)
160
       static void advance_isr();
172
       static void advance_isr();
161
     #endif
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
     // Block until all buffered steps are executed
182
     // Block until all buffered steps are executed
315
       acc_step_rate = current_block->initial_rate;
333
       acc_step_rate = current_block->initial_rate;
316
       acceleration_time = calc_timer(acc_step_rate);
334
       acceleration_time = calc_timer(acc_step_rate);
317
       OCR1A = acceleration_time;
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
       // SERIAL_ECHO_START;
344
       // SERIAL_ECHO_START;
320
       // SERIAL_ECHOPGM("advance :");
345
       // SERIAL_ECHOPGM("advance :");
332
 
357
 
333
 };
358
 };
334
 
359
 
335
-#endif // STEPPER_H
360
+#endif // STEPPER_H

Loading…
Cancel
Save