Tom.
It seems that setting/clearing bits for Enable in a watchdog loop is a common task. I understand that it is simple code. But, it would be nice to have configuration settings for this task. That would highlight the need for drive enables and documenting the feature would provide help on the topic.
I know it would have saved me a couple of hours.
I do not know where it would fit in the Configuration dialog
An interface like so would be nice:
Enable Action |None,Clear,Set| Bit [ ]
Where |..| represents a combobox drop down and [ ] is an edit box where the I/O bit would be entered.
Adding EnableAction and EnableBit to CHAN would give the settings a home.
Since I am a beginner with KFlop/KAnalog, I am probably missing some reason this is not a good idea.
Perhaps the code would take too long to execute in the main program loop?
I put together this example code. I have not tested it. It is just a quick attempt at the logic. There is probably something missing, a bug or a better way to achieve the same thing.
It is obviously more complex that anything a user would need to write in their watchdog loop.
I know it does not follow the other code naming conventions etc... old hobbits die hard.
Code:
#include "PC-DSP.h"
#include "KMotionDef.h"
// Or use enum
#define ENABLE_ACTION_NONE 0
#define ENABLE_ACTION_CLEAR 1
#define ENABLE_ACTION_SET 2
// It would be nice to have one of each of these in the CHAN structure
int EnableAction[N_CHANNELS]; // CHAN.EnableAction
int EnableBit[N_CHANNELS]; // CHAN.EnableBit
int prevEnable[N_CHANNELS];
BOOL prevEnableSet = FALSE;
void SetStateEnableBit(int nChan)
{
int i;
if (chan[nChan].Enable != prevEnable[nChan])
{
prevEnable[nChan] = chan[nChan].Enable;
if (EnableAction[nChan] != ENABLE_ACTION_NONE) // (chan[nChan].EnableAction != ENABLE_ACTION_NONE)
{
BOOL bTakeAction = TRUE;
int nAction = EnableAction[nChan]; // chan[nChan].EnableAction;
int nBit = EnableBit[nChan]; // chan[nChan].EnableBit;
if (chan[nChan].Enable) // When enabling we need to check if all axis with same settings (action, bit) are enabled. Disable always performs !Action
{
for (i = 0; i < N_CHANNELS; i++)
{
if ((i != nChan) && (EnableAction[i] == nAction) && (EnableBit[i] == nBit) && (!chan[i].Enable))
//((i != nChan) && (chan[i].EnableAction == nAction) && (chan[i].EnableBit == nBit) && (!chan[i].Enable))
{ // At least one Axis with same I/O Bit settings is not enabled yet - do not do anything
// This makes Action only take place when the last channel with the same shared settings is enabled
bTakeAction = FALSE;
break;
}
}
}
if (bTakeAction)
{
BOOL bState = (BOOL)(nAction - 1);
if (!chan[nChan].Enable) // disabling = !Action
bState = !bState;
SetStateBit(nBit, bState);
}
}
}
}
void CheckEnableBits()
{
int i = 0;
if (!prevEnableSet)
{
for (i = 0; i < N_CHANNELS; i++)
{
prevEnable[i] = -1;
// The below lines are temporary - the values would be set in the configuation code
EnableAction[i] = ENABLE_ACTION_SET;
EnableBit[i] = 152 + i;
}
prevEnableSet = TRUE;
}
for (i = 0; i < N_CHANNELS; i++)
{
SetStateEnableBit(i);
}
}
Just a thought