Hello. This is a follow up on a previously posted question (http://www.c-sharpcorner.com/Forums/Thread/276805/). I've revised my code and despite it not throwing an exception any more, it doesn't seem to pick up the event. I don't have a lot of documentation on the api but what i'm trying to achieve is: have a form with a white label; after pressing a switch, the label should turn yellow. I've created an event and passed it to the GpioSetupInterruptPin function, configured to trigger on a rising edge.
As soon as i call GpioSetupInterruptPin, the event triggers and doesn't seem to reset. To me, this suggests there is a problem with the event, the waiting for the event or the api doesn't really work. I've managed to contact the developer of the api but he said others have successfully used the api, that he doesn't have experience using C# and offered no additional information on how to use the api or how it works.
Can someone please offer a suggestion on how i could fix my code?
public partial class Form1 : Form
{
// P/Invoke CreateEvent and WaitForSingleObjectprivate void GPIO_Open() //get handle for gpioprivate void GPIO_Output() //output pin declarationprivate void button1_Click(object sender, EventArgs e){
Interrupt_Setup();
}private void Interrupt_Setup(){
hGPIO = GPIOapi.GpioOpenHandle(); //returns a handle to the gpioGIPO_ON = true;Debug.WriteLine("Driver open \n" + hGPIO);GPIO_Output(); //set output pinsGPIO_Interrupt(Trigger); //configure interrupt
}private void GPIO_Interrupt(string trigger){
bool ok;_Main();//INTERRUPT DECALRATIONok = GPIOapi.GpioSetupInterruptPin(hGPIO, port6, 4, GPIOapi.INT_TRIGGER_MODE.TRIGGER_MODE_EDGE,GPIOapi.INT_TRIGGER_POLARITY.TRIGGER_POL_HIGH_RISING, trigger, true);if (!ok)
Debug.WriteLine("NO interrupt");
else
Debug.WriteLine("Interrupt set for:" + port6 + "04" + " at " + hGPIO);
}public static string Trigger = "InputProcessUpdateHandler";private static InputProcessor inputProcessor = null;private void _Main(){
public static IntPtr handle = CreateEvent(IntPtr.Zero, false, false, Trigger); //used P/Invoketry{
if (WaitForSingleObject(handle, 0xFFFFFFFF) == false)
label2.BackColor = Color.Red;
}catch(Exception e){Debug.WriteLine("exception: "+e);}
inputProcessor = new InputProcessor();ShowToggle showToggle = new ShowToggle(inputProcessor);inputProcessor.Process(label1);
}
}
public class ShowToggle
{
private InputProcessor _inputProcessor = null;public ShowToggle(InputProcessor inputProcessor){
_inputProcessor = inputProcessor;_inputProcessor.updateHandledBy += InputProcessUpdateHandler;
}private void InputProcessUpdateHandler(Label label){
label.BackColor = Color.Yellow;Debug.Write("execute");
}
}
public class InputProcessor
{
public delegate void InputProcessUpdateHandler(Label label);public event InputProcessUpdateHandler updateHandledBy = null;public void Process(Label label){
if (updateHandledBy != null)updateHandledBy(label);
}
}
VulpesPosted Dec 5, 2014, 5:42 AM
As it's difficult to do this when you can't run it, I apologize in advance if I've introduced any bugs.
You'll notice that I've moved the color selection stuff to the ShowToggle class which I felt was the best place for it to be:
Stefan CazacuPosted Dec 5, 2014, 10:11 AM
Stefan CazacuPosted Dec 5, 2014, 4:27 AM
VulpesPosted Dec 4, 2014, 10:13 AM
There's nothing wrong with infinite loops as long as you have a way to (eventually) get out of them which you appear to be lacking at present. One thing you could do is to have a 'stop' button to set a bool flag to true and for your while(true) loop to check the state of this flag and break when its true.
Stefan CazacuPosted Dec 4, 2014, 6:36 AM
The way I was expecting the code to work was for the WaitForTrigger() function to change the colour of label2 once the setup is complete and have the InputProcessUpdateHandler() function change the colour of label1 once an i/o is toggled. The code is largely the same, the only change being:
}
I can see how to get the functionality i want from this code but so many things seem wrong with it, I don't feel that i want to use it. I'm also a bit unclear on the event CloseHandle(). All the examples I've seen call it after the event has been triggered, but if i close the handle, how does the event trigger a second time?
VulpesPosted Dec 4, 2014, 6:06 AM
Stefan CazacuPosted Dec 4, 2014, 4:41 AM
Declaring the handle as public static was just an issue with the code i copied into the post (not sure what i did there). Thank you for the tip of calling WaitForSingleObject() after the call to GpioSetupInterruptPin().
Similarly, thank you to theLizard for the code sample.
I got the code working, however, i still have a few issues with it. I'm not really sure why it's working. It's not the event function that gets called when pressing the button, but whatever i call after WaitForSingleObject(). Also I've also used really messy coding and an infinite loop "while(1)"
Should I post the new code here, edit my original post or start a new thread?
theLizardPosted Nov 28, 2014, 7:51 PM
"the event triggers and doesn't seem to reset"
From looking at your code, the event is only ever triggered once and appears to be correct.
If you want the event to trigger @ x interval, you may want to consider using a thread object and in the execute() method
you may want to have somehing like
While(!Terminated)
{
if(WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
//do your work here. NOT SURE ABOUT THIS
//if this needs to be called each time, do it here.
//vulpes may now a bit more to help.
ok = GPIOapi.GpioSetupInterruptPin(hGPIO, port6, 4, GPIOapi.INT_TRIGGER_MODE.TRIGGER_MODE_EDGE,
GPIOapi.INT_TRIGGER_POLARITY.TRIGGER_POL_HIGH_RISING, trigger, true);
Synchronize(SetLabel);
ResetEvent(event);
}
}
SetLabel()
{
if(!ok)
form.label2.BackColor = Color.Red;
else
form.label2.BackColor = Color.Blue;
}
You may also need a timer to Do a SetEvent(event) @ say every second or whatever time interval you want on your main form.
NOTE: the code sample is C++,
VulpesPosted Nov 28, 2014, 11:54 AM