diff options
| author | Emanuele Caruso <emanuele.caruso@gmail.com> | 2011-05-04 21:49:09 +0200 | 
|---|---|---|
| committer | Emanuele Caruso <emanuele.caruso@gmail.com> | 2011-05-04 21:49:09 +0200 | 
| commit | d15d4b96ce5fd7414f6305361bcb4608393e3745 (patch) | |
| tree | d2b3c5ceb7c290457e92f81e6bf73d11c535f966 | |
| parent | 93529ad632ca9f4949004f7a350b3bbc48f9deac (diff) | |
Added constant acceleration option (aka speed ramp), enabled by default
| -rw-r--r-- | Tonokip_Firmware/Tonokip_Firmware.pde | 92 | ||||
| -rw-r--r-- | Tonokip_Firmware/configuration.h | 11 | 
2 files changed, 96 insertions, 7 deletions
| diff --git a/Tonokip_Firmware/Tonokip_Firmware.pde b/Tonokip_Firmware/Tonokip_Firmware.pde index f7874aa..62b2d34 100644 --- a/Tonokip_Firmware/Tonokip_Firmware.pde +++ b/Tonokip_Firmware/Tonokip_Firmware.pde @@ -90,6 +90,16 @@ void kill(byte debug);  bool direction_x, direction_y, direction_z, direction_e;  unsigned long previous_micros=0, previous_micros_x=0, previous_micros_y=0, previous_micros_z=0, previous_micros_e=0, previous_millis_heater, previous_millis_bed_heater;  unsigned long x_steps_to_take, y_steps_to_take, z_steps_to_take, e_steps_to_take; +#ifdef RAMP_ACCELERATION +unsigned long max_x_interval = 100000000.0 / (min_units_per_second * x_steps_per_unit); +unsigned long max_y_interval = 100000000.0 / (min_units_per_second * y_steps_per_unit); +unsigned long max_interval; +unsigned long x_steps_per_sqr_second = max_acceleration_units_per_sq_second * x_steps_per_unit; +unsigned long y_steps_per_sqr_second = max_acceleration_units_per_sq_second * y_steps_per_unit; +unsigned long x_travel_steps_per_sqr_second = max_travel_acceleration_units_per_sq_second * x_steps_per_unit; +unsigned long y_travel_steps_per_sqr_second = max_travel_acceleration_units_per_sq_second * y_steps_per_unit; +unsigned long steps_per_sqr_second, plateau_steps; +#endif  #ifdef EXP_ACCELERATION  unsigned long long_full_velocity_units = full_velocity_units * 100;  unsigned long long_travel_move_full_velocity_units = travel_move_full_velocity_units * 100; @@ -908,7 +918,6 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin    previous_millis_heater = millis();    //Define variables that are needed for the Bresenham algorithm. Please note that  Z is not currently included in the Bresenham algorithm. -  unsigned long start_move_micros = micros();     unsigned int delta_x = x_steps_remaining;    unsigned long x_interval_nanos;    unsigned int delta_y = y_steps_remaining; @@ -921,6 +930,10 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin    int error_x;    int error_y;    int error_z; +  #ifdef RAMP_ACCELERATION +  long max_speed_steps_per_second; +  long min_speed_steps_per_second; +  #endif    #ifdef EXP_ACCELERATION    unsigned long virtual_full_velocity_steps;    unsigned long full_velocity_steps; @@ -931,8 +944,16 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin    //Do some Bresenham calculations depending on which axis will lead it.    if(steep_y) {     error_x = delta_y / 2; -   previous_micros_y=micros()*100;     interval = y_interval; +   #ifdef RAMP_ACCELERATION +   max_interval = max_y_interval; +   if(e_steps_to_take > 0) steps_per_sqr_second = y_steps_per_sqr_second; +   else steps_per_sqr_second = y_travel_steps_per_sqr_second; +   max_speed_steps_per_second = 100000000 / interval; +   min_speed_steps_per_second = 100000000 / max_interval; +   float plateau_time = (max_speed_steps_per_second - min_speed_steps_per_second) / (float) steps_per_sqr_second; +   plateau_steps = (long) ((steps_per_sqr_second / 2.0 * plateau_time + min_speed_steps_per_second) * plateau_time); +   #endif     #ifdef EXP_ACCELERATION     if(e_steps_to_take > 0) virtual_full_velocity_steps = long_full_velocity_units * y_steps_per_unit /100;     else virtual_full_velocity_steps = long_travel_move_full_velocity_units * y_steps_per_unit /100; @@ -944,8 +965,16 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin     steps_to_take = delta_y;    } else if (steep_x) {     error_y = delta_x / 2; -   previous_micros_x=micros()*100;     interval = x_interval; +   #ifdef RAMP_ACCELERATION +   max_interval = max_x_interval; +   if(e_steps_to_take > 0) steps_per_sqr_second = x_steps_per_sqr_second; +   else steps_per_sqr_second = x_travel_steps_per_sqr_second; +   max_speed_steps_per_second = 100000000 / interval; +   min_speed_steps_per_second = 100000000 / max_interval; +   float plateau_time = (max_speed_steps_per_second - min_speed_steps_per_second) / (float) steps_per_sqr_second; +   plateau_steps = (long) ((steps_per_sqr_second / 2.0 * plateau_time + min_speed_steps_per_second) * plateau_time); +   #endif     #ifdef EXP_ACCELERATION     if(e_steps_to_take > 0) virtual_full_velocity_steps = long_full_velocity_units * x_steps_per_unit /100;     else virtual_full_velocity_steps = long_travel_move_full_velocity_units * x_steps_per_unit /100; @@ -956,9 +985,14 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin     steps_remaining = delta_x;     steps_to_take = delta_x;    } -  previous_micros_z=micros()*100; -  previous_micros_e=micros()*100;    unsigned long steps_done = 0; +  #ifdef RAMP_ACCELERATION +  plateau_steps *= 1.01; // This is to compensate we use discrete intervals +  acceleration_enabled = true; +  long full_interval = interval; +  if(interval > max_interval) acceleration_enabled = false; +  boolean decelerating = false; +  #endif    #ifdef EXP_ACCELERATION    acceleration_enabled = true;    if(full_velocity_steps == 0) full_velocity_steps++; @@ -974,9 +1008,48 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin    accelerating = acceleration_enabled;    #endif +  unsigned long start_move_micros = micros(); +  previous_micros_x=start_move_micros*100; +  previous_micros_y=previous_micros_x; +  previous_micros_z=previous_micros_x; +  previous_micros_e=previous_micros_x;    //move until no more steps remain     while(x_steps_remaining + y_steps_remaining + z_steps_remaining + e_steps_remaining > 0) { +    #ifdef RAMP_ACCELERATION +    //If acceleration is enabled on this move and we are in the acceleration segment, calculate the current interval +    if (acceleration_enabled && steps_done == 0) { +        interval = max_interval; +    } else if (acceleration_enabled && steps_done <= plateau_steps) { +        long current_speed = (long) ((((long) steps_per_sqr_second) / 10000) +	    * ((micros() - start_move_micros)  / 100) + (long) min_speed_steps_per_second); +	    interval = 100000000 / current_speed; +      if (interval < full_interval) { +        accelerating = false; +      	interval = full_interval; +      } +      if (steps_done >= steps_to_take / 2) { +	plateau_steps = steps_done; +	max_speed_steps_per_second = 100000000 / interval; +	accelerating = false; +      } +    } else if (acceleration_enabled && steps_remaining <= plateau_steps) { //(interval > minInterval * 100) { +      if (!accelerating) { +        start_move_micros = micros(); +        accelerating = true; +        decelerating = true; +      }				 +      long current_speed = (long) ((long) max_speed_steps_per_second - ((((long) steps_per_sqr_second) / 10000) +          * (((micros() - start_move_micros) + interval) / 10000))); +      interval = 100000000 / current_speed; +      if (interval > max_interval) +	interval = max_interval; +    } else { +      //Else, we are just use the full speed interval as current interval +      interval = full_interval; +      accelerating = false; +    } +    #endif      #ifdef EXP_ACCELERATION      //If acceleration is enabled on this move and we are in the acceleration segment, calculate the current interval      if (acceleration_enabled && steps_done < full_velocity_steps && steps_done / full_velocity_steps < 1 && (steps_done % steps_acceleration_check == 0)) { @@ -1018,6 +1091,9 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin              do_x_step(); x_steps_remaining--;              error_x = error_x + delta_y;            } +          #ifdef RAMP_ACCELERATION +          if (steps_remaining == plateau_steps || (steps_done >= steps_to_take / 2 && accelerating && !decelerating)) break; +          #endif            #ifdef STEP_DELAY_RATIO            if(timediff >= interval) delayMicroseconds(long_step_delay_ratio * interval / 10000);            #endif @@ -1037,6 +1113,9 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin              do_y_step(); y_steps_remaining--;              error_y = error_y + delta_x;            } +          #ifdef RAMP_ACCELERATION +          if (steps_remaining == plateau_steps || (steps_done >= steps_to_take / 2 && accelerating && !decelerating)) break; +          #endif            #ifdef STEP_DELAY_RATIO            if(timediff >= interval) delayMicroseconds(long_step_delay_ratio * interval / 10000);            #endif @@ -1046,6 +1125,9 @@ void linear_move(unsigned long x_steps_remaining, unsigned long y_steps_remainin          }        }      } +    #ifdef RAMP_ACCELERATION +    if (steps_to_take>0 && (steps_remaining == plateau_steps || (steps_done >= steps_to_take / 2 && accelerating && !decelerating))) continue; +    #endif      //If there are z steps remaining, check if z steps must be taken      if(z_steps_remaining) { diff --git a/Tonokip_Firmware/configuration.h b/Tonokip_Firmware/configuration.h index 1d3a1c8..2733a72 100644 --- a/Tonokip_Firmware/configuration.h +++ b/Tonokip_Firmware/configuration.h @@ -16,11 +16,18 @@  //If you enable this, make sure STEP_DELAY_MICROS is disabled.  //#define STEP_DELAY_RATIO 0.25 +//Comment this to disable ramp acceleration +#define RAMP_ACCELERATION 1 -//Comment this to disable exponential acceleration -#define EXP_ACCELERATION 1 +//Uncomment this to enable exponential acceleration +//#define EXP_ACCELERATION 1  //Acceleration settings +#ifdef RAMP_ACCELERATION +float min_units_per_second = 35.0; // the minimum feedrate +long max_acceleration_units_per_sq_second = 750; +long max_travel_acceleration_units_per_sq_second = 1500; +#endif  #ifdef EXP_ACCELERATION  float full_velocity_units = 10; // the units between minimum and G1 move feedrate  float travel_move_full_velocity_units = 10; // used for travel moves | 
