Driver.WatchFor input going HIGH/LOW
hidegh opened this issue · 0 comments
hidegh commented
From the "low-level" driver access what I miss is a way to get notification (event) when an input gets in HIGH or LOW state + a proper action (with connection property embedded into the events).
I know similar function is avail. in the bigger connection class, yet low-level access can be a nice to have.
The current Wait function can be used to simulate that, but the wait for HIGH has to be paired with wait for LOW and vice versa, otherwise the "event" will be repeated until button is released/pressed...
using System;
using Raspberry.IO.GeneralPurpose;
using System.Threading;
using System.Threading.Tasks;
namespace LibR3IO
{
/// <summary>
/// Based on: https://github.com/raspberry-sharp/raspberry-sharp-io/blob/638f67fc8466d53d60168f2e896e51d77ed6823b/Tests/Test.Gpio.WatchPin/Program.cs
/// </summary>
public class LowLevelCode
{
public void Run()
{
Console.WriteLine("Starting GPIO program (LO)...");
Console.WriteLine();
Console.WriteLine("Settings up for:");
Console.WriteLine("- mode l: " + Raspberry.Board.Current.Model.ToString());
Console.WriteLine("- connector pin out: " + GpioConnectionSettings.ConnectorPinout.ToString());
var useButtonWaitForLOW = true;
var ledGreenPP = (ProcessorPin)16;
var ledRedPP = (ProcessorPin)20;
var buttonRedPP = (ProcessorPin)27;
var driver = GpioConnectionSettings.DefaultDriver;
//
// Blinker
var blinkerCancellationTokenSource = new CancellationTokenSource();
var blinkerCancellationToken = blinkerCancellationTokenSource.Token;
var taskBlinker = new Task(
() =>
{
Console.WriteLine("Starting blinker");
var value = false;
do
{
value = !value;
driver.Write(ledGreenPP, value);
/*
var rv = driver.Read(ledGreenPP);
Console.WriteLine("Green led is: " + rv);
*/
Thread.Sleep(1000);
} while (!blinkerCancellationToken.IsCancellationRequested);
},
blinkerCancellationToken
);
//
// Button
var buttonWatcherCancellationTokenSource = new CancellationTokenSource();
var buttonWatcherCancellationToken = buttonWatcherCancellationTokenSource.Token;
var taskButtonWatcher = new Task(
() =>
{
Console.WriteLine("Starting button watcher");
var ledValue = false;
do
{
Console.WriteLine($"Button waiting for HIGH, current value is {driver.Read(buttonRedPP)}");
driver.Wait(buttonRedPP, true, TimeSpan.MaxValue);
ledValue = !ledValue;
Console.WriteLine($"Changing led to: {ledValue}");
driver.Write(ledRedPP, ledValue);
if (useButtonWaitForLOW)
{
Console.WriteLine($"Button waiting for LOW, current value is {driver.Read(buttonRedPP)}");
driver.Wait(buttonRedPP, false, TimeSpan.MaxValue);
}
} while (!buttonWatcherCancellationToken.IsCancellationRequested);
},
buttonWatcherCancellationToken
);
try
{
driver.Allocate(ledGreenPP, PinDirection.Output);
driver.Allocate(ledRedPP, PinDirection.Output);
driver.Allocate(buttonRedPP, PinDirection.Input);
taskBlinker.Start();
taskButtonWatcher.Start();
Console.WriteLine("Press ENTER to exit...");
Console.ReadLine();
}
finally
{
// Stop threads
blinkerCancellationTokenSource.Cancel();
buttonWatcherCancellationTokenSource.Cancel();
// If commented out, then it leaves the pin unreleased so that other processes can keep reading...
driver.Release(ledGreenPP);
driver.Release(ledRedPP);
driver.Release(buttonRedPP);
}
}
}
}