-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSample10StepperMotorClock.cs
More file actions
79 lines (66 loc) · 3.22 KB
/
Sample10StepperMotorClock.cs
File metadata and controls
79 lines (66 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Threading;
namespace AbstractIO.Samples
{
/// <summary>
/// A simple stepper-driven clock: Let a stepper turn some steps each minute.
/// For the mechanics, you can use any technical construction kit, such as fischertechnik.
/// </summary>
public static class Sample10StepperMotorClock
{
/// <summary>
/// Runs a mechanical clock by turning a stepper motor periodically.
/// </summary>
/// <param name="stepper">The stepper to drive.</param>
/// <param name="stepsPerMinute">The number of steps that the stepper shall perform each minute. This may be any
/// positive or negative non-null number and depends on the mechanical implementation of the actual clock.</param>
/// <param name="pauseBetweenStepsInMs">The number of milliseconds to wait between stepper steps. Set this
/// parameter depending on the mechanical implementation.</param>
public static void Run(IStepDrive stepper, int stepsPerMinute, int pauseBetweenStepsInMs)
{
if (stepper == null) throw new ArgumentNullException(nameof(stepper));
if (stepsPerMinute == 0) throw new ArgumentOutOfRangeException(nameof(stepsPerMinute));
// Variant 1: Sleep a minute, turn the stepper, sleep again:
// RunUsingSleep(stepper, stepsPerMinute, pauseBetweenStepsInMs);
// Variant 2: Use a timer fireing each minute:
RunUsingTimer(stepper, stepsPerMinute, pauseBetweenStepsInMs);
}
private static void RunUsingSleep(
IStepDrive stepper, int stepsPerMinute, int pauseBetweenStepsInMs)
{
// Save "now":
DateTime lastTime = DateTime.UtcNow;
while (true)
{
// Compute the next time at which the stepper must work:
// For demo purposes, you can use one step per second, for example:
// DateTime nextTime = lastTime.AddSeconds(1.0);
DateTime nextTime = lastTime.AddMinutes(1.0);
// Wait the correct time, avoiding cumulative errors:
Thread.Sleep((int)((nextTime - DateTime.UtcNow).Ticks / TimeSpan.TicksPerMillisecond));
// Let the stepper do its job to turn the clock:
stepper.MoveSteps(stepsPerMinute, pauseBetweenStepsInMs);
// Set this time as the base for the next period:
lastTime = nextTime;
// Let the stepper turn freely, save power, and make not even a silent noise caused by PWM:
stepper.ReleaseHoldingTorque();
}
}
private static void RunUsingTimer(
IStepDrive stepper, int stepsPerMinute, int pauseBetweenStepsInMs)
{
// Do steps each minute, that is, every 60000 milliseconds:
var timer = new Timer(
(state) =>
{
stepper.MoveSteps(stepsPerMinute, pauseBetweenStepsInMs);
stepper.ReleaseHoldingTorque();
},
null,
60000,
60000);
// Sleep and let the timer do its job:
for (; ; ) Thread.Sleep(1000);
}
}
}