Axis positions change to arbitrary values when I run my C program

Moderators: TomKerekes, dynomotion

Post Reply
griffinboyle
Posts: 15
Joined: Sun Apr 07, 2024 11:15 pm
Location: Boston

Axis positions change to arbitrary values when I run my C program

Post by griffinboyle » Wed Jan 28, 2026 1:02 pm

Hello,

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;
}
Thanks in advance,
Griffin Boyle

User avatar
TomKerekes
Posts: 2889
Joined: Mon Dec 04, 2017 1:49 am

Re: Axis positions change to arbitrary values when I run my C program

Post by TomKerekes » Thu Jan 29, 2026 1:55 am

Hi Griffin,

With Input Mode = NO_INPUT_MODE the Position should be ignored. On Power/Up Default the axes are in Encoder Input mode. The state of the associated quadrature bits may cause a count of 0, 1, -1, or 2. Switching to NO_INPUT_MODE will not automatically zero the position. In some modes Enabling the Axis will set the target Destination equal to the current Position in order to not move.

I don't see your code that sets the Position, Destination, or enables the Axis

So in summary:

Ignore the Position. If it annoys you then set the Position to zero after your axis is configured. with ch->Position=0;

When the axis is Enabled set the Destination to 0 (or some value) with EnableAxisDest(axis, 0);

HTH
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply