EDIT: post might be in wrong subforum.
TLDR: WiringPi wrapper for .NET Interrupt functionality blocks program from exiting, until next interrupt is received. My sample program below. Any advice?
Long story:
I'm just starting to tinker with my RPi2 gpio's and simple components, just want to learn a little bit about electronics, self taught. I have some background in programming.
I'm using C#, I just think C# is elegant, powerful and time saving. Also code in C# can be easily readable if written well.
I'm just playing around with some components, like LED's, buttons and PCF8574N IO Extender chip, as for my next milestone I'll try to connect 16x2 LCD module.
Right now I'm trying to control LED programmically via I2C interface (using IO Extender), and get input from pushbutton using GPIO Interrupt. On C# side I am using WiringPi wrapper called WiringPi.NET https://github.com/danriches/WiringPi.Net.
My program seems to work, I get blinking LED when pressing pushbutton. Interrupt handler is firing, but right now my program does not terminate if interrupt handler was launched at least once. After pressing Ctrl+C I execution seems to fall off main function, but it never realy returns to command line. I have to press Ctrl+Z and then kill -9 it.
EDIT: it does exit if i press pushbutton once again. I'm not really sure if this is a bug in wiringPi itself?
What could be happening here? For me it looks like thread running interrupt handler is never finishing. Any ideas are welcome.
My code of main Program.cs file, may be it's just some silly mistake here:
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using WiringPi;
namespace i2ctest
{
class Program
{
static int hpcf1; // IO Expander 1 handle
static int icount = 0;
static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
// Init Gpio
int ret = Init.WiringPiSetupGpio();
if (ret == -1)
{
Console.WriteLine("Error initializing GPIO");
return;
}
// Get btn pin
int wPinBtn = 2;
int gPinBtn = MiscFunctions.wpiPinToGpio(wPinBtn);
// Set pin modes
GPIO.pinMode(gPinBtn, (int)GPIO.GPIOpinmode.Input);
// Activate pullDown resistor
GPIO.pullUpDnControl(gPinBtn, (int)GPIO.PullUpDnValue.Down);
// Console Ctrl-C break handler
Console.CancelKeyPress += (sender, eArgs) => {
Console.WriteLine("Exitting gracefuly");
eArgs.Cancel = true;
manualResetEvent.Set();
};
//
// IC2 Init
int pcf8574 = 0x20;
hpcf1 = I2C.wiringPiI2CSetup(pcf8574);
if (hpcf1 == -1)
{
Console.WriteLine("Error connecting to I2C device at 0x{0:X}", pcf8574);
return;
}
else
{
Console.WriteLine("I2C device at 0x{0:X} is Open", pcf8574);
BlinkLed(hpcf1);
}
PiThreadInterrupts.wiringPiISR(gPinBtn, (int)PiThreadInterrupts.InterruptLevels.INT_EDGE_RISING, Button1Down);
Console.WriteLine("Waiting for interrupts...");
manualResetEvent.WaitOne();
Environment.Exit(Environment.ExitCode);
}
public static void Button1Down()
{
Console.WriteLine("{0}. Interrupted", ++icount);
BlinkLed(hpcf1);
}
public static readonly int ledOn = 0xFE;
public static readonly int ledOff = 0xFF;
private static void BlinkLed(int ahandle)
{
for (int i = 0; i < 10; i++)
{
I2C.wiringPiI2CWrite(ahandle, ledOn);
Thread.Sleep(100);
I2C.wiringPiI2CWrite(ahandle, ledOff);
Thread.Sleep(100);
}
}
}
}
Just hope it makes some sense to someone here.