-
Notifications
You must be signed in to change notification settings - Fork 2
/
Netduino3SamplesMain.cs
590 lines (436 loc) · 29.6 KB
/
Netduino3SamplesMain.cs
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
// Please uncomment exactly one of the offered samples to run it:
//#define Sample01SimpleBlinker
//#define Sample01SimpleBlinkerDistributed
//#define Sample01SimpleBlinkerAlternating
//#define Sample02SmoothPwmBlinker
//#define Sample03ButtonControlsLampPolling
//#define Sample03ButtonControlsLampPollingInvertingButton
//#define Sample03ButtonControlsLampPollingInvertingLamp
//#define Sample03ButtonControlsLampUsing2ButtonsWithAnd
//#define Sample03ButtonControlsLampUsing2ButtonsWithOr
//#define Sample03ButtonControlsLampBlinking
//#define Sample03ButtonControlsLampBlinkingSmoothly
//#define Sample04ButtonControlsLampEventBased
//#define Sample04ButtonControlsLampEventBasedInvertingButton
//#define Sample04ButtonControlsLampEventBasedSmoothly
//#define Sample05ControlLampBrightnessThroughAnalogInput
//#define Sample05ControlLampBrightnessThroughAnalogInputScaled
//#define Sample05ControlLampBrightnessThroughAnalogInputScaledInverted
//#define Sample06WaitForButtonPolling
//#define Sample07WaitForButtonEventBased
//#define Sample02LetMotorRun
//#define Sample08LetManyMotorsRun
//#define Sample09SimpleStepperMotor
//#define Sample10StepperMotorClock
//#define Sample11SimpleTrainWithDoors
#define Sample12ClockWithContinuouslyControlledMotor
//#define Sample13SimplifiedDevelopment
using System;
using System.Diagnostics;
using System.Threading;
namespace AbstractIO.Netduino3.Samples
{
/// <summary>
/// This class runs the abstract samples in AbstractIO.Samples on a Netduino 3 board.
/// </summary>
public static class Netduino3SamplesMain
{
/// <summary>
/// Runs one of the abstract samples using physical ports of an Netduino 3 board.
/// </summary>
public static void Main()
{
// AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2 shield;
#if Sample01SimpleBlinker
// Sample 01: Blink a LED:
AbstractIO.Samples.Sample01SimpleBlinker.Run(
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample01SimpleBlinkerDistributed
// Sample 01 again, but this time blinking several LEDs at once simply by distributing the output to them
// using a BooleanOutputDistributor object, which on itself implements IBooleanOutput and simply passes the
// Values to an arbitrary number of outputs:
AbstractIO.Samples.Sample01SimpleBlinker.Run(
lamp: new BooleanOutputDistributor(
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort1Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort2Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort3Led)));
#elif Sample01SimpleBlinkerAlternating
// Sample 01 again, but this time blinking two LEDs alternating by using the BooleanOutputDistributor
// combined with inverting one of the outputs using the BooleanOutputInverter, coded using the fluent API
// that the corresponding extension method offers:
AbstractIO.Samples.Sample01SimpleBlinker.Run(
lamp: new BooleanOutputDistributor(
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort1Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort2Led).Inverted(),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort3Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue).Inverted()));
#elif Sample02SmoothPwmBlinker
// Sample 02: Let a lamp blink smoothly. The abstract code just expects any IDoubleOutput and will cyle that
// in small steps from 0.0 to 1.0 and back to 0.0 forever. As an example of an IDoubleOutput, we pass a
// PWM-controlled pin:
AbstractIO.Samples.Sample02SmoothBlinker.Run(
lamp: new Netduino3.AnalogPwmOutput(DigitalPwmOutputPin.OnboardLedBlue));
#elif Sample03ButtonControlsLampPolling
// Sample 03: Control a LED using a button:
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new Netduino3.DigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample03ButtonControlsLampPollingInvertingButton
// Sample 03 again, but this time inverting the button simply by using a BooleanInputConverter, simply by
// using the fluent API offered by the corresponding extension methods:
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new Netduino3.DigitalInput(DigitalInputPin.OnboardButton).Invert(),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample03ButtonControlsLampPollingInvertingLamp
// Sample 03 again, but this time inverting the lamp simply by using a BooleanOuputConverter, simply by
// using the fluent API offered by the corresponding extension methods:
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new Netduino3.DigitalInput(DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue).Inverted());
#elif Sample03ButtonControlsLampUsing2ButtonsWithAnd
// Sample 03 again, but this time the lamp shall only light up if both of two buttons are pressed.
// To use this sample, connect two closing buttons to the Netduino 3 input pins D0 and D1 with their other
// ports connected to VSS (+5V).
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new BooleanAndInput(
new Netduino3.DigitalInput(Netduino3.DigitalInputPin.D0),
new Netduino3.DigitalInput(Netduino3.DigitalInputPin.D1)),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample03ButtonControlsLampUsing2ButtonsWithOr
// Sample 03 again, but this time the lamp shall light up if one or both of two buttons are pressed.
// To use this sample, connect two closing buttons to the Netduino 3 input pins D0 and D1 with their other
// ports connected to VSS (+5V).
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new BooleanOrInput(
new Netduino3.DigitalInput(Netduino3.DigitalInputPin.D0),
new Netduino3.DigitalInput(Netduino3.DigitalInputPin.D1)),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample03ButtonControlsLampBlinking
// Sample 03 again, but this time we let the lamp blink simply by using the BlinkedWhenTrueOutput class,
// coded using the fluent API provided by extension methods:
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new Netduino3.DigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue)
.BlinkedWhenTrue(onDurationMs: 300, offDurationMs: 500));
#elif Sample03ButtonControlsLampBlinkingSmoothly
// Sample 03 again, but this time we let the lamp blink smoothly by using PWM and the SmoothedOutput class,
// coded using fluent API (even if the Run() method does nothing than simply turn the "output" on when the
// button is pressed). Read the definition of the lamp in reverse order:
// - Incoming is simply the boolean signal of the button.
// - This is made blink (BlinkedWhenTrue).
// - This, still boolean, value gets mapped to the double number 0.0 for false and 1.0 for true
// (MappedFromBoolean).
// - This signal, which switches between 0.0 and 1.0, is then smoothed to slowly enlight or dimm the lamp
// (Smoothed).
// - This, finally, is fed into the AnalogPwmOutput controlling the LED.
// So, using the fluent API for outputs is coded from back to front: Define the target output (here, the
// PWM-controlled LED, that is an IDoubleOutput), and apply transformations until you get an "I(type)Output"
// output where "(type)" matches the output type expected (here, an IBooleanOutput).
AbstractIO.Samples.Sample03ButtonControlsLampPolling.Run(
button: new Netduino3.DigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue)
.Smoothed(valueChangePerSecond: 1.0f, rampIntervalMs: 20)
.MappedFromBoolean(falseValue: 0.0f, trueValue: 1.0f)
.BlinkedWhenTrue(onDurationMs: 300, offDurationMs: 500));
#elif Sample04ButtonControlsLampEventBased
// Sample 04: Control a lamp using a button, but this time do not poll the status of the button, but react
// to the ValueChanged event (that is, reacting on an IRQ generated by the µC whenever the status of the
// button's input pin changed).
AbstractIO.Samples.Sample04ButtonControlsLampEventBased.Run(
button: new Netduino3.ObservableDigitalInput(DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample04ButtonControlsLampEventBasedInvertingButton
// Sample 04 again: Control a lamp using a button using events, but with an inverted button using the
// ObserverableBooleanInputInverter class, coded using the fluent API that the extension methods offer.
AbstractIO.Samples.Sample04ButtonControlsLampEventBased.Run(
button: new Netduino3.ObservableDigitalInput(DigitalInputPin.OnboardButton).Invert(),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample04ButtonControlsLampEventBasedSmoothly
// Sample 04 again, but let the LED blink smoothly just as in Sample03ButtonControlsLampBlinkingSmoothly.
// We do the very same here: Convert the IBooleanOutput of the event based method to the smoothly blinking
// IDoubleOutput for the PWM-controlled LED. It works all the same whether we use a polling IBooleanInput
// or the IRQ/event-based variant IObservableBooleanInput for the button. The output possibillities are just
// the same.
AbstractIO.Samples.Sample04ButtonControlsLampEventBased.Run(
button: new Netduino3.ObservableDigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue)
.Smoothed(valueChangePerSecond: 1.0f, rampIntervalMs: 20)
.MappedFromBoolean(falseValue: 0.0f, trueValue: 1.0f)
.BlinkedWhenTrue(onDurationMs: 300, offDurationMs: 500));
#elif Sample05ControlLampBrightnessThroughAnalogInput
// Sample 05: Let a LED light up just as bright (in the range from 0.0 to 1.0) as an analog input gives
// values (also in the range from 0.0 to 1.0). Note that the input range is not scaled in any way in this
// sample, but just goes straigt to the output. To run this sample, connect a variable resistor (such as a
// photo cell) between anlog input pin A0 and GND (0V). Then, the lamp will light darker as more light goes
// to the photo cell.
AbstractIO.Samples.Sample05ControlLampBrightnessThroughAnalogInput.Run(
input: new Netduino3.AnalogAdcInput(Netduino3.AnalogInputPin.A0),
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue));
#elif Sample05ControlLampBrightnessThroughAnalogInputScaled
// Sample 05 again, but this time auto-learn the actual incoming value range of the input and scale it to
// the range from 0.0 to 1.0 using the ScaleToRangeInput class, coded using the fluent API of the
// corresponding extension methods. This will cause the full range from 0.0 to 1.0 being used on the lamp,
// regardless if, for example, the incoming values range only from 0.3 to 0.6. To run this sample, connect a
// variable resistor (such as a photo cell) between anlog input pin A0 and GND (0V).
AbstractIO.Samples.Sample05ControlLampBrightnessThroughAnalogInput.Run(
input: new Netduino3.AnalogAdcInput(Netduino3.AnalogInputPin.A0)
.ScaleToRange(smallestValueMappedTo: 0.0f, largestValueMappedTo: 1.0f),
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue));
#elif Sample05ControlLampBrightnessThroughAnalogInputScaledInverted
// Sample 05 again, but this time the auto-learned ranged has swapped lower and upper limits. This results
// in the lamp going brighter when the analog input signal gets lower (that is, the photo cell getting more
// light, and vice versa. To run this sample, connect a variable resistor (such as a photo cell) between
// anlog input pin A0 and GND (0V).
AbstractIO.Samples.Sample05ControlLampBrightnessThroughAnalogInput.Run(
input: new Netduino3.AnalogAdcInput(Netduino3.AnalogInputPin.A0)
.ScaleToRange(smallestValueMappedTo: 1.0f, largestValueMappedTo: 0.0f),
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue));
#elif Sample06WaitForButtonPolling
// Sample 06: Wait for an input to reach a specific value, or to change, using the WaitFor() and
// WaitForChange() extension methods. In this sample, the button is used only as an IBooleanInput, so that
// waiting will cause polling. See sample 07 for the exact same code, just using the butten as an
// IObservableBooleanInput, working without polling.
AbstractIO.Samples.Sample06WaitForButtonPolling.Run(
button: new Netduino3.DigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample07WaitForButtonEventBased
// Sample 07: Nearly the same as sample 06, but using the button as an IObservableBooleanInput insted of
// a plain IBooleanInput. This allows the WaitFor() and WaitForChange() methods to use IRQ events instead of
// polling:
AbstractIO.Samples.Sample07WaitForButtonEventBased.Run(
button: new Netduino3.ObservableDigitalInput(Netduino3.DigitalInputPin.OnboardButton),
lamp: new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.OnboardLedBlue));
#elif Sample02LetMotorRun
// Connect to the Adafruit V2 shield at its default address:
shield = new AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2();
// Use the sample controlling a lamp just control a motor, as both implement IDoubleOutput:
AbstractIO.Samples.Sample02SmoothBlinker.Run(
lamp: shield.GetDcMotor(1));
#elif Sample08LetManyMotorsRun
// Control as many motors you whish on as many motor shields you whish simultaneously:
// Let a lamp blink smoothly on a separate thread as a means to see how smooth all these operations can be
// handled by the board:
Thread blinkThread = new Thread(
() => AbstractIO.Samples.Sample02SmoothBlinker.Run(
lamp: new Netduino3.AnalogPwmOutput(Netduino3.DigitalPwmOutputPin.OnboardLedBlue)));
blinkThread.Start();
// Run the sample, using as many motors as you like:
// As additional ideas, suppose that:
// - All motors can run on 9V, but one only on 6V. So we scale this motor's output by 6/9.
// - One DC motor has its pins swapped and needs output in reverse polarity. So scale by a factor of -1.
// Note that the Run() method does not know nor needs to know about this facts about the actual motors, and
// that all we need to do is to pass scaled outputs using the fluent API to the Run() method.
//
// We pass 3 onboard LEDs to display the number of motors which are (still) accelerating or decelerating
// as numbers 0, 1, 2 or greater than 2.
//
// We let the Run() method run on its own thread because blocking the main thread by waiting for
// ManualResetEvents (as is done while the Run() method waits) would block the whole OS (as of 2018-05-05).
var shield1 = new AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2(96);
var shield2 = new AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2(97);
var shield3 = new AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2(98);
var shield4 = new AbstractIO.AdafruitMotorShieldV2.AdafruitMotorShieldV2(99);
Thread runner = new Thread(() =>
AbstractIO.Samples.Sample08SmoothManyAnalogOutputs.Run(
new IBooleanOutput[] {
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort1Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort2Led),
new Netduino3.DigitalOutput(Netduino3.DigitalOutputPin.GoPort3Led)
},
shield1.GetDcMotor(1),
shield1.GetDcMotor(2),
shield1.GetDcMotor(3),
shield1.GetDcMotor(4),
shield2.GetDcMotor(1),
shield2.GetDcMotor(2),
shield2.GetDcMotor(3),
shield2.GetDcMotor(4),
shield3.GetDcMotor(1).Scaled(factor: 6.0f / 9.0f),
shield3.GetDcMotor(2),
shield3.GetDcMotor(3),
shield3.GetDcMotor(4),
shield4.GetDcMotor(1).Scaled(factor: -1.0f),
shield4.GetDcMotor(2),
shield4.GetDcMotor(3),
shield4.GetDcMotor(4)));
runner.Start();
for (; ; ) { Thread.Sleep(10); }
#elif Sample09SimpleStepperMotor
// Let a stepper motor turn randomly:
shield = new AdafruitMotorShieldV2.AdafruitMotorShieldV2();
//new Thread(() =>
// AbstractIO.Samples.Sample09SimpleStepperMotor.Run(shield.GetStepperMotor(1, 2, 8)))
// .Start();
const float scale = 0.4f;
new Thread(() =>
AbstractIO.Samples.Sample09SimpleStepperMotor.Run(
new StepperMotor(shield.GetDcMotor(1).Scaled(scale), shield.GetDcMotor(2).Scaled(scale), 8)))
.Start();
for (; ; )
{
Thread.Sleep(10);
}
#elif Sample10StepperMotorClock
// Let a simple clock run by turning a stepper motor a given number of steps every minute:
shield = new AdafruitMotorShieldV2.AdafruitMotorShieldV2(97);
const float clockScale = 0.2f;
new Thread(() =>
AbstractIO.Samples.Sample10StepperMotorClock.Run(
stepper: new StepperMotor(phase1Output: shield.GetDcMotor(1).Scaled(clockScale),
phase2Output: shield.GetDcMotor(2).Scaled(clockScale),
stepsPerStepCycle: 4),
stepsPerMinute: 4,
pauseBetweenStepsInMs: 50))
.Start();
for (; ; )
{
Thread.Sleep(10);
}
#elif Sample11SimpleTrainWithDoors
// Let a train run:
shield = new AdafruitMotorShieldV2.AdafruitMotorShieldV2(97);
AbstractIO.Samples.Sample11SimpleTrainWithDoors.Run(
trainMotor: shield.GetDcMotor(1).Smoothed(valueChangePerSecond: 2.0f, rampIntervalMs: 20),
trainReachedBottomStation: new BooleanOrInput(new Netduino3.DigitalInput(DigitalInputPin.D0),
new Netduino3.DigitalInput(DigitalInputPin.D1)),
doorMotor: shield.GetDcMotor(2),
waitForDoorsToMoveInMs: 1000,
waitWithOpenDoorsInMs: 3000,
waitAroundDoorOperationsInMs: 1000);
#elif Sample12ClockWithContinuouslyControlledMotor
// Let a clock run that is driven by a simple DC motor (no stepper) and which has a digital input that gives
// a specific number of "1" pulses for a turn of a specific axis of the clock's gear.
// The motor is a simple DC motor. As its pins are swapped in the fischertechnik model currently, we use
// the .Scaled() extension to turn its direction by a factor of -1.
// The pulse switch is a contact customly built out of fischertechnik parts directly on a very small
// metallic worm gear. Note that its value is not only fed into the model code, but also tee-like output to
// a monitor LED.
// The seconds lamp is driven independently of all this. The model code just has a timer changing a boolean
// output each time it fires. To have the effect of a lamp going smoothly on and of, we use the
// .Smoothed() extension method to smooth the boolean value from the timer code into a nice looking LED
// pattern.
// The ideal seconds per pulse are calculated for a miniaturized fischertechnik clock with the following
// gear:
// Motor worm => Z14 and worm => Z14 and worm (here pulses are detected) => Z14 and worm => Z22 and minutes.
// So the relation of pulse detection to minutes is 1/14/22 and thus the turnaround time of the detecting
// worm is 3600 s / 14 / 22 ≈ 11,69 seconds (rounded).
var shield = new AdafruitMotorShieldV2.AdafruitMotorShieldV2();
// Let a lamp blink in one-second-intervals:
// Start a blinking seconds lamp calmly going on in one second and off again in the next:
var secondsLamp = new Netduino3.AnalogPwmOutput(DigitalPwmOutputPin.OnboardLedBlue)
.Scaled(quadraticCoefficient: 1f, factor: 0f, offset: 0f)
.Smoothed(valueChangePerSecond: 1f, rampIntervalMs: 20)
.MappedFromBoolean(falseValue: 0f, trueValue: 1f);
var secondsTimer = new System.Threading.Timer(
(state) => { secondsLamp.Value = !secondsLamp.Value; },
null, 0, 1000);
// Run the clock:
AbstractIO.Samples.Sample12ClockWithContinuouslyControlledMotor.Run(
motor: shield.GetDcMotor(3)
.Scaled(factor: -1f), // If pins are reversed in the model, negate speed.
minimumMotorSpeed: 0.08f,
initialSpeedGuess: 0.11f,
pulse: (new Netduino3.DigitalInput(DigitalInputPin.D2))
.MonitoredTo(teeTarget: new Netduino3.DigitalOutput(DigitalOutputPin.GoPort3Led)),
idealSecondsPerCycle: 3600f / (22f * 14f),
runAtFullSpeedSwitch: new DigitalInput(DigitalInputPin.OnboardButton));
#elif Sample13SimplifiedDevelopment
// The most primitive program ever: Let a motor run when a button is pressed.
shield = new AdafruitMotorShieldV2.AdafruitMotorShieldV2(address: 97);
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.DigitalInput(DigitalInputPin.D2), // Monitor a digital input pin
// motor: shield.GetDcMotor(1) // Create a motor output
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f) // Map a boolean to a float
// );
// Let the motor turn on and off smoothly!
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.DigitalInput(DigitalInputPin.D2),
// motor: shield.GetDcMotor(1)
// .Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20) // Smooth the float value
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// );
// Let a lamp monitor when the motor is on or off:
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.DigitalInput(DigitalInputPin.D2),
// motor: shield.GetDcMotor(1)
// .Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .Distributed( // Distribute output to another one
// shield.GetDcMotor(2) // A lamp output
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)) // Mapped from boolean
// );
// Let the lamp blink instead of only light up:
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.DigitalInput(DigitalInputPin.D2),
// motor: shield.GetDcMotor(1)
// .Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .Distributed(
// shield.GetDcMotor(2)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .BlinkedWhenTrue(onDurationMs: 500, offDurationMs: 500)) // Blink as long as pressed
// );
// Let the lamp blink smoothly:
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.DigitalInput(DigitalInputPin.D2),
// motor: shield.GetDcMotor(1)
// .Smoothed(valueChangePerSecond: 0.5f, rampIntervalMs: 20)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .Distributed(
// shield.GetDcMotor(2)
// .Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20) // Smooth the blinking lamp
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .BlinkedWhenTrue(onDurationMs: 500, offDurationMs: 500))
//);
// Replace the lamp with an analog photocell, auto-learning its value range:
//AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
// button: new Netduino3.AnalogAdcInput(AnalogInputPin.A1) // An analog input
// .ScaleToRange(smallestValueMappedTo: 0f, largestValueMappedTo: 1f) // auto-learning its range
// .SchmittTrigger(threshold: 0.5f, hysteresis: 0.05f), // converted too boolean
// motor: shield.GetDcMotor(1)
// .Smoothed(valueChangePerSecond: 0.5f, rampIntervalMs: 20)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .Distributed(
// shield.GetDcMotor(2)
// .Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20)
// .MappedFromBoolean(falseValue: 0f, trueValue: 1f)
// .BlinkedWhenTrue(onDurationMs: 500, offDurationMs: 500))
// );
// Invert the behavior of the light barrier:
AbstractIO.Samples.Sample13SimplifiedDevelopment.Run(
button: new Netduino3.AnalogAdcInput(AnalogInputPin.A1)
.ScaleToRange(smallestValueMappedTo: 0f, largestValueMappedTo: 1f)
.SchmittTrigger(threshold: 0.5f, hysteresis: 0.05f)
.Invert(), // Invert the light barrier
motor: shield.GetDcMotor(1)
.Smoothed(valueChangePerSecond: 0.5f, rampIntervalMs: 20)
.MappedFromBoolean(falseValue: 0f, trueValue: 1f)
.Distributed(
shield.GetDcMotor(2)
.Smoothed(valueChangePerSecond: 2f, rampIntervalMs: 20)
.MappedFromBoolean(falseValue: 0f, trueValue: 1f)
.BlinkedWhenTrue(onDurationMs: 500, offDurationMs: 500))
);
// Run forever:
Thread.Sleep(Timeout.Infinite);
#else
//#error Please uncomment exactly one of the samples.
var startTime = DateTime.UtcNow;
int periods = 0;
var timer = new Timer(
(state) =>
{
periods++;
double s = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
double p = periods;
Debug.WriteLine(p.ToString() + " | " + s.ToString() + " | " + ((p - s) / s).ToString());
},
null,
1000,
1000);
System.Threading.Thread.Sleep(Timeout.Infinite);
#endif
}
}
}