I am having a problem. The MPG wheel does not seem to be recognized in the program.
The bits for the switch positions all seem to work. I connected the MPG to hardware encoder channel 3 and after doing this:
ch1->InputChan0 = 3; // shows encoder count on Axis window using unused channel
I can see the MPG changing the Position field of channel 1 in the Axis window of Kmotion.
However, accessing the position member from within the program does not seem to work.
this operation:
Pos = chan[MPG_INPUT_AXIS].Position;
always yields zero, as far as I can tell.
I tried this:
Pos = ch1->Position;
with the same result.
I even printed all the channels to the console:
printf("0 %d\n",chan[0].Position);
printf("1 %d\n",chan[1].Position);
printf("2 %d\n",chan[2].Position);
printf("3 %d\n",chan[3].Position);
printf("4 %d\n",chan[4].Position);
printf("5 %d\n",chan[5].Position);
printf("6 %d\n",chan[6].Position);
printf("7 %d\n",chan[7].Position);
they all print zero, regardless of what I do to the MPG.
I am probably misunderstanding some channel mapping, as suggested here:
http://www.dynomotion.com/wiki/index.php?title=Channels_Channels_ChannelsI looked at the stucture definition of CHAN in kmotiondef.h, but that just confused me, because inside it,
// M A I N S T R U C T U R E T H A T D E F I N E S A N A X I S
typedef struct
{
int ChanNumber; // channel number 0-3
........
}CHAN;
so, CHAN defines a structure for an axis (as expected there are 8 of those in the array chan[]), and each axis has 4 channels (ChanNumber) of what exactly?
I am pasting the whole here, just in case:
#include "KMotionDef.h"
// Configure SnapAMP for 2 stepper motors in Optical Table Lathe
#define MPG_INPUT_AXIS 3
#define TAU 0.08 // smoothness factor (Low Pass Time constant seconds)
#define FINAL_TIME 1.0 // Set final dest after this amount of time with no change
#define ENABLE_MPG 92
#define SELECTX 93
#define SELECTZ 86
#define FACTOR1 88
#define FACTOR10 89
#define FACTOR100 90
int counter = 0;
void main()
{
WriteSnapAmp(SNAP0+SNAP_PEAK_CUR_LIMIT0,9); // current limit
WriteSnapAmp(SNAP0+SNAP_PEAK_CUR_LIMIT1,10); // current limit
Delay_sec(0.1); // wait for any fault to clear
ch1->InputChan0 = 3; // shows encoder count on Axis window using unused channel
ch2->InputChan0 = 10; // shows encoder count on Axis window using unused channel
ch3->InputChan0 = 11; // shows encoder count on Axis window using unused channel
ch4->InputMode=NO_INPUT_MODE;
ch4->OutputMode=MICROSTEP_MODE;
ch4->Vel=200.000000;
ch4->Accel=5000.000000;
ch4->Jerk=50000.000000;
ch4->P=1.000000;
ch4->I=0.000000;
ch4->D=0.000000;
ch4->FFAccel=0.000000;
ch4->FFVel=0.000000;
ch4->MaxI=200.000000;
ch4->MaxErr=1000000.000000;
ch4->MaxOutput=200.000000;
ch4->DeadBandGain=1.000000;
ch4->DeadBandRange=0.000000;
ch4->InputChan0=8;
ch4->InputChan1=9;
ch4->OutputChan0=8;
ch4->OutputChan1=9;
ch4->LimitSwitchOptions=0x0;
ch4->InputGain0=1.000000;
ch4->InputGain1=1.000000;
ch4->InputOffset0=0.000000;
ch4->InputOffset1=0.000000;
ch4->invDistPerCycle=1.000000;
ch4->Lead=0.000000;
ch4->MaxFollowingError=1000000000.000000;
ch4->StepperAmplitude=35.000000;
ch4->iir[0].B0=1.000000;
ch4->iir[0].B1=0.000000;
ch4->iir[0].B2=0.000000;
ch4->iir[0].A1=0.000000;
ch4->iir[0].A2=0.000000;
ch4->iir[1].B0=1.000000;
ch4->iir[1].B1=0.000000;
ch4->iir[1].B2=0.000000;
ch4->iir[1].A1=0.000000;
ch4->iir[1].A2=0.000000;
ch4->iir[2].B0=1.000000;
ch4->iir[2].B1=0.000000;
ch4->iir[2].B2=0.000000;
ch4->iir[2].A1=0.000000;
ch4->iir[2].A2=0.000000;
EnableAxisDest(4, 0.0);
ch5->InputMode=NO_INPUT_MODE;//ENCODER_MODE;
ch5->OutputMode=MICROSTEP_MODE;
ch5->Vel= 300;//20000.000000;
ch5->Accel=2000;//100000.000000;
ch5->Jerk= 20000;//2000000.000000;
ch5->P=1;//0.40000;
ch5->I=0;//.000300;
ch5->D=0;//.000000;
ch5->FFAccel=0.000000;
ch5->FFVel=0.000000;
ch5->MaxI=200.000000;
ch5->MaxErr=50.000000;
ch5->MaxOutput=1e10;//1000.000000;
ch5->DeadBandGain=0.0500000;
ch5->DeadBandRange=2.000000;
ch5->InputChan0=10; // 8 is snapamp0 ch0; 0 is kflop ch0 (JP7 pin7&8)
ch5->InputChan1=11;
ch5->OutputChan0=10;
ch5->OutputChan1=11;
ch5->LimitSwitchOptions=0x0;
ch5->InputGain0=1.000000;
ch5->InputGain1=1.000000;
ch5->InputOffset0=0.000000;
ch5->InputOffset1=0.000000;
ch5->invDistPerCycle=-1.000000;
ch5->Lead=0.000000;
ch5->MaxFollowingError=100.000000;
ch5->StepperAmplitude=50.000000;
ch5->iir[0].B0=1.000000;
ch5->iir[0].B1=0.000000;
ch5->iir[0].B2=0.000000;
ch5->iir[0].A1=0.000000;
ch5->iir[0].A2=0.000000;
ch5->iir[1].B0=1.000000;
ch5->iir[1].B1=0.000000;
ch5->iir[1].B2=0.000000;
ch5->iir[1].A1=0.000000;
ch5->iir[1].A2=0.000000;
ch5->iir[2].B0=1.0;//0.0566048;
ch5->iir[2].B1=0.0;//0.11321;
ch5->iir[2].B2=0.0;//0.0566048;
ch5->iir[2].A1=0.0;//1.22804;
ch5->iir[2].A2=0.0;//-0.454462;
DefineCoordSystem(4,-1,5,-1); //define ch4 as x and ch5 as y; z and a disabled
/*
DisableAxis(5);
ch5->Vel= 50000.000000;
ch5->Accel=2000000.000000;
ch5->Jerk= 4000000.000000;
//ch5->P=0.40000;
//ch5->I=0.000500;
//ch5->D=7.000000;
ch5->P=0.50000;
ch5->I=0.000000;
ch5->D=0.000000;
Write4PH(ch5,100,0); // energize a pole
Delay_sec(2); // wait
Zero(5);
ch5->InputMode=ENCODER_MODE;
ch5->OutputMode=BRUSHLESS_4PH_MODE;
//ch5->CommutationOffset = 0.25 * 20000/50 + 4; // offset ~1/4 of encoder count per pole
//ch5->invDistPerCycle= 1.0 * 50.0/20000.0; // 200 step stepper -> 50 poles; 5000 line encoder -> 20000 counts per revolution.
ch5->CommutationOffset = 0.25 * 16384/50 + 4; // offset ~1/4 of encoder count per pole
ch5->invDistPerCycle= 1.0 * 50.0/16384.0; // 200 step stepper -> 50 poles; 4096 line encoder -> 20000 counts per revolution.
*/
EnableAxisDest(5, 0.0);
Zero(5);
int Change1, NewPos, Pos;
int InMotion=FALSE,Axis,LastAxis=-1;
double LastChangeTime=0,Target,Factor=0;
Pos = ch1->Position;//chan[MPG_INPUT_AXIS].Position;
for (;;) // forever
{
counter++;
NewPos = ch1->Position;//chan[MPG_INPUT_AXIS].Position;
Change1 = NewPos - Pos;
Pos = NewPos;
if (1 == ReadBit(ENABLE_MPG)) // if rotary knob is on 'off' this bit is high
{
Change1 = 0;
if (counter > 1000)
{
counter = 0;
printf("e\n");
}
}
else if (ReadBit(FACTOR1)) // is X1 selected?
{
Change1 = 0;
if (counter > 1000)
{
counter = 0;
printf("2\n");
}
Factor = 2;
}
else if (ReadBit(FACTOR10)) // is X10 selected?
{
Change1 = 0;
if (counter > 1000)
{
counter = 0;
printf("20\n");
}
Factor = 20;
}
else if (ReadBit(FACTOR100)) // is X100 selected?
{
Change1 = 0;
if (counter > 1000)
{
counter = 0;
printf("200\n");
}
Factor = 200;
}
else
{
Change1 = 0;
if (counter > 1000)
{
counter = 0;
printf("0\n");
}
Factor = 0.0;
}
if (ReadBit(SELECTX)) // is x selected?
{
Axis=4;
}
else if (ReadBit(SELECTZ)) // is z selected?
{
Axis=5;
}
// check if the Axis just changed or we have been
// converging to the target for a long time
if (Axis != LastAxis ||(InMotion && Time_sec() > LastChangeTime+FINAL_TIME))
{
printf("0 %d\n",chan[0].Position);
printf("1 %d\n",ch1->Position);//chan[1].Position);
printf("2 %d\n",chan[2].Position);
printf("3 %d\n",chan[3].Position);
printf("4 %d\n",chan[4].Position);
printf("5 %d\n",chan[5].Position);
printf("6 %d\n",chan[6].Position);
printf("7 %d\n",chan[7].Position);
if (InMotion)
Move(LastAxis,Target); //finalize any motion
LastAxis = Axis;
InMotion = FALSE;
}
if (Change1) // did we move?
{
printf("if2\n");
if (!InMotion) Target = chan[Axis].Dest;
Target += Change1 * Factor;
MoveExp(Axis,Target,TAU); // note: contains a WaitNextTimeSlice
LastChangeTime = Time_sec();
InMotion=TRUE;
}
else
{
WaitNextTimeSlice();
}
}
}