          return steps; } } }
 
 void do_calibration(void) {  // calibrate the center, bottom, and top positions of all shafts in use
-   int shaft;
-   for (shaft = 0; shaft < NUM_SHAFTS; ++shaft) {  // initialize all shafts as centered and nominal
-      shaft_status[shaft].shaft_position = SHAFT_CENTER;
-      shaft_status[shaft].steps_to_down = shaft_status[shaft].steps_to_up = NOMINAL_STEPS;
-      shaft_status[shaft].steps_to_move = 0; }
+   int shaft, steps;
    for (shaft = 0; shaft < NUM_SHAFTS; ++shaft) {  // now ask to recalibrate
       if (using_shaft(shaft)) {                    //  the shaft is in use for this pattern
-         if (get_calibration(shaft, "center", true) != 999) { // calibrating this shaft
-            shaft_status[shaft].steps_to_down = -get_calibration(shaft, "down", false);
+         steps = get_calibration(shaft, "center", 0, true);
+         shaft_status[shaft].shaft_position = SHAFT_CENTER;
+         if (steps == CALIB_ABORT) goto abort;
+         if (steps != CALIB_SKIP) { // calibrating this shaft
+            steps = get_calibration(shaft, "down", -shaft_status[shaft].steps_to_down, false);
+            if (steps == CALIB_ABORT) goto abort;
+            shaft_status[shaft].steps_to_down = -steps;
             shaft_status[shaft].steps_to_move = shaft_status[shaft].steps_to_down; // return it to the center
             do_steps();  // (it will be the only motor to move)
-            shaft_status[shaft].steps_to_up = get_calibration(shaft, "up", false);
+            steps = get_calibration(shaft, "up", shaft_status[shaft].steps_to_up, false);
+            if (steps == CALIB_ABORT) goto abort;
+            shaft_status[shaft].steps_to_up = steps;
             shaft_status[shaft].steps_to_move = -shaft_status[shaft].steps_to_up; // return it to the center
             do_steps(); // (it will be the only motor to move)
-         } } }
+         } }
+      else { // not using this shaft: assume centered, and leave the previous calibration
+         shaft_status[shaft].shaft_position = SHAFT_CENTER;
+         shaft_status[shaft].steps_to_move = 0; } }
    write_config(); // write the shaft calibration data
-   info_message("calibration saved", 0); }
+   info_message("calibration saved", 0);
+   return;
+abort:
+   read_config(); // reread the existing config
+   info_message("calibration aborted", 0); }
 
 void center_all_shafts(void) {
    for (int shaft = 0; shaft < NUM_SHAFTS; ++shaft) {

            Serial.print(" moves "); Serial.println(shaft_status[shaft].steps_to_move); } } }
   do_steps();
   for (int shaft = 0; shaft < NUM_SHAFTS; ++shaft) // record the ending position of the shafts
      shaft_status[shaft].shaft_position = tieup[shaft] [treadle] ? SHAFT_DOWN : SHAFT_UP; }

int get_calibration(int shaft, const char *msg, bool allow_abort) {  // calibrate the center, bottom, or top position of a shaft
   // returns the number of steps down (negative) or up (positive) we went, or 999 if aborted
   enum events event;
   int steps = 0, stepadj;
   char str[25];


bool using_shaft(int shaft) {  // does any used treadle tie up to this shaft?
   if ((file_hdr.flags & FILE_TABBY) &&
         (tieup[shaft][0] || tieup[shaft][1])) return true;  // used by treadle 0 or 1 in "alternate tabby 1/2" mode
   for (int pos = 0; pos < sequence_size; ++pos)
      if (treadle_sequence[pos] != UNUSED_SEQ && tieup[shaft][treadle_sequence[pos]])
         return true;
