Hi Don,
Here is a software example that should work. It is a bit complicated because it debounces the switches and is state driven. As you state you could also use a KFLOP Hardware Encoder Counter but that wouldn't do debouncing. It wouldn't ever loose count but might dither between positions when transitioning. It would of course use up an encoder input as well.
As shown in the example you must call ServiceQuadCount(); continuously and then the global variable quadcount will be the current position.
I've attached it as a txt file as well. Let me know if you have questions.
Regards
TK
Code:
#include "KMotionDef.h"
// Example counting quadrature transitions
#define QUADPHASEA 46
#define QUADPHASEB 47
// function prototypes for compiler
int Debounce(int n, int *cnt, int *last, int *lastsolid);
void ServiceQuadCount(void);
// state variables for switch debouncing
int alast=0,alastsolid=-1,acount=0;
int blast=0,blastsolid=-1,bcount=0;
int quadcount=0; // the counted position
main()
{
for (;;) // loop forever
{
WaitNextTimeSlice();
ServiceQuadCount();
// for testing put as Position 7 for viewing on Axis Screen
ch7->Position = quadcount;
}
}
void ServiceQuadCount(void)
{
int bita,bitb,resulta,resultb;
bita=ReadBit(QUADPHASEA); // Read Phases
bitb=ReadBit(QUADPHASEB);
// Debounce Phases and detect any transition
resulta = Debounce(bita,&acount,&alast,&alastsolid);
resultb = Debounce(bitb,&bcount,&blast,&blastsolid);
if (resulta != -1) // a transition?
{
// when moving forward phases are different after a transition
if (resulta != blastsolid) quadcount++;
else quadcount--;
}
if (resultb != -1) // b transition?
{
// when moving forward phases are same after b transition
if (resultb == alastsolid) quadcount++;
else quadcount--;
}
}
// Debounce a bit
//
// return 1 one time when first debounced high
// return 0 one time when first debounced low
// return -1 otherwise
#define DBTIME 300
int Debounce(int n, int *cnt, int *last, int *lastsolid)
{
int v = -1;
if (n == *last) // same as last time?
{
if (*cnt == DBTIME-1)
{
if (n != *lastsolid)
{
v = *lastsolid = n; // return debounced value
}
}
if (*cnt < DBTIME) (*cnt)++;
}
else
{
*cnt = 0; // reset count
}
*last = n;
return v;
}