Skip to content. | Skip to navigation

Personal tools

mturret.cpp

mturret.cpp

mturret.cpp

/////////////////////////////////////////////////////////////////////////////
// MTURRET.CPP
//
//  Last updated: 10/31/2003
//
//  Part of the source code for the M3 Program
//
//  Contains routines for motion and status of the M3 (inner) turret
/////////////////////////////////////////////////////////////////////////////

void M3TurretInterrupt()
{
	// Do we need to do an emergency stop?
	if (M3Turret->abortmove)
  {
		// Don't go further than the emergency stop distance
		if (M3Turret->movesteps > M3Turret->EmergencyStopDistance)
			M3Turret->movesteps = M3Turret->EmergencyStopDistance - 1;
		// Stop even sooner if our motion profile allows it
		if (M3Turret->movesteps > M3Turret->profileindex)
			M3Turret->movesteps = M3Turret->profileindex;
		// Jump to the necessary deceleration point in the motion profile
		M3Turret->profileindex = M3Turret->movesteps;
		// Don't go faster than max velocity
		if (M3Turret->profileindex >= M3Turret->MaxProfile)
			M3Turret->profileindex = M3Turret->MaxProfile - 1;
		M3Turret->pulsecount = 1;

    // Remember why we aborted
    M3Turret->tempresult = M3Turret->abortmove;
    M3Turret->abortmove = 0;

    // Stop now if movesteps is already 0
    if (M3Turret->movesteps == 0)
    {
	    M3Turret->moveresult = M3Turret->tempresult;
      M3Turret->Motion = MTMStop;
	    return;
    }
  }

	// Should we be moving things?
	if (M3Turret->movesteps > 0)
  {
  	// Did we hit a limit?
  	//if (M3Turret->CheckLimit(M3Turret->limitbit))
    //{
    //	M3Turret->abortmove = MTRHitLimit;		// We hit a limit, so abort
    //	return;
    //}

	  // On the first loop for the current step, set the step bit
	  if (M3Turret->pulsecount == 1)
	  {
		  M3Turret->pulsecount++;
		  SetDigBit(MTBitStep);
	  }
	  // Delay until pulse needs to go back low (halfway through current step)
	  else if (M3Turret->pulsecount == M3Turret->Profile[M3Turret->profileindex] >> 1)
	  {
		  M3Turret->pulsecount++;
		  ClrDigBit(MTBitStep);
	  }
	  // At the end of the current step, update the motion profile,
	  // and motor phase tracking
	  else if (M3Turret->pulsecount == M3Turret->Profile[M3Turret->profileindex])
	  {
    	// Get ready for next step
		  M3Turret->pulsecount = 1;
		  M3Turret->movesteps--;

      // Are we done?
      if (M3Turret->movesteps == 0)
      {
        M3Turret->moveresult = M3Turret->tempresult;
        M3Turret->Motion = MTMStop;
        return;
      }

		  // Accelerate
		  if (M3Turret->profileindex < M3Turret->movesteps)
			  M3Turret->profileindex++;
		  // Decelerate or maintain max speed (depending on steps left)
		  else
			  M3Turret->profileindex = M3Turret->movesteps;
		  // Update recorded motor phase
		  if (GetDigBit(MTBitMon))
			  M3Turret->MonStep = 0;
		  else
		  {
			  M3Turret->MonStep += M3Turret->direction;
			  if (M3Turret->MonStep > 9)
				  M3Turret->MonStep -= 10;
			  if (M3Turret->MonStep < 0)
				  M3Turret->MonStep += 10;
		  }
	  }
	  // Keep looping for current step
	  else
		  M3Turret->pulsecount++;

	  // Don't exceed maximum velocity
	  if (M3Turret->profileindex >= M3Turret->MaxProfile)
		  M3Turret->profileindex = M3Turret->MaxProfile - 1;

    ////////////////////////////////////////////////////////////////////
    // If we're moving slowly to an index, make sure you can always
		// decelerate exactly to the target index.
    // if we are moving in the forward direction
    if (M3Turret->direction == 1)
    {
		  if ((M3Turret->submove == MTSSlowIndex) &&
				  (M3Turret->profileindex > M3Turret->MTHalfIndexWidthFwd))
			  M3Turret->profileindex = M3Turret->MTHalfIndexWidthFwd;
    }
    // we are moving in the revrse direction
    else
    {
		  if ((M3Turret->submove == MTSSlowIndex) &&
				  (M3Turret->profileindex > M3Turret->MTHalfIndexWidthRev))
			  M3Turret->profileindex = M3Turret->MTHalfIndexWidthRev;
    }

	  // Read indexes
	  M3Turret->IndexA = GetDigBit(MTBitIndexA);
	  M3Turret->IndexB = GetDigBit(MTBitIndexB);
	  M3Turret->IndexC = GetDigBit(MTBitIndexC);
	  M3Turret->Index = M3Turret->IndexA + 2*M3Turret->IndexB + 4*M3Turret->IndexC;

		// If we're moving slowly to an index and we come to an index,
		// stop in half the width of an index.
		if ((M3Turret->submove == MTSSlowIndex) &&
				(M3Turret->Index && !M3Turret->indexflag))
		{
			M3Turret->indexflag = 1;		// We just found an index
			if (M3Turret->direction == 1)	// in the forward direction
			  M3Turret->movesteps = M3Turret->MTHalfIndexWidthFwd;
      else	// we are moving in the reverse direction
			  M3Turret->movesteps = M3Turret->MTHalfIndexWidthRev;
    }

    // Check if we're supposed to stop after a given number of indexes
		if ((M3Turret->submove == MTSStopOnIndex) ||
				(M3Turret->submove == MTSStepsPastIndex))
    {
    	// Flag when we're off an index
		  if (!M3Turret->Index)
			  M3Turret->indexflag = 0;
		  // Flag if we hit an index mark and come to a stop if necessary
		  if (M3Turret->Index && !M3Turret->indexflag)
		  {
			  M3Turret->indexflag = 1;
			  M3Turret->indexleft--;
			  if (M3Turret->indexleft == 0)
         	if (M3Turret->submove == MTSStopOnIndex)
					  M3Turret->movesteps = M3Turret->profileindex; // Stop now
          else
				    M3Turret->movesteps = M3Turret->extrasteps;	// Move extrasteps further
			  else
				  M3Turret->movesteps = M3Turret->MTMinIndexDistance; // Move to next index
		  }
    }
  }
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::Init - Initialize M3 Turret object
void CM3Turret::Init()
{
	int i;
	int minpulse;				// Minimum number of FastestSteps for the given max velocity
	double total;				// Used for motion profile calculations (total time)
  double error;				// Used for motion profile calculations (cumulative error)
	double err,errp,errm; // Test errors for small changes in a Profile entry
  double Vt;					// Target velocity
  double V,Vp,Vm;			// Newly calculated velocities
  int Done = 0;				// Flag for completion of motion profile

	// Allocate an array for the stepper motion profile
	Profile = (int *)malloc(MotionProfile * sizeof(int));
	FastestStep = 1.0 / RealClockRate; // Shortest pulse width in seconds

	// Initialize all status variables
	Motion = MTMStop;
	OldMotion = MTMStop;
  Moving = 0;
  MoveType = MTMTNone;
	//Limit = MTLNone;
  OldLimit = -1;
	Position = MTPUnknown;
	OldPosition = -1;
	CartoonPosition = MTCPNone;
	OldCartoonPosition = MTCPNone;
	Index = 0;
	IndexA = 0;
	IndexB = 0;
	IndexC = 0;
	OldIndex = -1;
	Dir = 0;
	Stp = 0;
	Mon = 0;
	Pwr = 0;
	Cur = 0;
	MonStep = 0;
  FwdLimitCount = 0;
  RevLimitCount = 0;

  // Initialize interrupt flags
  abortmove = 0;
  movesteps = 0;

	// Initialize motion profile
	i = 1;
	// Initial pulse length (Convert from milliseconds to ticks)
	Profile[0] = InitialPulse / 1000.0 / FastestStep;
  // total = total time in seconds the profile has used so far
	total = Profile[0] * FastestStep;
	// minpulse is the lower limit on our motion profile; when the profile
	// pulse width gets shorter than minpulse, we're at our maximum velocity.
	minpulse = 1.0 / (FastestStep * MaxVelocity);
	// minpulse must be at least 2 to toggle the stepper bit on and then off.
	if (minpulse < 2) minpulse = 2;

  Done = 0;
  error = 0;
	while (!Done)
	{
		// Calculate stepper acceleration pulse profile
    Vt = Acceleration * total;
   	Profile[i] = 1.0 / (Acceleration * total * FastestStep);

    // Find possible velocities near our target velocity
    V = round(1.0 / (Profile[i] * FastestStep));
    Vp = round(1.0 / ((Profile[i]+1) * FastestStep));
    Vm = round(1.0 / ((Profile[i]-1) * FastestStep));
    // Dither velocities if necessary for a smooth ramp-up
    if (i > 1)
    {
    	// Find new velocity that minimizes accumulated error
    	err = fabs(error + (V - Vt));
      errp = fabs(error + (Vp - Vt));
      errm = fabs(error + (Vm - Vt));
      if ((errp < err) && (errp < errm))
      	Profile[i]++;
      else if ((errm < err) && (errm < errp))
      	Profile[i]--;

	    V = 1.0 / (Profile[i] * FastestStep);
    }
    // Keep track of total error
    error += V - Vt;

		if (Profile[i] < minpulse)
    {
			Profile[i] = minpulse;
      Done = 1;
    }
		// Add to total time for next calculation
		total += Profile[i] * FastestStep;
		i++;
    if (i == MotionProfile)
    	Done = 1;
	}
	// When accelerating a stepper, go from Profile[0] .. Profile[MaxProfile-1]
	MaxProfile = i;
  GroupFlag = 0;
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::Update - Update all M3 turret status, motion
void CM3Turret::Update()
{
	int e;

	// Save old status values, and display on-screen if they change
	int OldDir = Dir,OldStp = Stp,OldMon = Mon,OldPwr = Pwr,OldCur = Cur;

	// Read limit switches
  //CheckLimit(0);

	// Read indexes
	IndexA = GetDigBit(MTBitIndexA);
	IndexB = GetDigBit(MTBitIndexB);
	IndexC = GetDigBit(MTBitIndexC);
	Index = IndexA + 2*IndexB + 4*IndexC;
	// Read stepper controller status bits
	Dir = GetDigBit(MTBitDir);
	Stp = GetDigBit(MTBitStep);
	Mon = GetDigBit(MTBitMon);
	Pwr = !GetParBit(5);
	Cur = GetParBit(1);

  // Update any high level motion in progress
  // (a MoveSteps, Home, or MovePosition)
  if (Moving)
  {
  	switch (MoveType)
    {
    	case MTMTSteps:
      {
      	switch (MoveStep)
        {
        	// MoveSteps: Wait for stepper power to come on
        	case 0:
          {
          	if (msTimer - StepperTime >= 1000)
            {
            	StepperPowerOnStage2();
              MoveStep = 1;
            }
          } break;
          // MoveSteps: Begin move
          case 1:
          {
            SubStep = 0;
	          subMoveSteps(tempsteps);
            MoveStep = 2;
          } break;
          // MoveSteps: Wait for move to finish
          case 2:
          {
		      	e = subMoveSteps(0);
		        if (e >= 0)
		        {
            	if (e > 0)
              {
				        if (e == MTRUserAbort)
					        EDSLog.Add(6,"M3 Turret: User interrupted motion");
				        //else if (e == MTRHitLimit)
					      //  EDSLog.Add(7,"M3 Turret: Hit a limit");
			     	    else
					  	    EDSLog.Add(8,"M3 Turret: Motion error");
              }
              MoveType = MTMTNone;
              Moving = 0;
              StepperPowerOff(1);
            }
          } break;
        }
      } break; // End of MTMTSteps case
      case MTMTHome:
      {
      	switch (MoveStep)
        {
          // Home: Unlock M3 Turret Pin
        	case 0:
          {
	          M3TurretPin.ForcedUnlock();
  	        MoveStep = 1;
          } break;
        	// Home: Wait for lockpin to unlock
        	case 1:
          {
          	if ((msTimer - M3TurretPin.MotionTimer) > TimePinUnlock)
  	        	MoveStep = 2;
          } break;
        	// Home: turn stepper power on
          case 2:
          {
            if (StepperPowerOn())
            {
  	          StepperTime = msTimer;
		          MoveStep = 3;
            }
            else
  	          MoveStep = 4;
          } break;
        	// Home: Wait for stepper power to come on
        	case 3:
          {
          	if (msTimer - StepperTime >= 1000)
            {
            	StepperPowerOnStage2();
              MoveStep = 4;
            }
          } break;
          // Home: Begin move to complete pin-dog unlocking
          case 4:
          {
            SubStep = 0;
	          subMoveSteps(StepsToUnlock);
            MoveStep = 5;
          } break;
          // Home: Wait for move to finish
          case 5:
          {
		      	e = subMoveSteps(0);
            if (e < 0)
            	break;		// Not done yet
            else if (e == 0)
              MoveStep = 10; // Go check if dog is retracted
            else	// An error occurred
            {
				      if (e == MTRUserAbort)
					      EDSLog.Add(6,"M3 Turret: User interrupted motion");
				      //else if (e == MTRHitLimit)
					    //  EDSLog.Add(7,"M3 Turret: Hit a limit");
			     	  else
					  	  EDSLog.Add(8,"M3 Turret: Motion error");
              MoveType = MTMTNone;
              Moving = 0;
              StepperPowerOff(1);
              break;
            }
          } break;

        	// Home: Wait for M3 Turret dog to retract
        	case 10:
          {
          	if (M3TurretPin.Motion == MTPMStop)
            {
			        if (M3TurretPin.Limit != MTPLUnlock)
			        {
                MoveType = MTMTNone;
                Moving = 0;
                StepperPowerOff(1);
				        EDSLog.Add(5,"M3 Turret: Unable to unlock pin");
		  	      }
              else
              	MoveStep = 11;
            }
          } break;
          // Home: See if we're on an index
          case 11:
          {
	          if (Index != 0)
	          {
		          // We're already on an index, move off a bit and back on to center
							SubStep = 0;
		          subMoveSteps(1000);
              MoveStep = 12;
            }
            else
            {
            	// We're not on an index, find one
              SubStep = 0;
              subMoveAndStopOnIndex(1);
              MoveStep = 16;
            }
          } break;
          // Home: Wait to get off index
          case 12:
          {
          	e = subMoveSteps(0);
            if (e < 0)
            	break;		// Not done yet
            //else if ( (e == 0) || ((e == 2) && (Limit == MTLForward)) )
            else if (e == 0)
            	MoveStep = 13;		// OK, the move off the index is complete
            else	// An error occurred
            {
			        // The motion was interrupted by a user keypress
			        if (e == 1)
				        EDSLog.Add(6,"M3 Turret: User interrupted motion");
			        //else if (e == 2)
				      //  EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
			        else
				        EDSLog.Add(8,"M3 Turret Home: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
            }
          } break;
          // Home: Are we at the forward limit or are we still on an index?
          case 13:
          {
		        // Are we at the forward limit or are we still on an index?
		        // If so, back up and then move forward slowly
		        //if ((Limit == MTLForward) || (Index != 0))
		        if (Index != 0)
		        {
							SubStep = 0;
		          subMoveSteps(-2000);
              MoveStep = 14;
            }
            else
            {
              // We're not on an index or at the forward limit,
              // so back up onto the index we left
              SubStep = 0;
              subMoveSlowToIndex(-2000);
              MoveStep = 15;
            }
          } break;
          // Home: Wait for back up move to complete
          case 14:
          {
            e = subMoveSteps(0);
            if (e > 0)	// Was there an error?
            {
					    if (e == 1)
						    EDSLog.Add(6,"M3 Turret: User interrupted motion");
					    //else if (e == 2)
						  //  EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
					    else
						    EDSLog.Add(8,"M3 Turret: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
				    }
            else if (e == 0)
            {
            	// Back up move is complete.
              // Now move slowly to the index.
              SubStep = 0;
              subMoveSlowToIndex(4000);
            	MoveStep = 15;
            }
          } break;
          // Home: Wait for the move back to the center of the index
      		case 15:
          {
          	e = subMoveSlowToIndex(0);
            if (e > 0)	// Was there an error?
            {
					    if (e == 1)
						    EDSLog.Add(6,"M3 Turret: User interrupted motion");
					    //else if (e == 2)
						  //  EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
					    else if (e == 3)
						    EDSLog.Add(9,"M3 Turret: Couldn't find an index");
					    else
						    EDSLog.Add(8,"M3 Turret: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
				    }
            else if (e == 0)
            {
            	// Move to center of index is complete. Home successful.
              MoveStep = 19;	// Lock M3 Turret Pin
            }
          } break;
          // Home:  We're not on an index, wait to find one
          case 16:
          {
          	e = subMoveAndStopOnIndex(0);
            if (e < 0)	// Not done yet
            	break;
            //else if ( (e == 0) || ((e == 2) && (Limit == MTLForward)) )
            else if (e == 0)
            {
		          //if ((Limit != MTLForward) && (Index == 0))
		          if (Index == 0)
		          // We're not at the limit or an index, so just move slowly back to the
		          // center of the index
              {
            	  SubStep = 0;
			          subMoveSlowToIndex(-2000);
                MoveStep = 15;
              }
		          else
		          // We're at the forward limit or we didn't clear the index.
		          // Backup a bunch and then move to the index
		          {
            	  SubStep = 0;
			          // Try to move backwards off the limit or index
			          subMoveSteps(-2000);
                MoveStep = 17;
              }
            }
            else	// An error occurred
            {
			        // The motion was interrupted by a user keypress
			        if (e == 1)
				        EDSLog.Add(6,"M3 Turret: User interrupted motion");
			        // We hit the reverse limit, so things are really screwed up
			        // because we were moving forward.
			        //else if ((e == 2) && (Limit != MTLForward))
				      //  EDSLog.Add(7,"M3 Turret: Hit wrong limit");
			        else
				        EDSLog.Add(8,"M3 Turret Home: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
            }
          } break;
          // Home: Wait to move backwards off of limit
          case 17:
          {
          	e = subMoveSteps(0);
            if (e < 0)	// Not done yet
            	break;
            else if (e == 0)
						{
		          // Move slowly forward onto the index
           	  SubStep = 0;
		          subMoveSlowToIndex(4000);
              MoveStep = 15;
						}
						/*
            else if ((e == 2) && (Limit == MTLReverse))
            {
		          // We backed into the reverse limit,
		          // so go forward past the index and back into it slowly
           	  SubStep = 0;
		          subMoveSteps(2000);
              MoveStep = 18;
            }
            */
            else	// An error occurred
            {
			        // The motion was interrupted by a user keypress
			        if (e == 1)
				        EDSLog.Add(6,"M3 Turret: User interrupted motion");
			        // We hit the forward limit, so things are really screwed up
			        // because we were moving backwards.
			        //else if ((e == 2) && (Limit != MTLReverse))
				      //  EDSLog.Add(7,"M3 Turret: Hit wrong limit");
			        else
				        EDSLog.Add(8,"M3 Turret Home: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
            }
          } break;
          // Home: Wait for forward move
          case 18:
          {
            /*
          	e = subMoveSteps(0);
            if (e > 0)	// Was there an error?
            {
					    if (e == 1)
						    EDSLog.Add(6,"M3 Turret: User interrupted motion");
					    else if (e == 2)
						    EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
					    else
						    EDSLog.Add(8,"M3 Turret: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
				    }
            else if (e == 0)
            {
            	// Forward move is complete.
              // Now move slowly to the index.
              SubStep = 0;
              subMoveSlowToIndex(-4000);
            	MoveStep = 15;
            }
            */
          } break;
          // Home: Lock the M3 Turret Pin
          case 19:
          {
			      StepperPowerOff(1);
						M3TurretPin.Lock(1);
            MoveStep = 20;
          } break;
          // Home: Wait for lock to complete
          case 20:
          {
          	if (M3TurretPin.Motion == MTPMStop)
            {
			        if (M3TurretPin.Limit != MTPLLock)
				        EDSLog.Add(5,"M3 Turret: Unable to lock pin");
              // All done.
              MoveType = MTMTNone;
              Moving = 0;
            }
          } break;
        }
      } break; // End of MTMTHome case
      // Move to a given position
      case MTMTPosition:
      {
      	switch (MoveStep)
        {
          // MovePosition: Unlock M3 Turret Pin
        	case 0:
          {
	          M3TurretPin.ForcedUnlock();
  	        MoveStep = 1;
          } break;
        	// MovePosition: Wait for lockpin to unlock
        	case 1:
          {
          	if ((msTimer - M3TurretPin.MotionTimer) > TimePinUnlock)
  	        	MoveStep = 2;
          } break;
        	// MovePosition: turn stepper power on
          case 2:
          {
            if (StepperPowerOn())
            {
  	          StepperTime = msTimer;
		          MoveStep = 3;
            }
            else
  	          MoveStep = 4;
          } break;
        	// MovePosition: Wait for stepper power to come on
        	case 3:
          {
          	if (msTimer - StepperTime >= 1000)
            {
            	StepperPowerOnStage2();
              MoveStep = 4;
            }
          } break;
          // MovePosition: Begin move to complete pin-dog unlocking
          case 4:
          {
            SubStep = 0;
	          subMoveSteps(StepsToUnlock);
            MoveStep = 5;
          } break;
          // MovePosition: Wait for move to finish
          case 5:
          {
		      	e = subMoveSteps(0);
            if (e < 0)
            	break;		// Not done yet
            else if (e == 0)
              MoveStep = 9; // Go check if dog is retracted
            else	// An error occurred
            {
				      if (e == MTRUserAbort)
					      EDSLog.Add(6,"M3 Turret: User interrupted motion");
				      //else if (e == MTRHitLimit)
					    //  EDSLog.Add(7,"M3 Turret: Hit a limit");
			     	  else
					  	  EDSLog.Add(8,"M3 Turret: Motion error");
              MoveType = MTMTNone;
              Moving = 0;
              StepperPowerOff(1);
              break;
            }
          } break;

        	// MovePosition: Check if we need to servo the tilts also
        	case 9:
          {
            if (GroupFlag == 6) // west
							Tilt.ServoAll(Tilt.TNASW[0],Tilt.TNASW[1],Tilt.TNASW[2]);
            else if (GroupFlag == 5) // aux3
							Tilt.ServoAll(Tilt.TAUX3[0],Tilt.TAUX3[1],Tilt.TAUX3[2]);
            else if (GroupFlag == 4) // aux2
							Tilt.ServoAll(Tilt.TAUX2[0],Tilt.TAUX2[1],Tilt.TAUX2[2]);
            else if (GroupFlag == 3) // aux1
							Tilt.ServoAll(Tilt.TAUX1[0],Tilt.TAUX1[1],Tilt.TAUX1[2]);
            else if (GroupFlag == 2) // nase
							Tilt.ServoAll(Tilt.TNASE[0],Tilt.TNASE[1],Tilt.TNASE[2]);
            MoveStep = 10;
          }
        	// MovePosition: Wait for M3 Turret dog to retract
        	case 10:
          {
          	if (M3TurretPin.Motion == MTPMStop)
            {
			        if (M3TurretPin.Limit != MTPLUnlock)
			        {
                MoveType = MTMTNone;
                Moving = 0;
                StepperPowerOff(1);
				        EDSLog.Add(5,"M3 Turret: Unable to unlock pin");
		  	      }
              else
              	MoveStep = 11;
            }
          } break;
          // MovePosition: Move to just before our target index
          case 11:
          {
          	SubStep = 0;
          	subMoveStepsPastIndex(indexnum,distance);
            MoveStep = 12;
          } break;
          // MovePosition: Wait for move to complete
          case 12:
          {
          	e = subMoveStepsPastIndex(0,0);
            if (e > 0)	// Was there an error?
            {
					    if (e == 1)
						    EDSLog.Add(6,"M3 Turret: User interrupted motion");
					    //else if (e == 2)
						  //  EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
					    else
						    EDSLog.Add(8,"M3 Turret: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
				    }
            else if (e == 0)
            {
            	// Big move is complete.
              // Now move slowly to the index.
              SubStep = 0;
              subMoveSlowToIndex(extradistance);
            	MoveStep = 13;
            }
          } break;
          // Move position: Wait for slow move to complete
          case 13:
          {
          	e = subMoveSlowToIndex(0);
            if (e > 0)	// Was there an error?
            {
					    if (e == 1)
						    EDSLog.Add(6,"M3 Turret: User interrupted motion");
					    //else if (e == 2)
						  //  EDSLog.Add(10,"M3 Turret: Hit an unexpected limit");
					    else if (e == 3)
						    EDSLog.Add(9,"M3 Turret: Couldn't find an index");
					    else
						    EDSLog.Add(8,"M3 Turret: Motion error");
			        MoveType = MTMTNone;
				      StepperPowerOff(1);
              Moving = 0;
              break;
				    }
            else if (e == 0)
            {
            	// Move to center of index is complete. Home successful.
              MoveStep = 14;	// Lock M3 Turret Pin
            }
          } break;
          // MovePosition: Lock the M3 Turret Pin
          case 14:
          {
			      StepperPowerOff(1);
						M3TurretPin.Lock(1);
            MoveStep = 15;
          } break;
          // MovePosition: Wait for lock to complete
          case 15:
          {
          	if (M3TurretPin.Motion == MTPMStop)
            {
			        if (M3TurretPin.Limit != MTPLLock)
				        EDSLog.Add(5,"M3 Turret: Unable to lock pin");
              // All done.
              MoveType = MTMTNone;
              Moving = 0;
            }
          } break;
        }
      } break; // End of MTMTPosition case
    }
  }

	// Figure out what position the turret and its cartoon should be in
	CartoonPosition = MTCPNone;
	if (Motion != MTMStop)
		Position = MTPMidway;	// We're between indexes, and moving
	else
	{
		// Can we figure out where we are? We need a locked pin to do so
		if (M3TurretPin.Limit == MTPLLock)
			switch(Index)
			{
				case 5: Position = MTPForward; 		break;	// Nas W
				case 4: Position = MTPForwardAux;	break;	// Aux 3
				case 3:	Position = MTPMiddleAux;	break;	// Aux 2
				case 2:	Position = MTPReverseAux;	break;	// Aux 1
				case 1:	Position = MTPReverse;		break;	// Nas E
				default: Position = MTPUnknown;		break;	// We're lost
			}
		// Verify that we're at the position we think we're in
		switch(Position)
		{
			// If we're stopped and there's no index, we're lost.
			case MTPMidway:
				Position = MTPUnknown;
			break;
			case MTPForward:
				//if ((Index != 5) || (Limit != MTLNone))
				if (Index != 5)
					Position = MTPUnknown;
				else
				{
					if (Mirror.Limit == MLDown)
						CartoonPosition = MTCPNasEDown;
					else
						CartoonPosition = MTCPNasEUp;
				}
			break;
			case MTPForwardAux:
				//if ((Index != 4) || (Limit != MTLNone))
				if (Index != 4)
					Position = MTPUnknown;
				else
				{
					if (Mirror.Limit == MLDown)
						CartoonPosition = MTCPAux3Down;
					else
						CartoonPosition = MTCPAux3Up;
				}
			break;
			case MTPMiddleAux:
				//if ((Index != 3) || (Limit != MTLNone))
				if (Index != 3)
					Position = MTPUnknown;
				else
				{
					if (Mirror.Limit == MLDown)
						CartoonPosition = MTCPAux2Down;
					else
						CartoonPosition = MTCPAux2Up;
				}
			break;
			case MTPReverseAux:
				//if ((Index != 2) || (Limit != MTLNone))
				if (Index != 2)
					Position = MTPUnknown;
				else
				{
					if (Mirror.Limit == MLDown)
						CartoonPosition = MTCPAux1Down;
					else
						CartoonPosition = MTCPAux1Up;
				}
			break;
			case MTPReverse:
				//if ((Index != 1) || (Limit != MTLNone))
				if (Index != 1)
					Position = MTPUnknown;
				else
				{
					if (Mirror.Limit == MLDown)
						CartoonPosition = MTCPNasWDown;
					else
						CartoonPosition = MTCPNasWUp;
				}
			break;
		}
	}

	// Display anything that has changed
	if (OldMotion != Motion)
		DisplayMotion();
	//if (OldLimit != Limit)
	//	DisplayLimit();
	if (OldIndex != Index)
		DisplayIndex();
	if (OldPosition != Position)
		DisplayPosition();
	if (OldCartoonPosition != CartoonPosition)
		DisplayCartoon();
	if ((OldDir != Dir) || (OldStp != Stp) || (OldMon != Mon) ||
			(OldPwr != Pwr) || (OldCur != Cur))
		DisplayStepper();

	// Record displayed values
  //OldLimit = Limit;
	OldPosition = Position;
	OldMotion = Motion;
	OldIndex = Index;
	OldCartoonPosition = CartoonPosition;
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayAll - Redraw all status info on-screen
void CM3Turret::DisplayAll()
{
	DisplayMotion();
	//DisplayLimit();
	DisplayIndex();
	DisplayPosition();
	DisplayCartoon();
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayMotion - Display motion status bits on-screen
void CM3Turret::DisplayMotion()
{
	int x = 148,y = 200;

	switch (Motion)
	{
		case MTMStop:
			PutChar16(CLeftRight,x,y,BLACK,SHECMEDGRAY);break;
		case MTMForward:
			PutChar16(CRight,x,y,SHECGREEN,SHECMEDGRAY);break;
		case MTMReverse:
			PutChar16(CLeft,x,y,SHECGREEN,SHECMEDGRAY);break;
		default:
			PutChar16(CLeftRight,x,y,SHECRED,SHECMEDGRAY);
	}
}

/*
/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayLimit - Display limit status bits on-screen
void CM3Turret::DisplayLimit()
{
	int x = 188,y = 200;

	switch (Limit)
	{
		case MTLNone:
			PutChar16(CLeftRight,x,y,BLACK,SHECMEDGRAY);break;
		case MTLForward:
			PutChar16(CRight,x,y,SHECGREEN,SHECMEDGRAY);break;
		case MTLReverse:
			PutChar16(CLeft,x,y,SHECGREEN,SHECMEDGRAY);break;
		default:
			PutChar16(CLeftRight,x,y,SHECRED,SHECMEDGRAY);
	}
}
*/

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayIndex - Display index status bits on-screen
void CM3Turret::DisplayIndex()
{
	int x = 220,y = 200;

	if (IndexA)
		PutChar16('A',x,y,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('A',x,y,BLACK,SHECMEDGRAY);
	if (IndexB)
		PutChar16('B',x+8,y,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('B',x+8,y,BLACK,SHECMEDGRAY);
	if (IndexC)
		PutChar16('C',x+16,y,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('C',x+16,y,BLACK,SHECMEDGRAY);
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayPosition - Display M3 turret position on-screen
void CM3Turret::DisplayPosition()
{
	int x1 = 260,x2 = 340,y = 200;

	switch (Position)
	{
		case MTPUnknown:
			PutString16("Unknown",x1,x2,y,SHECRED,SHECMEDGRAY);break;
		case MTPMidway:
			PutString16("Midway",x1,x2,y,BLACK,SHECMEDGRAY);break;
		case MTPForward:
			PutString16("Nas W",x1,x2,y,BLACK,SHECMEDGRAY);break;
		case MTPForwardAux:
			PutString16("Aux 3",x1,x2,y,BLACK,SHECMEDGRAY);break;
		case MTPMiddleAux:
			PutString16("Aux 2",x1,x2,y,BLACK,SHECMEDGRAY);break;
		case MTPReverseAux:
			PutString16("Aux 1",x1,x2,y,BLACK,SHECMEDGRAY);break;
		case MTPReverse:
			PutString16("Nas E",x1,x2,y,BLACK,SHECMEDGRAY);break;
		default:
			PutString16("Error",x1,x2,y,BLACK,SHECMEDGRAY);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayCartoon - Erase last cartoon and draw current one
void CM3Turret::DisplayCartoon()
{
	DrawCartoon(OldCartoonPosition,SHECMEDGRAY);
	DrawCartoon(CartoonPosition,BLACK);
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DrawCartoon - Draw the M3 cartoon at given Position in Color
void CM3Turret::DrawCartoon(int Position,int Color)
{
	int i,j;

	// Draw an arrow if the mirror is down in the beam
	if ((Position >= MTCPNasWDown) && (Position <= MTCPNasEDown))
	{
		i = Position - 1;
		// Draw MT arrow
		for (j=1;j<=3;j++)
			Line(MTurretCoords[i][0],MTurretCoords[i][1],
					 MTurretCoords[i][j*2],MTurretCoords[i][j*2+1],
					 Color);
	}
	// Otherwise draw a line, showing the mirror out of the beam
	else if ((Position >= MTCPNasWUp) && (Position <= MTCPNasEUp))
	{
		i = Position - 11;
		// Draw MT line
		Line(MTurretCoords[i][8],MTurretCoords[i][9],
				 MTurretCoords[i][10],MTurretCoords[i][11],
				 Color);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::DisplayStepper - Display all stepper status bits
void CM3Turret::DisplayStepper()
{
	// Direction
	if (Dir)
		PutChar16('þ',468,32,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('þ',468,32,BLACK,SHECMEDGRAY);
	// Step
	if (Stp)
		PutChar16('þ',500,32,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('þ',500,32,BLACK,SHECMEDGRAY);
	// Moni (Motor phase)
	if (Mon)
		PutChar16('þ',532,32,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('þ',532,32,BLACK,SHECMEDGRAY);
	// Power
	if (Pwr)
		PutChar16('þ',564,32,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('þ',564,32,BLACK,SHECMEDGRAY);
	// Motor Current
	if (Cur)
		PutChar16('þ',596,32,SHECGREEN,SHECMEDGRAY);
	else
		PutChar16('þ',596,32,BLACK,SHECMEDGRAY);
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::Home - Find the position of the M3 turret
int CM3Turret::Home()
// Returns a 0 on success or if move was started,
// 1 on other moves in progress, 2 on mirror not down
{
	// See if we can immediately figure out where we are
	// (if the turret is locked at one of its indexes)
	Position = MTPUnknown;
	if (M3TurretPin.Limit == MTPLLock)
		switch(Index)
		{
			case 5:
				Position = MTPForward;
			break;
			case 4:
				Position = MTPForwardAux;
			break;
			case 3:
				Position = MTPMiddleAux;
			break;
			case 2:
				Position = MTPReverseAux;
			break;
			case 1:
				Position = MTPReverse;
			break;
			default:
				Position = MTPUnknown;
		}
	if (Position != MTPUnknown)
		return(0);

	// We don't know where we are, so we need to do a full home

	// Don't move if there are any other moves taking place
  if (Moving || (ADCTurret->Moving) || (Mirror.MMoving) || (Mirror.LMoving) ||
  	  (ADCTurretPin.Moving) || (M3TurretPin.Moving))
	{
    if (Moving)
  	  EDSLog.Add(500,"M3 Turret: Home aborted, M3 Turret moving");
    else if (ADCTurret->Moving)
  	  EDSLog.Add(500,"M3 Turret: Home aborted, ADC Turret moving");
    else if (Mirror.MMoving)
  	  EDSLog.Add(500,"M3 Turret: Home aborted, M3 Mirror moving");
    else if (Mirror.LMoving)
  	  EDSLog.Add(500,"M3 Turret: Home aborted, M3 Mirror latches moving");
    else if (ADCTurretPin.Moving)
  	  EDSLog.Add(500,"M3 Turret: Home aborted, ADC Turret pin moving");
    else if (M3TurretPin.Moving)
      EDSLog.Add(500,"M3 Turret: Home aborted, M3 Turret pin moving");
    return(1);
  }

  // Don't move if mirror not down
  if (!(Mirror.Limit & MLDown))
	{
		EDSLog.Add(71,"M3 Turret: Home aborted, mirror not down");
    return(2);
  }

  // Ok, we're going to have to do some moving
  Moving = 1;
  MoveType = MTMTHome;

  MoveStep = 0;

	// Home started successfully
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::MovePosition - Move to one of the turret's five positions
int CM3Turret::MovePosition(int targetposition)
// Returns a 0 on success or if move was started,
// 1 on other moves in progress, 2 on mirror not down,
// 3 if we need to home first.
{
	// Are we already at the commanded position?
	if (Position == targetposition)
		return(0);

	// Don't move if there are any other moves taking place
  if (Moving || (ADCTurret->Moving) || (Mirror.MMoving) || (Mirror.LMoving) ||
  	  (ADCTurretPin.Moving) || (M3TurretPin.Moving))
	{
    if (Moving)
  	  EDSLog.Add(500,"M3 Turret: Move position aborted, M3 Turret moving");
    else if (ADCTurret->Moving)
  	  EDSLog.Add(500,"M3 Turret: Move position aborted, ADC Turret moving");
    else if (Mirror.MMoving)
  	  EDSLog.Add(500,"M3 Turret: Move position aborted, M3 Mirror moving");
    else if (Mirror.LMoving)
  	  EDSLog.Add(500,"M3 Turret: Move position aborted, M3 Mirror latches moving");
    else if (ADCTurretPin.Moving)
  	  EDSLog.Add(500,"M3 Turret: Move position aborted, ADC Turret pin moving");
    else if (M3TurretPin.Moving)
      EDSLog.Add(500,"M3 Turret: Move position aborted, M3 Turret pin moving");
    return(1);
  }

  // Don't move if mirror not down
  if (!(Mirror.Limit & MLDown))
	{
		EDSLog.Add(73,"M3 Turret: Move aborted, mirror not down");
    return(2);
  }

	// Don't move because we're lost and need a Home operation
	if (Position == MTPUnknown)
	{
		EDSLog.Add(16,"M3 Turret: Move aborted, Home required first");
		return(3);
	}

	// How many index marks do we have to pass?
	indexnum = Position - targetposition;

	// We're going to move at full speed until just before our target.
	// There are four cases where we'll move an Aux-Nas distance after
	// we pass the last index, and in all other cases we move an aux-aux
	// distance.
	if ( ((Position == MTPForward) && (targetposition == MTPForwardAux)) ||
			 ((Position == MTPReverse) && (targetposition == MTPReverseAux)) ||
			 (targetposition == MTPForward) ||
			 (targetposition == MTPReverse) )
		distance = MTAuxToNasDistance;
	else
		distance = MTAuxToAuxDistance;
	extradistance = MTExtraDistance;
	// We're moving forward
	if (Position > targetposition)
		indexnum--;
	// We're going backward
	else
	{
		indexnum++;
		distance = -distance;
		extradistance = -extradistance;
	}

  // Begin move
  Moving = 1;
  MoveType = MTMTPosition;

  MoveStep = 0;

	// Move started successfully
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// M3Turret::MoveSteps - Move the turret the given number of steps
int CM3Turret::MoveSteps(int steps,int MotionOK)
// Returns a 0 on success or if move was started,
// 1 on other moves in progress, 2 on mirror not down,
// 3 if the turret is locked.
// Steps is positive for forward motion and negative for reverse motion
{
	// Don't move if steps is 0
  if (steps == 0)
  	return(0);

	// Don't move if there are any other moves taking place
  if (!MotionOK && (Moving || (ADCTurret->Moving) || (Mirror.MMoving) ||
     (Mirror.LMoving) || (ADCTurretPin.Moving) || (M3TurretPin.Moving)))
	{
    if (Moving)
  	  EDSLog.Add(500,"M3 Turret: Move steps aborted, M3 Turret moving");
    else if (ADCTurret->Moving)
  	  EDSLog.Add(500,"M3 Turret: Move steps aborted, ADC Turret moving");
    else if (Mirror.MMoving)
  	  EDSLog.Add(500,"M3 Turret: Move steps aborted, M3 Mirror moving");
    else if (Mirror.LMoving)
  	  EDSLog.Add(500,"M3 Turret: Move steps aborted, M3 Mirror latches moving");
    else if (ADCTurretPin.Moving)
  	  EDSLog.Add(500,"M3 Turret: Move steps aborted, ADC Turret pin moving");
    else if (M3TurretPin.Moving)
      EDSLog.Add(500,"M3 Turret: Move steps aborted, M3 Turret pin moving");
    return(1);
  }

  // Don't move if mirror not down
  if (!(Mirror.Limit & MLDown))
	{
		EDSLog.Add(72,"M3 Turret: Move aborted, mirror not down");
    return(2);
  }

	// Don't move if the turret is locked in position
	if (!MotionOK &&
     ((M3TurretPin.Limit != MTPLUnlock) || (M3TurretPin.Motion != MTPMStop)))
	{
		EDSLog.Add(12,"M3 Turret: Move aborted, turret is Locked");
		return(3);
	}

  // Tell everyone we're moving
  Moving = 1;
  MoveType = MTMTSteps;
  tempsteps = steps;
	if (StepperPowerOn())
  {
  	StepperTime = msTimer;
		MoveStep = 0;
  }
  else
  	MoveStep = 1;
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::AbortMove - Abort any move in progress
void CM3Turret::AbortMove()
{
	// Tell M3TurretInterrupt to stop anything in progress
	abortmove = 1;
}

/////////////////////////////////////////////////////////////////////////////
// M3Turret::subMoveSteps - Move the turret the given number of steps
int CM3Turret::subMoveSteps(int steps)
// Returns a -1 on not done, 0 on success, 1 on user interrupt,
//// 2 on hit a limit.
// Steps is positive for forward motion and negative for reverse motion
// Error checking (other moves in progress, mirror not down, etc) done
// in the higher level routines.
{
  switch (SubStep)
  {
  	// Begin motion
  	case 0:
    {
	    // Forward motion
	    if (steps > 0)
	    {
		    SetDigBit(MTBitDir);
		    //limitbit = MTBitForward;
		    Motion = MTMForward;
		    direction = 1;
	    }
	    // Reverse motion
	    else
	    {
		    ClrDigBit(MTBitDir);
		    //limitbit = MTBitReverse;
		    Motion = MTMReverse;
		    direction = -1;
	    }

      // Tell interrupt routine to start moving
      moveresult = -1;					// This will change on move completion
      tempresult = MTRSuccess;	// Return code for success
      abortmove = 0;						// Clear abort flag
      pulsecount = 1;
      profileindex = 0;
      submove = MTSSteps;				// Tell interrupt what kind of motion we want
	    movesteps = abs(steps);		// Interrupt starts going when it sees
  													    // movesteps != 0
      SubStep++;
    } break;
    // Check for move completion
    case 1:
    {
    	if (moveresult >= 0)
      {
      	Motion = MTMStop;
      	return(moveresult);
      }
    } break;
  };
  return(-1);	// Move not complete
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::subMoveAndStopOnIndex - Move past given number of indexes and stop
int CM3Turret::subMoveAndStopOnIndex(int indexcount)
// Returns a 0 on success, 1 on user interrupt, ////2 on hit a limit.
// This routine moves past the given number of indexes, and comes to a
// smooth stop after the last one.  This is used for the Home routine.
// indexcount > 0 for forward motion, < 0 for reverse.
// Error checking (other moves in progress, mirror not down, etc) done
// in the higher level routines.
{
  switch (SubStep)
  {
  	// Begin motion
  	case 0:
    {
	    // Move enough steps to get to the next index
	    if (indexcount < 0)
	    {
		    movesteps = MTMinIndexDistance;
		    Motion = MTMReverse;
		    direction = -1;
		    ClrDigBit(MTBitDir);
		    //limitbit = MTBitReverse;
	    }
	    else
	    {
		    movesteps = MTMinIndexDistance;
		    Motion = MTMForward;
		    direction = 1;
		    SetDigBit(MTBitDir);
		    //limitbit = MTBitForward;
	    }

	    // Check if we're initially on an index
	    if (Index)
		    indexflag = 1;
	    else
		    indexflag = 0;

      // Tell interrupt routine to start moving
      moveresult = -1;						// This will change on move completion
      tempresult = MTRSuccess;		// Return code for success
      abortmove = 0;							// Clear abort flag
      pulsecount = 1;
      profileindex = 0;
      indexleft = abs(indexcount);// Number of indexes to pass
      submove = MTSStopOnIndex;		// Tell interrupt what kind of motion we want
	    movesteps = abs(movesteps);	// Interrupt starts going when it sees
  													    	// movesteps != 0
      SubStep++;
    } break;
    // Check for move completion
    case 1:
    {
    	if (moveresult >= 0)
      {
      	Motion = MTMStop;
      	return(moveresult);
      }
    } break;
  };
  return(-1);	// Move not complete
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::subMoveSlowToIndex - Move slowly to the center of the next index
int CM3Turret::subMoveSlowToIndex(int steps)
// Returns a 0 on success, 1 on user interrupt, ////2 on hit a limit,
// 3 if we somehow aren't on an index when we should be.
// This routine moves slowly to the next index, and stops in the center
// of the index when it gets there.  Pass it the number of steps it should
// go looking for the next index before giving up, with positive steps
// being forward and negative reverse.
// Most error checking (other moves in progress, mirror not down, etc) done
// in the higher level routines.
{
  switch (SubStep)
  {
  	// Begin motion
  	case 0:
    {
    	// You're not allowed to start on top of an index
    	if (Index)
      {
      	SubStep = 2;
        break;
      }
	    // Forward motion
	    if (steps > 0)
	    {
		    SetDigBit(MTBitDir);
		    //limitbit = MTBitForward;
		    Motion = MTMForward;
		    direction = 1;
	    }
	    // Reverse motion
	    else
	    {
		    ClrDigBit(MTBitDir);
		    //limitbit = MTBitReverse;
		    Motion = MTMReverse;
		    direction = -1;
	    }

      // Tell interrupt routine to start moving
      moveresult = -1;					// This will change on move completion
      tempresult = MTRSuccess;	// Return code for success
      abortmove = 0;						// Clear abort flag
      pulsecount = 1;
      profileindex = 0;
      indexflag = 0;
      submove = MTSSlowIndex;		// Tell interrupt what kind of motion we want
	    movesteps = abs(steps);		// Interrupt starts going when it sees
  													    // movesteps != 0
      SubStep++;
    } break;
    // Check for move completion
    case 1:
    {
    	if (moveresult > 0)
      {
      	Motion = MTMStop;
      	return(moveresult);
      }
      if (moveresult == 0)
      {
      	Motion = MTMStop;
      	if (indexflag == 0)
        	return(MTRNoIndex);		// We didn't land on our index.
	      // Figure out our location
	      switch(Index)
	      {
		      case 5: Position = MTPForward; break;
		      case 4: Position = MTPForwardAux; break;
		      case 3: Position = MTPMiddleAux; break;
		      case 2: Position = MTPReverseAux; break;
		      case 1: Position = MTPReverse; break;
		      default: Position = MTPUnknown;
	      }
	      if (Position == MTPUnknown)
        	return(MTRNoIndex);		// We didn't land on our index.
	      // Success
	      return(0);
      }
    } break;
    // Error, we started on top of an index
    case 2:
    {
    	return(MTRNoIndex);
    } break;
  }
  return(-1);	// Move not complete
}

/////////////////////////////////////////////////////////////////////////////
// CM3Turret::subMoveStepsPastIndex - Move past indexes, plus additional steps
int CM3Turret::subMoveStepsPastIndex(int indexcount,int Extrasteps)
// Returns a 0 on success, 1 on user interrupt, ////2 on hit a limit.
// This moves past the given number of indexes, and then an additional
// number of steps.
// This is used when moving to a position.. you move past however
// many indexes are necessary to get to your new position, and then
// you move right up next to the next index without crossing it.
// Then you perform a MoveSlowToIndex to center on your target position.
// Most error checking (other moves in progress, mirror not down, etc) done
// in the higher level routines.
{
  switch (SubStep)
  {
  	// Begin motion
  	case 0:
    {
	    // Move enough steps to get to the next index
	    if (indexcount < 0)
		    movesteps = -MTMinIndexDistance;
	    else if (indexcount > 0)
		    movesteps = MTMinIndexDistance;
      else
      	movesteps = Extrasteps;
      // Forward motion
      if (movesteps > 0)
      {
		    Motion = MTMForward;
		    direction = 1;
		    SetDigBit(MTBitDir);
		    //limitbit = MTBitForward;
      }
      // Reverse motion
      else
      {
		    Motion = MTMReverse;
		    direction = -1;
		    ClrDigBit(MTBitDir);
		    //limitbit = MTBitReverse;
      }

	    // Check if we're initially on an index
	    if (Index)
		    indexflag = 1;
	    else
		    indexflag = 0;

      // Tell interrupt routine to start moving
      moveresult = -1;						// This will change on move completion
      tempresult = MTRSuccess;		// Return code for success
      abortmove = 0;							// Clear abort flag
      pulsecount = 1;
      profileindex = 0;
      indexleft = abs(indexcount);// Number of indexes to pass
      submove = MTSStepsPastIndex;// Tell interrupt what kind of motion we want
	    movesteps = abs(movesteps);	// Interrupt starts going when it sees
  													    	// movesteps != 0
      extrasteps = abs(Extrasteps);
      SubStep++;
    } break;
    // Check for move completion
    case 1:
    {
    	if (moveresult >= 0)
      {
      	Motion = MTMStop;
      	return(moveresult);
      }
    } break;
  };
  return(-1);	// Move not complete
}

/*
/////////////////////////////////////////////////////////////////////////////
// CM3Turret::CheckLimit - Check a limit, and debounce
int CM3Turret::CheckLimit(int limitbit)
// Returns a 0 on limit not hit, 1 on limit hit
// Debouncing was necessary because of noise in the limit signals during motion
{
  // Is forward limit triggered?
	if (!GetDigBit(MTBitForward))
  {
		if (FwdLimitCount < MTDebounceLimit)
	    FwdLimitCount++;
  }
  else
  {
  	// Did we kill some noise?
    if ((FwdLimitCount > 0) && (FwdLimitCount < MTDebounceLimit))
    	Log->Add("M3 Turret Forward Limit debounced",1);
  	FwdLimitCount = 0;
  }

	// Is reverse limit triggered?
	if (!GetDigBit(MTBitReverse))
  {
		if (RevLimitCount < MTDebounceLimit)
	    RevLimitCount++;
  }
  else
  {
  	// Did we kill some noise?
    if ((RevLimitCount > 0) && (RevLimitCount < MTDebounceLimit))
    	Log->Add("M3 Turret Reverse Limit debounced",1);
  	RevLimitCount = 0;
  }

  // Record limit status
	Limit = 2 * (RevLimitCount >= MTDebounceLimit) +
					FwdLimitCount >= MTDebounceLimit;

  // Report the limit bit of interest
  if ((limitbit == MTBitForward) && (FwdLimitCount >= MTDebounceLimit))
  	return(1);
  if ((limitbit == MTBitReverse) && (RevLimitCount >= MTDebounceLimit))
  	return(1);
  return(0);
}
*/

Generated by GNU Enscript 1.6.5.2.
Document Actions