Merge pull request #4980 from thinkyhead/rc_lin_update
LIN_ADVANCE bug fix and optimization
This commit is contained in:
		
						commit
						bbeaca5839
					
				| @ -4899,8 +4899,8 @@ inline void gcode_M42() { | |||||||
|       for (uint8_t j = 0; j <= n; j++) sum += sample_set[j]; |       for (uint8_t j = 0; j <= n; j++) sum += sample_set[j]; | ||||||
|       mean = sum / (n + 1); |       mean = sum / (n + 1); | ||||||
| 
 | 
 | ||||||
|       if(sample_set[n] < min) min = sample_set[n]; |       NOMORE(min, sample_set[n]); | ||||||
|       if(sample_set[n] > max) max = sample_set[n]; |       NOLESS(max, sample_set[n]); | ||||||
| 
 | 
 | ||||||
|       /**
 |       /**
 | ||||||
|        * Now, use that mean to calculate the standard deviation for the |        * Now, use that mean to calculate the standard deviation for the | ||||||
| @ -4956,7 +4956,6 @@ inline void gcode_M42() { | |||||||
|     SERIAL_PROTOCOLPGM("Standard Deviation: "); |     SERIAL_PROTOCOLPGM("Standard Deviation: "); | ||||||
|     SERIAL_PROTOCOL_F(sigma, 6); |     SERIAL_PROTOCOL_F(sigma, 6); | ||||||
|     SERIAL_EOL; |     SERIAL_EOL; | ||||||
| 
 |  | ||||||
|     SERIAL_EOL; |     SERIAL_EOL; | ||||||
| 
 | 
 | ||||||
|     clean_up_after_endstop_or_probe_move(); |     clean_up_after_endstop_or_probe_move(); | ||||||
|  | |||||||
| @ -95,7 +95,7 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even | |||||||
|   volatile unsigned char Stepper::eISR_Rate = 200; // Keep the ISR at a low rate until needed
 |   volatile unsigned char Stepper::eISR_Rate = 200; // Keep the ISR at a low rate until needed
 | ||||||
| 
 | 
 | ||||||
|   #if ENABLED(LIN_ADVANCE) |   #if ENABLED(LIN_ADVANCE) | ||||||
|     volatile long Stepper::e_steps[E_STEPPERS]; |     volatile int Stepper::e_steps[E_STEPPERS]; | ||||||
|     int Stepper::extruder_advance_k = LIN_ADVANCE_K, |     int Stepper::extruder_advance_k = LIN_ADVANCE_K, | ||||||
|         Stepper::final_estep_rate, |         Stepper::final_estep_rate, | ||||||
|         Stepper::current_estep_rate[E_STEPPERS], |         Stepper::current_estep_rate[E_STEPPERS], | ||||||
| @ -311,8 +311,20 @@ void Stepper::set_directions() { | |||||||
|   #endif // !ADVANCE && !LIN_ADVANCE
 |   #endif // !ADVANCE && !LIN_ADVANCE
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse.
 | /**
 | ||||||
| // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
 |  * Stepper Driver Interrupt | ||||||
|  |  * | ||||||
|  |  * Directly pulses the stepper motors at high frequency. | ||||||
|  |  * Timer 1 runs at a base frequency of 2MHz, with this ISR using OCR1A compare mode. | ||||||
|  |  * | ||||||
|  |  * OCR1A   Frequency | ||||||
|  |  *     1     2 MHz | ||||||
|  |  *    50    40 KHz | ||||||
|  |  *   100    20 KHz - capped max rate | ||||||
|  |  *   200    10 KHz - nominal max rate | ||||||
|  |  *  2000     1 KHz - sleep rate | ||||||
|  |  *  4000   500  Hz - init rate | ||||||
|  |  */ | ||||||
| ISR(TIMER1_COMPA_vect) { Stepper::isr(); } | ISR(TIMER1_COMPA_vect) { Stepper::isr(); } | ||||||
| 
 | 
 | ||||||
| void Stepper::isr() { | void Stepper::isr() { | ||||||
| @ -323,7 +335,7 @@ void Stepper::isr() { | |||||||
|       if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); |       if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); | ||||||
|     #endif |     #endif | ||||||
|     cleaning_buffer_counter--; |     cleaning_buffer_counter--; | ||||||
|     OCR1A = 200; |     OCR1A = 200; // Run at max speed - 10 KHz
 | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -348,7 +360,7 @@ void Stepper::isr() { | |||||||
|       #if ENABLED(Z_LATE_ENABLE) |       #if ENABLED(Z_LATE_ENABLE) | ||||||
|         if (current_block->steps[Z_AXIS] > 0) { |         if (current_block->steps[Z_AXIS] > 0) { | ||||||
|           enable_z(); |           enable_z(); | ||||||
|           OCR1A = 2000; //1ms wait
 |           OCR1A = 2000; // Run at slow speed - 1 KHz
 | ||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|       #endif |       #endif | ||||||
| @ -358,7 +370,7 @@ void Stepper::isr() { | |||||||
|       // #endif
 |       // #endif
 | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       OCR1A = 2000; // 1kHz.
 |       OCR1A = 2000; // Run at slow speed - 1 KHz
 | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -391,7 +403,7 @@ void Stepper::isr() { | |||||||
| 
 | 
 | ||||||
|       #if ENABLED(MIXING_EXTRUDER) |       #if ENABLED(MIXING_EXTRUDER) | ||||||
|         // Step mixing steppers proportionally
 |         // Step mixing steppers proportionally
 | ||||||
|         bool dir = motor_direction(E_AXIS); |         const bool dir = motor_direction(E_AXIS); | ||||||
|         MIXING_STEPPERS_LOOP(j) { |         MIXING_STEPPERS_LOOP(j) { | ||||||
|           counter_m[j] += current_block->steps[E_AXIS]; |           counter_m[j] += current_block->steps[E_AXIS]; | ||||||
|           if (counter_m[j] > 0) { |           if (counter_m[j] > 0) { | ||||||
| @ -401,22 +413,6 @@ void Stepper::isr() { | |||||||
|         } |         } | ||||||
|       #endif |       #endif | ||||||
| 
 | 
 | ||||||
|       if (current_block->use_advance_lead) { |  | ||||||
|         int delta_adv_steps = (((long)extruder_advance_k * current_estep_rate[TOOL_E_INDEX]) >> 9) - current_adv_steps[TOOL_E_INDEX]; |  | ||||||
|         #if ENABLED(MIXING_EXTRUDER) |  | ||||||
|           // Mixing extruders apply advance lead proportionally
 |  | ||||||
|           MIXING_STEPPERS_LOOP(j) { |  | ||||||
|             int steps = delta_adv_steps * current_block->step_event_count / current_block->mix_event_count[j]; |  | ||||||
|             e_steps[j] += steps; |  | ||||||
|             current_adv_steps[j] += steps; |  | ||||||
|           } |  | ||||||
|         #else |  | ||||||
|           // For most extruders, advance the single E stepper
 |  | ||||||
|           e_steps[TOOL_E_INDEX] += delta_adv_steps; |  | ||||||
|           current_adv_steps[TOOL_E_INDEX] += delta_adv_steps; |  | ||||||
|         #endif |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|     #elif ENABLED(ADVANCE) |     #elif ENABLED(ADVANCE) | ||||||
| 
 | 
 | ||||||
|       // Always count the unified E axis
 |       // Always count the unified E axis
 | ||||||
| @ -432,7 +428,7 @@ void Stepper::isr() { | |||||||
|       #if ENABLED(MIXING_EXTRUDER) |       #if ENABLED(MIXING_EXTRUDER) | ||||||
| 
 | 
 | ||||||
|         // Step mixing steppers proportionally
 |         // Step mixing steppers proportionally
 | ||||||
|         bool dir = motor_direction(E_AXIS); |         const bool dir = motor_direction(E_AXIS); | ||||||
|         MIXING_STEPPERS_LOOP(j) { |         MIXING_STEPPERS_LOOP(j) { | ||||||
|           counter_m[j] += current_block->steps[E_AXIS]; |           counter_m[j] += current_block->steps[E_AXIS]; | ||||||
|           if (counter_m[j] > 0) { |           if (counter_m[j] > 0) { | ||||||
| @ -536,6 +532,21 @@ void Stepper::isr() { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   #if ENABLED(LIN_ADVANCE) | ||||||
|  |     if (current_block->use_advance_lead) { | ||||||
|  |       int delta_adv_steps = (((long)extruder_advance_k * current_estep_rate[TOOL_E_INDEX]) >> 9) - current_adv_steps[TOOL_E_INDEX]; | ||||||
|  |       current_adv_steps[TOOL_E_INDEX] += delta_adv_steps; | ||||||
|  |       #if ENABLED(MIXING_EXTRUDER) | ||||||
|  |         // Mixing extruders apply advance lead proportionally
 | ||||||
|  |         MIXING_STEPPERS_LOOP(j) | ||||||
|  |           e_steps[j] += delta_adv_steps * current_block->step_event_count / current_block->mix_event_count[j]; | ||||||
|  |       #else | ||||||
|  |         // For most extruders, advance the single E stepper
 | ||||||
|  |         e_steps[TOOL_E_INDEX] += delta_adv_steps; | ||||||
|  |       #endif | ||||||
|  |    } | ||||||
|  |   #endif | ||||||
|  |    | ||||||
|   #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |   #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) | ||||||
|     // If we have esteps to execute, fire the next advance_isr "now"
 |     // If we have esteps to execute, fire the next advance_isr "now"
 | ||||||
|     if (e_steps[TOOL_E_INDEX]) OCR0A = TCNT0 + 2; |     if (e_steps[TOOL_E_INDEX]) OCR0A = TCNT0 + 2; | ||||||
| @ -593,7 +604,7 @@ void Stepper::isr() { | |||||||
|     #endif // ADVANCE or LIN_ADVANCE
 |     #endif // ADVANCE or LIN_ADVANCE
 | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |     #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) | ||||||
|       eISR_Rate = (timer >> 2) * step_loops / abs(e_steps[TOOL_E_INDEX]); |       eISR_Rate = (timer >> 3) * step_loops / abs(e_steps[TOOL_E_INDEX]); //>> 3 is divide by 8. Reason: Timer 0 runs at 16/8=2MHz, Timer 1 at 16/64=0.25MHz. ==> 2/0.25=8.
 | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
|   else if (step_events_completed > (uint32_t)current_block->decelerate_after) { |   else if (step_events_completed > (uint32_t)current_block->decelerate_after) { | ||||||
| @ -643,7 +654,7 @@ void Stepper::isr() { | |||||||
|     #endif // ADVANCE or LIN_ADVANCE
 |     #endif // ADVANCE or LIN_ADVANCE
 | ||||||
| 
 | 
 | ||||||
|     #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |     #if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) | ||||||
|       eISR_Rate = (timer >> 2) * step_loops / abs(e_steps[TOOL_E_INDEX]); |       eISR_Rate = (timer >> 3) * step_loops / abs(e_steps[TOOL_E_INDEX]); | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
|   else { |   else { | ||||||
| @ -653,7 +664,7 @@ void Stepper::isr() { | |||||||
|       if (current_block->use_advance_lead) |       if (current_block->use_advance_lead) | ||||||
|         current_estep_rate[TOOL_E_INDEX] = final_estep_rate; |         current_estep_rate[TOOL_E_INDEX] = final_estep_rate; | ||||||
| 
 | 
 | ||||||
|       eISR_Rate = (OCR1A_nominal >> 2) * step_loops_nominal / abs(e_steps[TOOL_E_INDEX]); |       eISR_Rate = (OCR1A_nominal >> 3) * step_loops_nominal / abs(e_steps[TOOL_E_INDEX]); | ||||||
| 
 | 
 | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
| @ -904,6 +915,7 @@ void Stepper::init() { | |||||||
|   // output mode = 00 (disconnected)
 |   // output mode = 00 (disconnected)
 | ||||||
|   TCCR1A &= ~(3 << COM1A0); |   TCCR1A &= ~(3 << COM1A0); | ||||||
|   TCCR1A &= ~(3 << COM1B0); |   TCCR1A &= ~(3 << COM1B0); | ||||||
|  | 
 | ||||||
|   // Set the timer pre-scaler
 |   // Set the timer pre-scaler
 | ||||||
|   // Generally we use a divider of 8, resulting in a 2MHz timer
 |   // Generally we use a divider of 8, resulting in a 2MHz timer
 | ||||||
|   // frequency on a 16MHz MCU. If you are going to change this, be
 |   // frequency on a 16MHz MCU. If you are going to change this, be
 | ||||||
| @ -911,6 +923,7 @@ void Stepper::init() { | |||||||
|   // create_speed_lookuptable.py
 |   // create_speed_lookuptable.py
 | ||||||
|   TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10); |   TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10); | ||||||
| 
 | 
 | ||||||
|  |   // Init Stepper ISR to 122 Hz for quick starting
 | ||||||
|   OCR1A = 0x4000; |   OCR1A = 0x4000; | ||||||
|   TCNT1 = 0; |   TCNT1 = 0; | ||||||
|   ENABLE_STEPPER_DRIVER_INTERRUPT(); |   ENABLE_STEPPER_DRIVER_INTERRUPT(); | ||||||
|  | |||||||
| @ -108,7 +108,7 @@ class Stepper { | |||||||
|       static unsigned char old_OCR0A; |       static unsigned char old_OCR0A; | ||||||
|       static volatile unsigned char eISR_Rate; |       static volatile unsigned char eISR_Rate; | ||||||
|       #if ENABLED(LIN_ADVANCE) |       #if ENABLED(LIN_ADVANCE) | ||||||
|         static volatile long e_steps[E_STEPPERS]; |         static volatile int e_steps[E_STEPPERS]; | ||||||
|         static int extruder_advance_k; |         static int extruder_advance_k; | ||||||
|         static int final_estep_rate; |         static int final_estep_rate; | ||||||
|         static int current_estep_rate[E_STEPPERS]; // Actual extruder speed [steps/s]
 |         static int current_estep_rate[E_STEPPERS]; // Actual extruder speed [steps/s]
 | ||||||
|  | |||||||
| @ -1371,7 +1371,7 @@ void Temperature::set_current_temp_raw() { | |||||||
|  * Timer 0 is shared with millies so don't change the prescaler. |  * Timer 0 is shared with millies so don't change the prescaler. | ||||||
|  * |  * | ||||||
|  * This ISR uses the compare method so it runs at the base |  * This ISR uses the compare method so it runs at the base | ||||||
|  * frequency (16 MHz / 256 = 62500 Hz), but at the TCNT0 set |  * frequency (16 MHz / 64 / 256 = 976.5625 Hz), but at the TCNT0 set | ||||||
|  * in OCR0B above (128 or halfway between OVFs). |  * in OCR0B above (128 or halfway between OVFs). | ||||||
|  * |  * | ||||||
|  *  - Manage PWM to all the heaters and fan |  *  - Manage PWM to all the heaters and fan | ||||||
| @ -1485,9 +1485,16 @@ void Temperature::isr() { | |||||||
|       #endif |       #endif | ||||||
|     #endif |     #endif | ||||||
| 
 | 
 | ||||||
|     // 488.28 Hz (or 1:976.56, 2:1953.12, 3:3906.25, 4:7812.5, 5:7812.5 6:15625, 6:15625 7:31250)
 |     // SOFT_PWM_SCALE to frequency:
 | ||||||
|  |     //
 | ||||||
|  |     // 0: 16000000/64/256/128 =   7.6294 Hz
 | ||||||
|  |     // 1:                / 64 =  15.2588 Hz
 | ||||||
|  |     // 2:                / 32 =  30.5176 Hz
 | ||||||
|  |     // 3:                / 16 =  61.0352 Hz
 | ||||||
|  |     // 4:                /  8 = 122.0703 Hz
 | ||||||
|  |     // 5:                /  4 = 244.1406 Hz
 | ||||||
|     pwm_count += _BV(SOFT_PWM_SCALE); |     pwm_count += _BV(SOFT_PWM_SCALE); | ||||||
|     pwm_count &= 0x7f; |     pwm_count &= 0x7F; | ||||||
| 
 | 
 | ||||||
|   #else // SLOW_PWM_HEATERS
 |   #else // SLOW_PWM_HEATERS
 | ||||||
| 
 | 
 | ||||||
| @ -1586,10 +1593,18 @@ void Temperature::isr() { | |||||||
|       #endif |       #endif | ||||||
|     #endif //FAN_SOFT_PWM
 |     #endif //FAN_SOFT_PWM
 | ||||||
| 
 | 
 | ||||||
|  |     // SOFT_PWM_SCALE to frequency:
 | ||||||
|  |     //
 | ||||||
|  |     // 0: 16000000/64/256/128 =   7.6294 Hz
 | ||||||
|  |     // 1:                / 64 =  15.2588 Hz
 | ||||||
|  |     // 2:                / 32 =  30.5176 Hz
 | ||||||
|  |     // 3:                / 16 =  61.0352 Hz
 | ||||||
|  |     // 4:                /  8 = 122.0703 Hz
 | ||||||
|  |     // 5:                /  4 = 244.1406 Hz
 | ||||||
|     pwm_count += _BV(SOFT_PWM_SCALE); |     pwm_count += _BV(SOFT_PWM_SCALE); | ||||||
|     pwm_count &= 0x7f; |     pwm_count &= 0x7F; | ||||||
| 
 | 
 | ||||||
|     // increment slow_pwm_count only every 64 pwm_count circa 65.5ms
 |     // increment slow_pwm_count only every 64 pwm_count (e.g., every 8s)
 | ||||||
|     if ((pwm_count % 64) == 0) { |     if ((pwm_count % 64) == 0) { | ||||||
|       slow_pwm_count++; |       slow_pwm_count++; | ||||||
|       slow_pwm_count &= 0x7f; |       slow_pwm_count &= 0x7f; | ||||||
|  | |||||||
| @ -223,7 +223,7 @@ uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to | |||||||
|     static int8_t _countedItems = 0; \ |     static int8_t _countedItems = 0; \ | ||||||
|     int8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \ |     int8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \ | ||||||
|     if (_countedItems > 0 && encoderLine >= _countedItems - LIMIT) { \ |     if (_countedItems > 0 && encoderLine >= _countedItems - LIMIT) { \ | ||||||
|       encoderLine = _countedItems - LIMIT; \ |       encoderLine = max(0, _countedItems - LIMIT); \ | ||||||
|       encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); \ |       encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); \ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user