private void setEdgeDetection(byte pin, EdgeDetectionMode edge) { if (edge == EdgeDetectionMode.none) { // open file handle to gpio export var fd = FCntl.open("/sys/class/gpio/unexport", FCntl.O_WRONLY); if (fd < 0) { throw new IOException(string.Format("Failed to open gpio class - error {0}.", fd)); } // write pin number to export gpio pin // (don't check for errors because it raises if already unexported..) var buf = System.Text.UTF8Encoding.UTF8.GetBytes(pin.ToString() + Environment.NewLine); UniStd.write(fd, buf, Convert.ToUInt32(buf.Length)); FCntl.close(fd); } else { // open file handle to gpio export var fd = FCntl.open("/sys/class/gpio/export", FCntl.O_WRONLY); if (fd < 0) { throw new IOException(string.Format("Failed to open gpio class - error {0}.", fd)); } // write pin number to export gpio pin // (don't check for errors because it raises if already exported..) var buf = System.Text.UTF8Encoding.UTF8.GetBytes(pin.ToString() + Environment.NewLine); UniStd.write(fd, buf, Convert.ToUInt32(buf.Length)); FCntl.close(fd); // wait short delay for export to complete System.Threading.Thread.Sleep(50); // open file handle to gpio direction fd = FCntl.open(String.Format("/sys/class/gpio/gpio{0}/direction", pin), FCntl.O_WRONLY); if (fd < 0) { throw new IOException(string.Format("Failed to open gpio direction - error {0}.", fd)); } // write pin number to export gpio direction buf = System.Text.UTF8Encoding.UTF8.GetBytes("in" + Environment.NewLine); UniStd.write(fd, buf, Convert.ToUInt32(buf.Length)); FCntl.close(fd); // open file handle to gpio edge fd = FCntl.open(String.Format("/sys/class/gpio/gpio{0}/edge", pin), FCntl.O_WRONLY); if (fd < 0) { throw new IOException(string.Format("Failed to open gpio edge - error {0}.", fd)); } // write pin number to export gpio direction buf = System.Text.UTF8Encoding.UTF8.GetBytes(edge.ToString() + Environment.NewLine); UniStd.write(fd, buf, Convert.ToUInt32(buf.Length)); FCntl.close(fd); } }
public GpioEdgeDetector(byte pin, EdgeDetectionMode edge, int pollTimeout = 1000) { this.pin = pin; this.deviceName = String.Format("/sys/class/gpio/gpio{0}/value", pin); this.pollTimeout = pollTimeout; // enable edge detection setEdgeDetection(pin, edge); // open gpio file handle openEdgeDetectionFileHandle(); // start async polling task cancelTokenSource = new System.Threading.CancellationTokenSource(); pollParams p = new pollParams(); p.cancelToken = cancelTokenSource.Token; // TODO: Error Handling! Task.Factory.StartNew(new Action <Object>(pollInterrupt), p, cancelTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default). ContinueWith((t) => { Console.WriteLine(String.Format("GpioEdgeDetector Error: {0}", (t.Exception != null ? t.Exception.ToString() : String.Empty))); }, System.Threading.CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Current); }
/// <summary> /// Creates a new PiFace object using the default device name and registers an interrupt service routine on PiFace inputs. /// </summary> /// <param name="enableInputInterruptMask"> /// Byte mask for input pins to enable interrupt. /// </param> /// <param name="interruptGpioPin"> /// Raspberry Pi GPIO Pin which is connected to PiFace interrupt signaling pin (default 25). /// </param> /// <param name="edge"> /// <see cref="EdgeDetectionMode"/> (rising/falling/both) specifies which signal edge should be detected (default falling). /// </param> /// <remarks> /// Interrupt handling is only enabled if enableInputInterruptMask is > 0 and edge is not None. /// interruptGpioPin must be preconfigured as an input on Raspberry Pi GPIO. /// </remarks> public PiFaceDevice(byte enableInputInterruptMask, byte interruptGpioPin = 25, EdgeDetectionMode edge = EdgeDetectionMode.falling) : this() { if (enableInputInterruptMask > 0 && edge != EdgeDetectionMode.none) { InitializeEdgeDetection(enableInputInterruptMask); this.EdgeDetector = new GpioEdgeDetector(interruptGpioPin, edge); } }