Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing. Using it, one can e.g. tune the z-position in realtime, while printing the first layer. Also, lost steps can be manually added/removed, but thats not the prime feature. Stuff is placed into the Tune->Babystep * It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then. Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name. say goodby to fuddling around with the z-axis.
This commit is contained in:
		| @@ -270,6 +270,17 @@ | ||||
| // Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled. | ||||
| //#define ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED | ||||
|  | ||||
| // Babystepping enables the user to control the axis in tiny amounts, independently from the normal printing process | ||||
| // it can e.g. be used to change z-positions in the print startup phase in realtime | ||||
| // does not respect endstops! | ||||
|  | ||||
| //#define BABYSTEPPING | ||||
| //#define BABYSTEP_XY  //not only z, but also XY | ||||
|  | ||||
| #ifdef COREXY | ||||
|     #error BABYSTEPPING not implemented for COREXY yet. | ||||
| #endif | ||||
|  | ||||
| // extruder advance constant (s2/mm3) | ||||
| // | ||||
| // advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 | ||||
|   | ||||
| @@ -997,6 +997,116 @@ void quickStop() | ||||
|   ENABLE_STEPPER_DRIVER_INTERRUPT(); | ||||
| } | ||||
|  | ||||
| #ifdef BABYSTEPPING | ||||
|  | ||||
|  | ||||
| void babystep(const uint8_t axis,const bool direction) | ||||
| { | ||||
|   //MUST ONLY BE CALLED BY A ISR, it depends on that no other ISR interrupts this | ||||
|     //store initial pin states | ||||
|   switch(axis) | ||||
|   { | ||||
|   case X_AXIS: | ||||
|   { | ||||
|     enable_x();    | ||||
|     uint8_t old_x_dir_pin= READ(X_DIR_PIN);  //if dualzstepper, both point to same direction. | ||||
|     | ||||
|     //setup new step | ||||
|     WRITE(X_DIR_PIN,(INVERT_X_DIR)^direction); | ||||
|     #ifdef DUAL_X_CARRIAGE | ||||
|       WRITE(X2_DIR_PIN,(INVERT_X_DIR)^direction); | ||||
|     #endif | ||||
|      | ||||
|     //perform step  | ||||
|     WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);  | ||||
|     #ifdef DUAL_X_CARRIAGE | ||||
|       WRITE(X2_STEP_PIN, !INVERT_X_STEP_PIN); | ||||
|     #endif | ||||
|     { | ||||
|     float x=1./float(axis+1)/float(axis+2); //wait a tiny bit | ||||
|     } | ||||
|     WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); | ||||
|     #ifdef DUAL_X_CARRIAGE | ||||
|       WRITE(X2_STEP_PIN, INVERT_X_STEP_PIN); | ||||
|     #endif | ||||
|  | ||||
|     //get old pin state back. | ||||
|     WRITE(X_DIR_PIN,old_x_dir_pin); | ||||
|     #ifdef DUAL_X_CARRIAGE | ||||
|       WRITE(X2_DIR_PIN,old_x_dir_pin); | ||||
|     #endif | ||||
|  | ||||
|   } | ||||
|   break; | ||||
|   case Y_AXIS: | ||||
|   { | ||||
|     enable_y();    | ||||
|     uint8_t old_y_dir_pin= READ(Y_DIR_PIN);  //if dualzstepper, both point to same direction. | ||||
|     | ||||
|     //setup new step | ||||
|     WRITE(Y_DIR_PIN,(INVERT_Y_DIR)^direction); | ||||
|     #ifdef DUAL_Y_CARRIAGE | ||||
|       WRITE(Y2_DIR_PIN,(INVERT_Y_DIR)^direction); | ||||
|     #endif | ||||
|      | ||||
|     //perform step  | ||||
|     WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);  | ||||
|     #ifdef DUAL_Y_CARRIAGE | ||||
|       WRITE(Y2_STEP_PIN, !INVERT_Y_STEP_PIN); | ||||
|     #endif | ||||
|     { | ||||
|     float x=1./float(axis+1)/float(axis+2); //wait a tiny bit | ||||
|     } | ||||
|     WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); | ||||
|     #ifdef DUAL_Y_CARRIAGE | ||||
|       WRITE(Y2_STEP_PIN, INVERT_Y_STEP_PIN); | ||||
|     #endif | ||||
|  | ||||
|     //get old pin state back. | ||||
|     WRITE(Y_DIR_PIN,old_y_dir_pin); | ||||
|     #ifdef DUAL_Y_CARRIAGE | ||||
|       WRITE(Y2_DIR_PIN,old_y_dir_pin); | ||||
|     #endif | ||||
|  | ||||
|   } | ||||
|   break;  | ||||
|   case Z_AXIS: | ||||
|   { | ||||
|     enable_z(); | ||||
|     uint8_t old_z_dir_pin= READ(Z_DIR_PIN);  //if dualzstepper, both point to same direction. | ||||
|     //setup new step | ||||
|     WRITE(Z_DIR_PIN,(INVERT_Z_DIR)^direction); | ||||
|     #ifdef Z_DUAL_STEPPER_DRIVERS | ||||
|       WRITE(Z2_DIR_PIN,(INVERT_Z_DIR)^direction); | ||||
|     #endif | ||||
|     //perform step  | ||||
|     WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);  | ||||
|     #ifdef Z_DUAL_STEPPER_DRIVERS | ||||
|       WRITE(Z2_STEP_PIN, !INVERT_Z_STEP_PIN); | ||||
|     #endif | ||||
|     //wait a tiny bit | ||||
|     { | ||||
|     float x=1./float(axis+1); //absolutely useless | ||||
|     } | ||||
|     WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); | ||||
|     #ifdef Z_DUAL_STEPPER_DRIVERS | ||||
|       WRITE(Z2_STEP_PIN, INVERT_Z_STEP_PIN); | ||||
|     #endif | ||||
|  | ||||
|     //get old pin state back. | ||||
|     WRITE(Z_DIR_PIN,old_z_dir_pin); | ||||
|     #ifdef Z_DUAL_STEPPER_DRIVERS | ||||
|       WRITE(Z2_DIR_PIN,old_z_dir_pin); | ||||
|     #endif | ||||
|  | ||||
|   } | ||||
|   break; | ||||
|   | ||||
|   default:    break; | ||||
|   } | ||||
| } | ||||
| #endif //BABYSTEPPING | ||||
|  | ||||
| void digitalPotWrite(int address, int value) // From Arduino DigitalPotControl example | ||||
| { | ||||
|   #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 | ||||
|   | ||||
| @@ -92,4 +92,10 @@ void digipot_current(uint8_t driver, int current); | ||||
| void microstep_init(); | ||||
| void microstep_readings(); | ||||
|  | ||||
| #ifdef BABYSTEPPING | ||||
|   void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention | ||||
| #endif | ||||
|       | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -66,6 +66,10 @@ float current_temperature_bed = 0.0; | ||||
|   unsigned char fanSpeedSoftPwm; | ||||
| #endif | ||||
|    | ||||
| #ifdef BABYSTEPPING | ||||
|   volatile int babystepsTodo[3]={0,0,0}; | ||||
| #endif | ||||
|    | ||||
| //=========================================================================== | ||||
| //=============================private variables============================ | ||||
| //=========================================================================== | ||||
| @@ -1253,6 +1257,25 @@ ISR(TIMER0_COMPB_vect) | ||||
|     } | ||||
| #endif | ||||
|   } | ||||
|    | ||||
| #ifdef BABYSTEPPING | ||||
|   for(uint8_t axis=0;axis<3;axis++) | ||||
|   { | ||||
|     int curTodo=babystepsTodo[axis]; //get rid of volatile for performance | ||||
|     | ||||
|     if(curTodo>0) | ||||
|     { | ||||
|       babystep(axis,/*fwd*/true); | ||||
|       babystepsTodo[axis]--; //less to do next time | ||||
|     } | ||||
|     else | ||||
|     if(curTodo<0) | ||||
|     { | ||||
|       babystep(axis,/*fwd*/false); | ||||
|       babystepsTodo[axis]++; //less to do next time | ||||
|     } | ||||
|   } | ||||
| #endif //BABYSTEPPING | ||||
| } | ||||
|  | ||||
| #ifdef PIDTEMP | ||||
|   | ||||
| @@ -53,6 +53,11 @@ extern float current_temperature_bed; | ||||
|   extern float bedKp,bedKi,bedKd; | ||||
| #endif | ||||
|    | ||||
|    | ||||
| #ifdef BABYSTEPPING | ||||
|   extern volatile int babystepsTodo[3]; | ||||
| #endif | ||||
|    | ||||
| //high level conversion routines, for use outside of temperature.cpp | ||||
| //inline so that there is no performance decrease. | ||||
| //deg=degreeCelsius | ||||
|   | ||||
| @@ -322,6 +322,68 @@ static void lcd_cooldown() | ||||
|     lcd_return_to_status(); | ||||
| } | ||||
|  | ||||
| #ifdef BABYSTEPPING | ||||
| static void lcd_babystep_x() | ||||
| { | ||||
|     if (encoderPosition != 0) | ||||
|     { | ||||
|         babystepsTodo[X_AXIS]+=(int)encoderPosition; | ||||
|         encoderPosition=0; | ||||
|         lcdDrawUpdate = 1; | ||||
|     } | ||||
|     if (lcdDrawUpdate) | ||||
|     { | ||||
|         lcd_implementation_drawedit(PSTR("Babystepping X"),""); | ||||
|     } | ||||
|     if (LCD_CLICKED) | ||||
|     { | ||||
|         lcd_quick_feedback(); | ||||
|         currentMenu = lcd_tune_menu; | ||||
|         encoderPosition = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void lcd_babystep_y() | ||||
| { | ||||
|     if (encoderPosition != 0) | ||||
|     { | ||||
|         babystepsTodo[Y_AXIS]+=(int)encoderPosition; | ||||
|         encoderPosition=0; | ||||
|         lcdDrawUpdate = 1; | ||||
|     } | ||||
|     if (lcdDrawUpdate) | ||||
|     { | ||||
|         lcd_implementation_drawedit(PSTR("Babystepping Y"),""); | ||||
|     } | ||||
|     if (LCD_CLICKED) | ||||
|     { | ||||
|         lcd_quick_feedback(); | ||||
|         currentMenu = lcd_tune_menu; | ||||
|         encoderPosition = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void lcd_babystep_z() | ||||
| { | ||||
|     if (encoderPosition != 0) | ||||
|     { | ||||
|         babystepsTodo[Z_AXIS]+=(int)encoderPosition; | ||||
|         encoderPosition=0; | ||||
|         lcdDrawUpdate = 1; | ||||
|     } | ||||
|     if (lcdDrawUpdate) | ||||
|     { | ||||
|         lcd_implementation_drawedit(PSTR("Babystepping Z"),""); | ||||
|     } | ||||
|     if (LCD_CLICKED) | ||||
|     { | ||||
|         lcd_quick_feedback(); | ||||
|         currentMenu = lcd_tune_menu; | ||||
|         encoderPosition = 0; | ||||
|     } | ||||
| } | ||||
| #endif //BABYSTEPPING | ||||
|  | ||||
| static void lcd_tune_menu() | ||||
| { | ||||
|     START_MENU(); | ||||
| @@ -339,6 +401,14 @@ static void lcd_tune_menu() | ||||
| #endif | ||||
|     MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); | ||||
|     MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999); | ||||
|      | ||||
| #ifdef BABYSTEPPING | ||||
|     #ifdef BABYSTEP_XY | ||||
|       MENU_ITEM(submenu, "Babystep X", lcd_babystep_x); | ||||
|       MENU_ITEM(submenu, "Babystep Y", lcd_babystep_y); | ||||
|     #endif //BABYSTEP_XY | ||||
|     MENU_ITEM(submenu, "Babystep Z", lcd_babystep_z); | ||||
| #endif | ||||
| #ifdef FILAMENTCHANGEENABLE | ||||
|      MENU_ITEM(gcode, MSG_FILAMENTCHANGE, PSTR("M600")); | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user