I've somewhat recently noticed that, when I first run my C program, the Position and Destination displayed in the "Axes" tab in KMotion.exe jump from 0 to somewhat arbitrary values (sometimes 1, sometimes -1, sometimes 2). I've observed this now at least with version 5.4.0 and 5.4.1, though it may have been happening in earlier versions too. I assume that this is probably the fault of my own firmware, as I don't believe that I observe this behavior when running KMotion provided example programs. Could this be due to unaligned memory access, or have something to do with the way that I initialize my axes?
Here is a code snipped showing the function I use to initialize three of the axes which exhibit this behavior (they are used for my X, Y, Z motion stage, however, I do observe this behavior on my other axes as well).
Code: Select all
static void initialize_motion_stage_axis(motion_stage_axis_t *motion_stage_axis) {
const motion_stage_axis_config_t *config = motion_stage_axis->config;
motion_stage_axis_context_t *context = motion_stage_axis->context;
CHAN *const axis = config->axis;
BOOL use_negative_limit = FALSE;
BOOL use_positive_limit = FALSE;
int ret;
if (config->limit_switch_options->options.negative_limit_enable) {
ret = io_initialize(config->negative_limit_bit);
if (ret != 0) {
LOG_ERR("Failed to initialize Motion Stage Axis - Error initializing negative limit: %s", io_error_to_str[ret]);
return;
}
use_negative_limit = TRUE;
}
if (config->limit_switch_options->options.positive_limit_enable) {
ret = io_initialize(config->positive_limit_bit);
if (ret != 0) {
LOG_ERR("Failed to initialize Motion Stage Axis - Error initializing positive limit: %s", io_error_to_str[ret]);
return;
}
use_positive_limit = TRUE;
}
axis->InputMode = NO_INPUT_MODE;
axis->OutputMode = STEP_DIR_MODE;
axis->Vel = config->max_velocity;
axis->Accel = config->max_acceleration;
axis->Jerk = config->max_jerk;
axis->P = 0;
axis->I = 0;
axis->D = 0;
axis->FFAccel = 0;
axis->FFVel = 0;
axis->MaxI = 200;
axis->MaxErr = 1e+006;
axis->MaxOutput = 200;
axis->DeadBandGain = 1;
axis->DeadBandRange = 0;
axis->InputChan0 = 0;
axis->InputChan1 = 0;
axis->OutputChan0 = config->output_channel;
axis->OutputChan1 = 0;
axis->MasterAxis = -1;
if (use_negative_limit) {
axis->LimitSwitchNegBit = io_get_bit(config->negative_limit_bit);
} else {
axis->LimitSwitchNegBit = 0;
}
if (use_positive_limit) {
axis->LimitSwitchPosBit = io_get_bit(config->positive_limit_bit);
} else {
axis->LimitSwitchPosBit = 0;
}
axis->LimitSwitchOptions = config->limit_switch_options->as_int;
axis->SoftLimitPos = config->soft_limit_pos;
axis->SoftLimitNeg = config->soft_limit_neg;
axis->InputGain0 = 0;
axis->InputGain1 = 0;
axis->InputOffset0 = 0;
axis->InputOffset1 = 0;
axis->OutputGain = 1.0 - (2.0 * config->inverted);
axis->OutputOffset = 0;
axis->SlaveGain = 1;
axis->BacklashMode = BACKLASH_OFF;
axis->BacklashAmount = 0;
axis->BacklashRate = 0;
axis->invDistPerCycle = 1;
axis->Lead = 0;
axis->MaxFollowingError = 1000000000;
axis->StepperAmplitude = 255;
axis->iir[0].B0 = 0;
axis->iir[0].B1 = 0;
axis->iir[0].B2 = 0;
axis->iir[0].A1 = 0;
axis->iir[0].A2 = 0;
axis->iir[1].B0 = 0;
axis->iir[1].B1 = 0;
axis->iir[1].B2 = 0;
axis->iir[1].A1 = 0;
axis->iir[1].A2 = 0;
axis->iir[2].B0 = 0;
axis->iir[2].B1 = 0;
axis->iir[2].B2 = 0;
axis->iir[2].A1 = 0;
axis->iir[2].A2 = 0;
context->enabled = &axis->Enable;
context->position = &axis->Position;
context->destination = &axis->Dest;
context->oversample_idx = 0;
context->home_step = HOME_STEP_IDLE;
context->svc_prev_state = FALSE;
context->svc_state = FALSE;
context->svc_consec_on = 0;
context->svc_consec_off = 0;
context->initialized = TRUE;
}
Griffin Boyle