mondinmr - 2025-05-13

Hi everyone,

I’m investigating a potential issue with a cyclic method we use for reading incremental encoders in our libraries.

I’ve come across two implementations that, at first glance, appear to perform the same operation:

motionUnit.vlPositionActualValue is UINT due strange encoder type.

Version A

METHOD PROTECTED cyclicReadField
VAR_INST
    actPosFieldOld: INT;
    rI: INT;
    delta: INT;
END_VAR
rI := TO_INT(motionUnit.vlPositionActualValue);
delta := rI - actPosFieldOld;
m_actPosRaw := m_actPosRaw + TO_LREAL(delta);

actPosFieldOld := rI;

IF settings.velocityFeebackMapped THEN
    m_actVelRaw := TO_LREAL(motionUnit.velocityActualValue);
END_IF

Version B

METHOD PROTECTED cyclicReadField
VAR_INST
    actPosFieldOld: INT;

END_VAR
m_actPosRaw := m_actPosRaw + TO_LREAL(TO_INT(motionUnit.vlPositionActualValue) - actPosFieldOld);
actPosFieldOld := TO_INT(motionUnit.vlPositionActualValue);

IF settings.velocityFeebackMapped THEN
  m_actVelRaw := TO_LREAL(motionUnit.velocityActualValue);
END_IF

Both use INT and the same delta logic, so they seem equivalent. However, when an overflow (wrap-around) occurs, version A continues correctly as expected, while version B unexpectedly resets to -32768 without a clear reason.

Has anyone experienced similar behavior or can shed light on what might be happening here?

It almost seems as if the cast to LREAL is being applied before the calculation β€” but that would be illogical and potentially very dangerous in many situations!

Thanks!

 

Last edit: mondinmr 2025-05-13