Exemplo n.º 1
0
        /// <summary>
        /// Async method to step the motor multiple steps.
        /// </summary>
        /// <param name="steps">The number of steps to step the motor.</param>
        /// <param name="direction">A <see cref="Direction"/>.</param>
        /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
        /// <returns>The current step number.</returns>
        /// <remarks>
        /// The speed at which the steps will occur will be at the best effort to achieve the desired <see cref="SetSpeed(double)"/> speed.
        /// </remarks>
        internal async Task StepAsyncInternal(int steps, Direction direction, SteppingStyle stepStyle)
        {
            double s_per_s;
            int    lateststep = 0;

            var watch = System.Diagnostics.Stopwatch.StartNew();

            s_per_s = this._sec_per_step;
            if (stepStyle == SteppingStyle.Half)
            {
                s_per_s /= 2.0;
                steps   *= 2;
            }
            if (stepStyle == SteppingStyle.Microstep8)
            {
                s_per_s /= this._MICROSTEPS;
                steps   *= this._MICROSTEPS;
            }
            long ticksperstep = (long)(s_per_s * Stopwatch.Frequency);
            long nexttime     = 0;

            for (int s = 0; s < steps; s++)
            {
                lateststep = this.OneStep(direction, stepStyle);
                nexttime  += ticksperstep;
                await Task.Run(() =>
                {
                    while (watch.ElapsedTicks < ticksperstep)
                    {
                    }
                });
            }
            if (stepStyle == SteppingStyle.Microstep8)
            {
                // Always end in full step
                while ((lateststep != 0) && (lateststep != this._MICROSTEPS))
                {
                    lateststep = this.OneStep(direction, stepStyle);
                    nexttime  += ticksperstep;
                    await Task.Run(() =>
                    {
                        while (watch.ElapsedTicks < ticksperstep)
                        {
                        }
                    });
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Steps a specified number of steps, direction and stepping style.
        /// </summary>
        /// <param name="steps">The number of steps to process.</param>
        /// <param name="direction">A <see cref="Direction"/>.</param>
        /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
        /// <remarks>
        /// StepAsync cannot be called if the motor is already running.
        /// </remarks>
        public IAsyncAction StepAsync(int steps, Direction direction, SteppingStyle stepStyle)
        {
            if (_stepAsyncState == MotorState.Run)
            {
                throw new InvalidOperationException("Stepper motor is already running.");
            }

            cts        = new CancellationTokenSource();
            _stepStyle = stepStyle;
            WorkItemHandler loop = new WorkItemHandler((IAsyncAction) =>
                                                       motorThread(steps, direction, stepStyle, cts.Token)
                                                       );

            _runTask = ThreadPool.RunAsync(loop, WorkItemPriority.High);
            return(_runTask);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Steps a specified number of steps, direction and stepping style.
 /// </summary>
 /// <param name="steps">The number of steps to process.</param>
 /// <param name="direction">A <see cref="Direction"/>.</param>
 /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
 /// <remarks>
 /// .
 /// </remarks>
 public IAsyncAction StepAsync(int steps, Direction direction, SteppingStyle stepStyle)
 {
     return(StepAsyncInternal(steps, direction, stepStyle).AsAsyncAction());
 }
Exemplo n.º 4
0
        /// <summary>
        /// Steps the motor one step in the direction and style specified.
        /// </summary>
        /// <param name="direction">A <see cref="Direction"/>.</param>
        /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
        /// <returns>The current step number.</returns>
        /// <remarks>
        /// .
        /// </remarks>
        public int OneStep(Direction direction, SteppingStyle stepStyle)
        {
            double pwm_a, pwm_b;

            int[] coils;

            pwm_a = pwm_b = 1;

            // first determine what sort of stepping procedure we're up to
            if (stepStyle == SteppingStyle.Full)
            {
                if (((this._currentstep / (this._MICROSTEPS / 2)) % 2) == 0)
                {
                    // we're at an even step, weird
                    if (direction == Direction.Forward)
                    {
                        this._currentstep += this._MICROSTEPS / 2;
                    }
                    else
                    {
                        this._currentstep -= this._MICROSTEPS / 2;
                    }
                }
                else
                {
                    // go to next odd step
                    if (direction == Direction.Forward)
                    {
                        this._currentstep += this._MICROSTEPS;
                    }
                    else
                    {
                        this._currentstep -= this._MICROSTEPS;
                    }
                }
            }
            if (stepStyle == SteppingStyle.Wave)
            {
                if (((this._currentstep / (this._MICROSTEPS / 2)) % 2) == 1)
                {
                    // we're at an odd step, weird
                    if (direction == Direction.Forward)
                    {
                        this._currentstep += this._MICROSTEPS / 2;
                    }
                    else
                    {
                        this._currentstep -= this._MICROSTEPS / 2;
                    }
                }
                else
                {
                    // go to next even step
                    if (direction == Direction.Forward)
                    {
                        this._currentstep += this._MICROSTEPS;
                    }
                    else
                    {
                        this._currentstep -= this._MICROSTEPS;
                    }
                }
            }
            else if (stepStyle == SteppingStyle.Half)
            {
                if (direction == Direction.Forward)
                {
                    this._currentstep += this._MICROSTEPS / 2;
                }
                else
                {
                    this._currentstep -= this._MICROSTEPS / 2;
                }
            }
            else if (stepStyle == SteppingStyle.Microstep8)
            {
                if (direction == Direction.Forward)
                {
                    this._currentstep += 1;
                }
                else
                {
                    this._currentstep -= 1;
                }

                // go to next 'step' and wrap around
                this._currentstep += this._MICROSTEPS * 4;
                this._currentstep %= this._MICROSTEPS * 4;

                pwm_a = pwm_b = 0;
                if ((this._currentstep >= 0) && (this._currentstep < this._MICROSTEPS))
                {
                    pwm_a = this._MICROSTEP_CURVE[this._MICROSTEPS - this._currentstep];
                    pwm_b = this._MICROSTEP_CURVE[this._currentstep];
                }
                else if ((this._currentstep >= this._MICROSTEPS) && (this._currentstep < this._MICROSTEPS * 2))
                {
                    pwm_a = this._MICROSTEP_CURVE[this._currentstep - this._MICROSTEPS];
                    pwm_b = this._MICROSTEP_CURVE[this._MICROSTEPS * 2 - this._currentstep];
                }
                else if ((this._currentstep >= this._MICROSTEPS * 2) && (this._currentstep < this._MICROSTEPS * 3))
                {
                    pwm_a = this._MICROSTEP_CURVE[this._MICROSTEPS * 3 - this._currentstep];
                    pwm_b = this._MICROSTEP_CURVE[this._currentstep - this._MICROSTEPS * 2];
                }
                else if ((this._currentstep >= this._MICROSTEPS * 3) && (this._currentstep < this._MICROSTEPS * 4))
                {
                    pwm_a = this._MICROSTEP_CURVE[this._currentstep - this._MICROSTEPS * 3];
                    pwm_b = this._MICROSTEP_CURVE[this._MICROSTEPS * 4 - this._currentstep];
                }
            }

            // go to next 'step' and wrap around
            this._currentstep += this._MICROSTEPS * 4;
            this._currentstep %= this._MICROSTEPS * 4;

            // only really used for micro stepping, otherwise always on!
            this._PWMA.SetActiveDutyCyclePercentage(pwm_a * this.PowerFactor);
            this._PWMB.SetActiveDutyCyclePercentage(pwm_b * this.PowerFactor);

            // set up coil energizing!
            coils = new int[] { 0, 0, 0, 0 };

            if (stepStyle == SteppingStyle.Microstep8)
            {
                if ((this._currentstep >= 0) && (this._currentstep < this._MICROSTEPS))
                {
                    coils = new int[] { 1, 1, 0, 0 }
                }
                ;
                else if ((this._currentstep >= this._MICROSTEPS) && (this._currentstep < this._MICROSTEPS * 2))
                {
                    coils = new int[] { 0, 1, 1, 0 }
                }
                ;
                else if ((this._currentstep >= this._MICROSTEPS * 2) && (this._currentstep < this._MICROSTEPS * 3))
                {
                    coils = new int[] { 0, 0, 1, 1 }
                }
                ;
                else if ((this._currentstep >= this._MICROSTEPS * 3) && (this._currentstep < this._MICROSTEPS * 4))
                {
                    coils = new int[] { 1, 0, 0, 1 }
                }
                ;
            }
            else
            {
                int[][] step2coils = new int[][] {
                    new int[] { 1, 0, 0, 0 },
                    new int[] { 1, 1, 0, 0 },
                    new int[] { 0, 1, 0, 0 },
                    new int[] { 0, 1, 1, 0 },
                    new int[] { 0, 0, 1, 0 },
                    new int[] { 0, 0, 1, 1 },
                    new int[] { 0, 0, 0, 1 },
                    new int[] { 1, 0, 0, 1 }
                };
                coils = step2coils[this._currentstep / (this._MICROSTEPS / 2)];
            }

            // Turn on any coils that are off and need to be turned on
            for (int i = 0; i < 4; i++)
            {
                if ((coils[i] == 1) && (_currentcoils[i] == 0))
                {
                    _coilpins[i].SetActiveDutyCyclePercentage(1.0);
                }
            }

            // Turn off any coils that are on and need to be turned off
            for (int i = 0; i < 4; i++)
            {
                if ((coils[i] == 0) && (_currentcoils[i] == 1))
                {
                    _coilpins[i].SetActiveDutyCyclePercentage(0);
                }
            }

            //Debug.WriteLine("coils({0}, {1}, {2}, {3}) pwm({4}, {5})", coils[0], coils[1], coils[2], coils[3], pwm_a, pwm_b);
            _currentcoils = coils;
            return(this._currentstep);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Sets the stepping style for this stepper motor.
 /// </summary>
 /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
 public void SetStepStyle(SteppingStyle stepStyle)
 {
     _stepStyle = stepStyle;
 }
Exemplo n.º 6
0
        /// <summary>
        /// Async method to step the motor multiple steps.
        /// </summary>
        /// <param name="steps">The number of steps to step the motor.</param>
        /// <param name="direction">A <see cref="Direction"/>.</param>
        /// <param name="stepStyle">A <see cref="SteppingStyle"/>.</param>
        /// <param name="ct">A <see cref="CancellationToken"/>.</param>
        /// <returns>The current step number.</returns>
        /// <remarks>
        /// The speed at which the steps will occur will be at the best effort to achieve the desired <see cref="SetSpeed(double)"/> speed.
        /// </remarks>
        internal void motorThread(int steps, Direction direction, SteppingStyle stepStyle, CancellationToken ct)
        {
            _stepAsyncState = MotorState.Run;
            double s_per_s;
            int    _steps     = steps;
            int    lateststep = 0;

            var watch = System.Diagnostics.Stopwatch.StartNew();

            s_per_s = this._sec_per_step;
            if (stepStyle == SteppingStyle.Half)
            {
                s_per_s /= 2.0;
                _steps  *= 2;
            }
            if (stepStyle == SteppingStyle.Microstep8)
            {
                s_per_s /= this._MICROSTEPS;
                _steps  *= this._MICROSTEPS;
            }
            long ticksperstep = (long)(s_per_s * Stopwatch.Frequency);
            long nexttime     = 0;
            int  s            = 0;

            try
            {
                while ((s < _steps) || (steps == -1))
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }
                    lateststep = this.OneStep(direction, stepStyle);
                    if (_steps != -1)
                    {
                        s++;
                    }
                    nexttime += ticksperstep;
                    while (watch.ElapsedTicks < nexttime)
                    {
                        if (ct.IsCancellationRequested)
                        {
                            break;
                        }
                    }
                }
            }
            catch (TaskCanceledException)
            { }
            finally
            {
                if (stepStyle == SteppingStyle.Microstep8)
                {
                    // Always end in full step
                    while ((lateststep != 0) && (lateststep != this._MICROSTEPS))
                    {
                        lateststep = this.OneStep(direction, stepStyle);
                        nexttime  += ticksperstep;
                        while (watch.ElapsedTicks < nexttime)
                        {
                        }
                    }
                }
            }
            _stepAsyncState = MotorState.Brake;
        }