private void GotoPosition(int p, bool relaxAfterMove)
        {
            if (VerifyInitialized())
            {
                MovesCancelled = false;
                EasyStepperDriver.Direction dir = EasyStepperDriver.Direction.Forward;

                if (p > MaxPosition.Value)
                {
                    p = MaxPosition.Value;
                }

                if (p < MinPosition.Value)
                {
                    p = MinPosition.Value;
                }

                int positionDiff = p - CurrentPosition.Value;
                int stepsDiff    = Convert.ToInt32(Convert.ToDecimal(positionDiff) * StepsToPositionFactor);
                if (stepsDiff < 0)
                {
                    dir       = EasyStepperDriver.Direction.Backward;
                    stepsDiff = stepsDiff * -1;
                }

                if (stepsDiff != 0)
                {
                    State.StatusReason = OwlDeviceStateBase.StatusReasonTypes.ExecutingMove;

                    this.Driver.WakeUp();
                    this.Driver.EnableOutputs();
                    this.Driver.StepMode = EasyStepperDriver.Mode.Full;

                    this.Driver.StepDirection = dir;
                    Task.Run(async() => { await this.Driver.Turn(Convert.ToUInt32(stepsDiff), 1); }).Wait();

                    CurrentPosition = CurrentPosition.Value + positionDiff;

                    if (relaxAfterMove)
                    {
                        this.Driver.DisableOutputs();
                        this.Driver.Sleep();
                        State.StatusReason = OwlDeviceStateBase.StatusReasonTypes.Sleeping;
                    }
                    else
                    {
                        State.StatusReason = OwlDeviceStateBase.StatusReasonTypes.Awake;
                    }
                }

                FireMoveCompleted();
            }
            else
            {
                State.StatusReason = OwlDeviceStateBase.StatusReasonTypes.InError;
            }
        }
        public override void Recalibrate()
        {
            if (IsControlEnabled)
            {
                this.Status        = OwlDeviceStateBase.StatusTypes.Unavailable;
                State.StatusReason = OwlDeviceStateBase.StatusReasonTypes.Calibrating;
                CurrentPosition    = null;

                EasyStepperDriver.Direction directionForCalibration = EasyStepperDriver.Direction.Forward;
                //check the actual Gpio pins, not just the pin numbers.
                if (ForwardLimitSensorGpioPin == null && BackwardsLimitSensorGpioPin == null)
                {
                    //can't calibrate anything.  Disable me.
                    this.Status       = OwlDeviceStateBase.StatusTypes.InError;
                    this.StatusReason = OwlDeviceStateBase.StatusReasonTypes.InError;
                    this.FireDeviceError("Cannot calibrate.  No limit sensors found");
                }
                else
                {
                    //do we calibrate forwards or backwards or both?

                    bool isDirectLimitReachedAlready = false;
                    if (ForwardLimitSensorGpioPin != null)
                    {
                        if (IsForwardLimitReached().HasValue)
                        {
                            isDirectLimitReachedAlready = IsForwardLimitReached().Value;
                        }
                        else
                        {
                            //Expected to be able to
                            this.Status       = OwlDeviceStateBase.StatusTypes.InError;
                            this.StatusReason = OwlDeviceStateBase.StatusReasonTypes.InError;
                            this.FireDeviceError("Cannot calibrate.  Expected Forward limit sensor to return a non-null value.");
                        }
                    }
                    else if (BackwardsLimitSensorGpioPin != null)
                    {
                        directionForCalibration = EasyStepperDriver.Direction.Backward;
                        if (IsBackwardLimitReached().HasValue)
                        {
                            isDirectLimitReachedAlready = IsBackwardLimitReached().Value;
                        }
                        else
                        {
                            //Expected to be able to
                            this.Status       = OwlDeviceStateBase.StatusTypes.InError;
                            this.StatusReason = OwlDeviceStateBase.StatusReasonTypes.InError;
                            this.FireDeviceError("Cannot calibrate.  Expected Backwards limit sensor to return a non-null value (and there was no Forward limit sensor).");
                        }
                    }
                }
                if (this.Status != OwlDeviceStateBase.StatusTypes.InError)
                {
                    bool limitHit = false;
                    //Do the walk until we hit
                    limitHit = (directionForCalibration == EasyStepperDriver.Direction.Forward) ? IsForwardLimitReached().Value : IsBackwardLimitReached().Value;
                    int currentStep     = 0;
                    int stepToIncrement = 2;

                    this.Driver.WakeUp();
                    this.Driver.EnableOutputs();
                    this.Driver.StepMode = EasyStepperDriver.Mode.Full;

                    while (!limitHit && currentStep < StepsInRangeOfMotion)
                    {
                        //Step forward 2 steps

                        this.Driver.StepDirection = directionForCalibration;
                        Task.Run(async() => { await this.Driver.Turn(Convert.ToUInt32(stepToIncrement), 1); }).Wait();

                        currentStep += stepToIncrement;

                        //Task t = this.Driver.Turn(Convert.ToUInt32(stepsDiff), 1);
                        //t.Wait();

                        limitHit = (directionForCalibration == EasyStepperDriver.Direction.Forward) ? IsForwardLimitReached().Value : IsBackwardLimitReached().Value;
                    }
                    this.Driver.DisableOutputs();
                    this.Driver.Sleep();

                    if (limitHit)
                    {
                        //This sets the already-known scale.  It does not auto-scale yet
                        this.CurrentPosition = (directionForCalibration == EasyStepperDriver.Direction.Forward) ? 100 : 0;
                    }
                }


                //Do the limit test here.
                GotoPosition(0);

                GoHomePosition();
            }
            else
            {
                //not enabled
                this.Status          = OwlDeviceStateBase.StatusTypes.Unavailable;
                this.StatusReason    = OwlDeviceStateBase.StatusReasonTypes.Unknown;
                this.CurrentPosition = null;
            }
        }