We have implemented interrupt handling for our limit switches, reset operations, autonomous goodies using GPIO and the DigitialInput class. Points to note to save you from our madness, the DIO sig pins are pulled high, therefore you switch them low to get response (then high again to get toggle). You will get switch bounce as the contacts come together and separate. You need to program against that. You also need to set the leading or trailing edge of the pulse correctly (the default is the wrong way round by my estimation in the DigitalInput interrupt handler), since the initial setup is to transition to 0v, you should only interrupt on the trailing pulse edge. If not, you will get an interrupt for the press and another for the release of the switch - unless you are interested in that granularity of course.
Good luck. I'll paste some code here to help.
Tony
1711
Raptors
Code:
#include "WPILib.h"
#include "Reset.h"
// Victor crab drive definitions
Victor *vicCrabFront;
Victor *vicCrabRear;
#define CRABRESETTIMEOUT 20 // reset timeout in seconds for crab drive
bool frontLimit;
bool rearLimit;
// front crab limit switch interrupt handler (handles both left and right switches)
static void hdlrCrabFrontLimit(tNIRIO_u32 interruptAssertedMask, void *param) {
// only process if not already set (eliminates switch bounce)
if(frontLimit==false){
frontLimit=true;
// hit limit switch, turn the other way
if(vicCrabFront->Get()>0) {
cout<<"Front right limit fired"<<endl;
vicCrabFront->Set(-1);
} else {
cout<<"Front left limit fired"<<endl;
vicCrabFront->Set(1);
}
} else
frontLimit=false;
}
Reset::Reset () {
DigitalInput swCrabFrontRightLimit(4);
DigitalInput swCrabFrontLeftLimit(5);
Timer timer;
// create the crab Victor objects
vicCrabFront=new Victor(7);
vicCrabRear=new Victor(8);
// adjust interrupts to fire on trailing edge (5>0v) transitions.
swCrabFrontRightLimit.SetUpSourceEdge(false,true);
swCrabFrontLeftLimit.SetUpSourceEdge(false,true);
// enable limit switch interrupts (1 routine handles left and right limits)
swCrabFrontRightLimit.RequestInterrupts(hdlrCrabFrontLimit);
swCrabFrontRightLimit.EnableInterrupts();
swCrabFrontLeftLimit.RequestInterrupts(hdlrCrabFrontLimit);
swCrabFrontLeftLimit.EnableInterrupts();
// ensure all limit switches are off to start
frontLimit=false;
// zero front crab drive if not already in position
cout<<"Waiting "<<CRABRESETTIMEOUT<<" seconds for front reset"<<endl;
vicCrabFront->Set(1);
if(swCrabFrontZero.Get()==false) {
timer.Reset();
timer.Start();
// move crab front drive to right looking for 0 point
vicCrabFront->Set(1);
// hold for CRABRESETTIMEOUT seconds waiting for the crab to find zero
while(timer.Get()<CRABRESETTIMEOUT&&swCrabFrontZero.Get()==false) ;
vicCrabFront->Set(0);
// display error if we cannot zero the crab (timed out)
if(swCrabFrontZero.Get()==false) {
cout<<"Cannot zero front crab drive"<<endl;
return;
}
}
}