就个人而言,我不认为在您的代码中添加延迟是解决问题的正确方法。如果您需要延迟以使某些 UWP(最好是 Windows 10 IOT 核心)应用程序正常运行,那么可能有一些方法可以更好地避免延迟,因为延迟不仅是不准确且不可靠的了解方式尤其是在物联网项目方面,这项工作已经完成。事情随时可能出错,操作可能需要更长的时间。在这种情况下,您的延迟中断并且您的物联网设置开始搞砸了。
话虽如此:
我写了一个课程,可以帮助你毫不拖延地控制你的步进电机,这是一件很快的事情,所以如果有任何问题,请告诉我,但我已经彻底测试过,我似乎没有发现任何问题功能或性能方面。我的代码如下:
public class Uln2003Driver : IDisposable
{
private readonly GpioPin[] _gpioPins = new GpioPin[4];
private readonly GpioPinValue[][] _waveDriveSequence =
{
new[] {GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High}
};
private readonly GpioPinValue[][] _fullStepSequence =
{
new[] {GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High},
new[] {GpioPinValue.High, GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.High, GpioPinValue.High, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High, GpioPinValue.High }
};
private readonly GpioPinValue[][] _haveStepSequence =
{
new[] {GpioPinValue.High, GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High},
new[] {GpioPinValue.Low, GpioPinValue.High, GpioPinValue.High, GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High, GpioPinValue.High, GpioPinValue.High, GpioPinValue.Low, GpioPinValue.Low},
new[] {GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.Low, GpioPinValue.High, GpioPinValue.High, GpioPinValue.High }
};
public Uln2003Driver(int blueWireToGpio, int pinkWireToGpio, int yellowWireToGpio, int orangeWireToGpio)
{
var gpio = GpioController.GetDefault();
_gpioPins[0] = gpio.OpenPin(blueWireToGpio);
_gpioPins[1] = gpio.OpenPin(pinkWireToGpio);
_gpioPins[2] = gpio.OpenPin(yellowWireToGpio);
_gpioPins[3] = gpio.OpenPin(orangeWireToGpio);
foreach (var gpioPin in _gpioPins)
{
gpioPin.Write(GpioPinValue.Low);
gpioPin.SetDriveMode(GpioPinDriveMode.Output);
}
}
public async Task TurnAsync(int degree, TurnDirection direction,
DrivingMethod drivingMethod = DrivingMethod.FullStep)
{
var steps = 0;
GpioPinValue[][] methodSequence;
switch (drivingMethod)
{
case DrivingMethod.WaveDrive:
methodSequence = _waveDriveSequence;
steps = (int) Math.Ceiling(degree/0.1767478397486253);
break;
case DrivingMethod.FullStep:
methodSequence = _fullStepSequence;
steps = (int) Math.Ceiling(degree/0.1767478397486253);
break;
case DrivingMethod.HalfStep:
methodSequence = _haveStepSequence;
steps = (int) Math.Ceiling(degree/0.0883739198743126);
break;
default:
throw new ArgumentOutOfRangeException(nameof(drivingMethod), drivingMethod, null);
}
var counter = 0;
while (counter < steps)
{
for (var j = 0; j < methodSequence[0].Length; j++)
{
for (var i = 0; i < 4; i++)
{
_gpioPins[i].Write(methodSequence[direction == TurnDirection.Left ? i : 3 - i][j]);
}
await Task.Delay(5);
counter ++;
if (counter == steps)
break;
}
}
Stop();
}
public void Stop()
{
foreach (var gpioPin in _gpioPins)
{
gpioPin.Write(GpioPinValue.Low);
}
}
public void Dispose()
{
foreach (var gpioPin in _gpioPins)
{
gpioPin.Write(GpioPinValue.Low);
gpioPin.Dispose();
}
}
}
public enum DrivingMethod
{
WaveDrive,
FullStep,
HalfStep
}
public enum TurnDirection
{
Left,
Right
}`
将其作为一个类,您可以从任何 CodeBehind 或 ViewModel 与它进行交互,如下所示:
private readonly Uln2003Driver _uln2003Driver; //The Declaration on top of the Class to make it global.
//In the constructor of the Page CodeBehind or ViewModel. The arguments are the GPIO pins to which your stepper is connected.
_uln2003Driver = new Uln2003Driver(26, 13, 6, 5);
现在你已经完成了设置,使用上面的如下:
Task.Run(async () =>
{
await _uln2003Driver.TurnAsync(180, TurnDirection.Left, DrivingMethod.FullStep);
await _uln2003Driver.TurnAsync(180, TurnDirection.Right, DrivingMethod.WaveDrive);
});
上面的代码只是顺时针和逆时针方向旋转,但可以随意调整,
注意:请记住在页面卸载或工作完成后致电_uln2003Driver?.Dispose(); 以释放资源。 ? 也是c#6.0 中可用的空条件运算符,我知道这很明显,但在另一个答案中遇到了类似的问题。
如果您有任何需要,请随时使用 cmets 部分