public static void Run(IObservableBooleanInput button, IBooleanOutput lamp) { // Check arguments: if (button == null) { throw new ArgumentNullException(nameof(button)); } if (lamp == null) { throw new ArgumentNullException(nameof(lamp)); } // Store the lamp so that the event handler can use it: _lamp = lamp; // Attach the event handler to the event that the button raises whenever it's Value changed: button.ValueChanged += ButtonValueChangedHandler; // Set the lamp to its initial state, as the event will raise not earlier than when the input changes: lamp.Value = button.Value; // Just wait and let the event handler react on button changes: for (; ;) { Thread.Sleep(1000); } }
/// <summary> /// Creates an <see cref="BooleanBlinkedWhenTrueOutput"/> object letting an boolean target output "blink" when and as /// // long as the input value is true. /// </summary> /// <param name="targetOutput">The output which shall "blink", that is, periodically turned to true and false, /// when and as long as the <see cref="Value"/> property is true.</param> /// <param name="onDurationMs">The number of milliseconds for the true-phase of the blinker.</param> /// <param name="offDurationMs">The number of milliseconds for the false-phase of the blinker.</param> /// <returns>The created input which will blink the <paramref name="targetOutput"/> when and as long as its /// <see cref="IBooleanInput.Value"/> property is true.</returns> public static BooleanBlinkedWhenTrueOutput BlinkedWhenTrue( this IBooleanOutput targetOutput, int onDurationMs, int offDurationMs) { return(new BooleanBlinkedWhenTrueOutput(targetOutput, onDurationMs, offDurationMs)); }
public static void Run(IBooleanInput button, IBooleanOutput motor) { // Multithreading is simple: Thread thread = new Thread(() => { while (true) { motor.Value = button.Value; System.Threading.Thread.Sleep(20); } }); thread.Start(); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="targetOutput">The output which shall "blink", that is, periodically turned to true and false, /// when and as long as the <see cref="Value"/> property is true.</param> /// <param name="onDurationMs">The number of milliseconds for the true-phase of the blinker.</param> /// <param name="offDurationMs">The number of milliseconds for the false-phase of the blinker.</param> public BooleanBlinkedWhenTrueOutput(IBooleanOutput targetOutput, int onDurationMs, int offDurationMs) { _targetOutput = targetOutput ?? throw new ArgumentNullException(nameof(targetOutput)); if (onDurationMs <= 0) { throw new ArgumentOutOfRangeException(nameof(onDurationMs)); } if (offDurationMs <= 0) { throw new ArgumentOutOfRangeException(nameof(offDurationMs)); } _onDurationMs = onDurationMs; _offDurationMs = offDurationMs; }
/// <summary> /// Blinks any <see cref="IBooleanOutput"/>. /// </summary> /// <param name="lamp">The output to "blink".</param> public static void Run(IBooleanOutput lamp) { // Check parameters: if (lamp == null) { throw new ArgumentNullException(nameof(lamp)); } // Blink the passed-in lamp. // Note that we do not need to know anything about the actual physical output used: while (true) { lamp.Value = !lamp.Value; Thread.Sleep(500); } }
public static void Run(IBooleanInput button, IBooleanOutput lamp) { // Check parameters: if (button == null) { throw new ArgumentNullException(nameof(button)); } if (lamp == null) { throw new ArgumentNullException(nameof(lamp)); } // Control the lamp by the button, using polling: while (true) { lamp.Value = button.Value; Thread.Sleep(100); // Only to give you a chance to redeploy usung firmware as of 2018-04-08. } }
/// <summary> /// Waits for a button to turn from false to true, then turns a lamp on, and after that turns the lamp on or off /// on every change of the button. /// </summary> /// <param name="button">The button to use.</param> /// <param name="lamp">The lamp to use.</param> public static void Run(IObservableBooleanInput button, IBooleanOutput lamp) { // Check parameters: if (button == null) { throw new ArgumentNullException(nameof(button)); } if (lamp == null) { throw new ArgumentNullException(nameof(lamp)); } // Wait for the button to turn from false to true (test this holding the button when the program starts!): button.WaitFor(true, true); lamp.Value = true; // Wait for the button to change to any value and set the lamp accordingly. while (true) { lamp.Value = button.WaitForChange(); } }
/// <summary> /// Creates a <see cref="BooleanMonitoredInput"/> which passes a copy of the read value of the source input to a /// tee target <see cref="IBooleanOutput"/> each time it gets read. /// </summary> /// <param name="sourceInput">The input to tee.</param> /// <param name="teeTarget">The output to receive the passed-through value of the /// <paramref name="sourceInput"/>.</param> /// <returns>The input which returns the <paramref name="sourceInput"/> value and at the same time sets the /// <paramref name="teeTarget"/> to that same value.</returns> public static BooleanMonitoredInput MonitoredTo(this IBooleanInput sourceInput, IBooleanOutput teeTarget) { return(new BooleanMonitoredInput(sourceInput, teeTarget)); }
/// <summary> /// Distributes an <see cref="IBooleanOutput"/> to another one in copy. /// </summary> /// <param name="targetOutput">The output whose value shall be passed to another output whenever it is set. /// </param> /// <param name="monitor">The other output, which shall receive whatever <paramref name="targetOutput"/> /// receives.</param> /// <returns>The created <see cref="BooleanOutputDistributor"/> object.</returns> /// <remarks>If you need multiple monitors, directly use the <see cref="BooleanOutputDistributor"/> class whose /// constructor accepts any number of <see cref="IBooleanOutput"/> objects.</remarks> public static BooleanOutputDistributor Distributed(this IBooleanOutput targetOutput, IBooleanOutput monitor) { return(new BooleanOutputDistributor(targetOutput, monitor)); }
/// <summary> /// Creates an <see cref="BooleanInvertedOutput"/> object. /// </summary> /// <param name="target">The output which shall receive the inverted Value of this object.</param> /// <returns>The <see cref="BooleanInvertedOutput"/> object sending inverted /// <see cref="IBooleanOutput">Values</see> to <paramref name="target"/>.</returns> public static IBooleanOutput Inverted(this IBooleanOutput target) { return(new BooleanInvertedOutput(target)); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="sourceInput">The input to tee.</param> /// <param name="teeTarget">The output to receive the passed-through value of the /// <paramref name="sourceInput"/>.</param> public BooleanMonitoredInput(IBooleanInput sourceInput, IBooleanOutput teeTarget) { this.SourceInput = sourceInput ?? throw new ArgumentNullException(nameof(sourceInput)); this.TeeTarget = teeTarget ?? throw new ArgumentNullException(nameof(teeTarget)); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="target">The ouput get the inverted Value of this object.</param> public BooleanInvertedOutput(IBooleanOutput target) { _target = target ?? throw new ArgumentNullException(nameof(target)); }
/// <summary> /// Runs a "Turmbergbahn" train, that is, 2 trains hanging on a single steel wire driven by a motor, running on /// the same rails using a "Abt'sche Weiche". /// </summary> /// <param name="trainMotor">The motor driving both trains at once. +1.0 is output for the direction so that /// train 1 drives upwards and train 2 drives downwards, -1.0 vice versa.</param> /// <param name="train1ReachedBottomStation">Signals true when train 1 reached the bottom station (and thus /// train 2 reached the top station).</param> /// <param name="train2ReachedBottomStation">Signals true when train 2 reached the bottom station (and thus /// train 1 reached the top station).</param> /// <param name="doorMotor">The motor driving all doors on both trains at once. +1.0 is output for opening, /// -1.0 for closing.</param> /// <param name="redLight">True shall light up a red traffic light when people shall not enter or leave the /// train.</param> /// <param name="greenLight">True shall light up a green traffic light when people may enter or leave the /// train.</param> /// <param name="waitForDoorsToMoveInMs">The time, in milliseconds, to wait for the /// <paramref name="doorMotor"/> to have operated all doors reliably.</param> /// <param name="waitWithOpenDoorsInMs">The time, in milliseconds, that the doors shall remain open.</param> /// <param name="waitAroundDoorOperationsInMs">The time, in milliseconds, to wait after the train stopped and /// before opening the door, and after the doors were closed again before the train starts.</param> public static void Run(ISingleOutput trainMotor, IBooleanInput train1ReachedBottomStation, IBooleanInput train2ReachedBottomStation, ISingleOutput doorMotor, IBooleanOutput redLight, IBooleanOutput greenLight, int waitForDoorsToMoveInMs, int waitWithOpenDoorsInMs, int waitAroundDoorOperationsInMs) { // Check arguments: if (trainMotor == null) { throw new ArgumentNullException(nameof(trainMotor)); } if (train1ReachedBottomStation == null) { throw new ArgumentNullException(nameof(train1ReachedBottomStation)); } if (train2ReachedBottomStation == null) { throw new ArgumentNullException(nameof(train2ReachedBottomStation)); } if (doorMotor == null) { throw new ArgumentNullException(nameof(doorMotor)); } if (redLight == null) { throw new ArgumentNullException(nameof(redLight)); } if (greenLight == null) { throw new ArgumentNullException(nameof(greenLight)); } if (waitForDoorsToMoveInMs < 0) { throw new ArgumentOutOfRangeException(nameof(waitForDoorsToMoveInMs)); } if (waitWithOpenDoorsInMs < 0) { throw new ArgumentOutOfRangeException(nameof(waitWithOpenDoorsInMs)); } if (waitAroundDoorOperationsInMs < 0) { throw new ArgumentOutOfRangeException(nameof(waitAroundDoorOperationsInMs)); } // Run the train: bool moveDirection = false; var trainReachedBottom = new BooleanOrInput(train1ReachedBottomStation, train2ReachedBottomStation); while (true) { // Initialize lamps: redLight.Value = true; greenLight.Value = false; // Move the train in the current direction until one of the end buttons is pressed: if (!(train1ReachedBottomStation.Value || train2ReachedBottomStation.Value)) { trainMotor.Value = moveDirection ? 1.0f : -1.0f; trainReachedBottom.WaitFor(value: true, edgeOnly: false); trainMotor.Value = 0.0f; } moveDirection = !moveDirection; // Wait a bit before opening the doors: Thread.Sleep(waitAroundDoorOperationsInMs); // Open the door: doorMotor.Value = 1.0f; Thread.Sleep(waitForDoorsToMoveInMs); doorMotor.Value = 0.0f; // Let people step in and out, wait a bit: redLight.Value = false; greenLight.Value = true; Thread.Sleep(waitWithOpenDoorsInMs); redLight.Value = true; greenLight.Value = false; // Close the door: doorMotor.Value = -1.0f; Thread.Sleep(waitForDoorsToMoveInMs); doorMotor.Value = 0.0f; // Wait a bit before the train starts again: Thread.Sleep(waitAroundDoorOperationsInMs); } }