Table of Contents

Changelog

1.6.0-2 (2024-11-25)

  • doc: Twinpack is now available for GNU/Linux, f8f4142

  • ZAux

    • feat(Context): added Context ManagedObject for very simple applications, 5cde8e8
  • ZApplication

    • fix(unit): fixed stopping a locked unit when calling StopAsync with invalid unit reference

      When stopping a controlled unit with StopAsync(startToken:=startToken, unit:=0), the unit reports an error (unit.error = TRUE) after reaching the ?Stopped? state. (close #100), 266b4f9

  • ZEquipmentBeckhoff

    • feat(Stepper_EL7031): implemented overwriting of an active move absolute command (#30)

      It is now possible to use MoveAbsoluteAsync to specify a new target position and a new target speed for an axis that has already started. However, due to the limitations of the Beckhoff EL7031 terminal, this is only possible once If the new parameters for position and speed are set during the deceleration ramp, the original position is still approached and only then positioned at the updated position (closes #29), fee9ed7

1.6.0-3 (2024-12-16)

  • doc: removed errorhandling concept, ed9c470

  • doc(Twinpack) show how the icon property works, which is supported with Twinpack 1.2, 654cff5

  • ZCore

    • fix (Sequence): a sequence shall not be recoverable (#93)

      A sequence cannot be recovered, as changing the ObjectState would result in a not allowed behaviour by ending (if changing to Idle) or starting (if changing to Busy) the sequence, c052b93

  • ZApplication

    • fix (Application): sequence recover is not necessary and not available (#102), b0c34da

1.6.0-4 (2025-01-18)

  • ZEquipment

    • fix(AxisPlcOpen): added missing properties to interface IAxisPlcOpenMcParameterTarget

      Added missing properties Distance, Position, Speed, Velocity and VelocityFeedrate to parameter interface IAxisPlcOpenMcParaemterTarget, 0254a32

    • fix(AxisListenerProcesser): error in a listener sequence does not lead to an error in the axis

      If a listener sequence is aborted with an error the first time it is called, the axis itself now also reports an error In addition, the behavior of the simulated axis has been corrected when there is an error in a listener sequence, 677a366

  • ZApplication

    • fix(UnitListenerProcessor): error in a listener sequence does not lead to an error in the unit

      If a listener sequence is aborted with an error the first time it is called, the unit itself now also reports an error(close #103), 3066215

  • ZEquipmentBeckhoff

    • feat(AxisStepper): added target parameter

      We added the target parameter interface to all axis stepper objects to get back the parameters of an active move, 3200a37

1.6.0-6 (2025-03-10)

  • ZCore

    • feat!: added functionality to monitor the execution of an "Async" call (#92)

      "Async" methods accept an IStartToken parameter to indicate whether the method was executed successfully Additional to the StartToken, an ZCore.ExcecutionToken is now available to not only check if the method call was successful, but also to monitor the whole execution of the task. The ExecutionToken gets informed (aborted), if the originally started task changed unexpected

      BREAKING CHANGE: A sequence is now a ZCore.ExecutionToken to be used as a parameter for "Async" calls . A sequence as an ExecutionToken gets informed (aborted) from an object if the originally started task has changed unexpected For example you can think of an axis starting MoveAbsoluteAsync in a sequence (e.g. _axis.AxisName.MoveAbsolutAsync(THIS^)). Stopping the axis at a different place in your application without or with another Token leads now to aborting the stored Token, therefore the sequence gets informed about the change, c35c960

  • ZPlatform

    • feat!: added functionality to monitor the execution of an "Async" call (#98), 4d441be
  • ZEquipment

    • feat!: added IStartToken parameter to actuator StopAsync method (#191)

      BREAKING CHANGE: Async functions shall have a parameter startToken : ZCore.IStartToken to indicate whether the method was executed successfully. ActuatorDigital.StopAsync also got this parameter now to provide the same functionality, 87cd270

    • feat!: added functionality to monitor the execution of an "Async" call (#186), 680e69b

  • ZApplication

    • feat!: added functionality to monitor the execution of an "Async" call (#101), 7050792
  • ZEquipmentBeckhoff

    • feat!: added functionality to monitor the execution of an "Async" call (#32), 7d2de8b
  • ZEquipmentPepperlFuchs

    • feat!: added functionality to monitor the execution of an "Async" call (#9), d92fe6e
  • ZEquipmentCiA402

    • fix(lenzei550): fixed halting an already halted drive

      Until this fix halting an already halted drive resulted in a blocked halting sequence, 1430ca3

    • feat!: added functionality to monitor the execution of an "Async" call (#12), b8de5c7

1.6.0-7 (2025-03-12)

  • doc: add doc for Twinpack configure connections (#93), 35829df
  • ZPlatform
    • fix: DirectoryImpl now checks if DirectoryExists error is thrown (#100)

      In newer TwinCAT versions the behavior of FB_CreateDir was changed by Beckhoff in a way that with already existing directories, it is seen as error if one wants to create a directory which already exists. Now this FB throws an error with error Code 1807; We take care of this in our DirectoryImpl FB and you can work with it as it was in recent versions, ce6c4e5

1.6.0-8 (2025-05-07)

  • ZCore

    • feat: integrate ads over ethercat parameterchannel (#96), 58066e4
    • feat: add properties for antiwindup feature of pid, 520e01b
  • ZPlatform

    • feat: integrate ads over ethercat parameterchannel (#106), 92d82cd

    • feat: added test if default setting is set correctly (#105), 19f8b00

    • fix(PlatformAdapterObject): do not handle the special case of errorId=0 and errorMessage='' here, this can be handled in ZCore.Object, d2a56ab

    • fix: if message-len is zero on errorid=0, abort with unknown error (#103), b4d9b2c

    • feat: separate error-message for commandaborted; set enable direction flags on boot, c79c004

    • feat: allow to access enable_positive and negative of MC_power (#102)

      • refactor: renaming of properties, cd953b0
  • ZAux

    • feat: integrate parameterchannel via ads protocol (#100), 1bf9e0a
  • ZEquipment

    • fix: return zero dutycycle on interval=0 in pwm-ctrl (#206), 1c67498

    • feat: add antiwindup min-maxdutycycle properties to pwmctrl (#205)

      It is possible to fetch min and maxdutycycle via additional properties from pwm-controller, c555007

    • feat: removed initialization ob enable-direction because its done in zplatform (#202), f449932

    • feat: set enable flags on mc_power directly (#201), 2305767

    • feat: allow to change movement direction enable flags of mc_power via parameters (#200)

      It is now possible to access Enable_Positive and Enable_Negative of internally held MC_Power to lock up a movement direction or both. Default setting is both directions are allowed, 8c7e1f4

  • ZEquipmentBeckhoff

    • fix: make movevelocity available in um version of stepper implementation, 40760fe

    • feat: add movevelocity to stepper (#34)

      Adding movevelocity capability to beckhoff stepper axes with beckhoff stepper terminal EL7031/7041, 69ca942

1.6.0-9 (2025-05-16)

  • ZAux
    • fix: use real functions for AppendReal in Stringbuilder (#101)

      StringBuilder internally used Lreal functions to append real values to string-chain which could generate slightly wrong numbers due to this type change, fe499f1

1.6.0-10 (2025-05-28)

  • ZApplication
    • fix: due to twincat check-all-object-problems to_string at UnitStateMachineState enum removed (#105)

      Beckhoff fixed with Version 3.1.4024.56 a problem regarding To-String attribute on certain enumerations. In our case this was happening on ZApplication.UnitStateMachineState enumeration which had this attribute activated. in order to stay compatible, this attribute is now removed, 31aca42

1.6.0-11 (2025-06-23)

  • ZEquipmentBeckhoff
    • fix (PowerMeasurementEL34x3): Iteration through variant values (#37)

      The iteration of variant values which can be added with the method AddVariantValue did not work correctly, cf35b58

1.6.0-12 (2025-07-02)

  • ZAux
    • fix (LoggerRollingFileAppender): optimized calculation of next rollover timestamp (#103)

      The Logger supports a rollover time policy When it was configured to roll over at midnight, it could lead to the loss of backup files, 583c32b

1.6.0-13 (2025-07-22)

  • ZEquipment
    • feat(ActuatorDigital): When overwriting a movement with movement in same direction, call the pre-movement listener (#209=

      this leads to the same bahavior as when overwriting a movement with the opposite direction, 70d07c8

    • feat: allow override of an actuator movement (#208), 0598385

1.6.0-14 (2025-07-28)

  • feat: added some images for doc, e2686c5

  • ZCore

    • doc: fixed image paths, 8f90f0c
    • fix: make Constants.PRG visible when using ZCore, 0bcb61d
  • ZAux

    • feat: adding sine2ramp object for simple trajectory calculations (#105)

      Added Sine-squared ramp generator for easy trajectory generation for pumps or simple velocity control applications, 1baf5c8

  • ZEquipment

    • fix: stop running listeners if an actuator movement was overwritten (#212)

      Previously an interrupted Pre or Post listener did not coll the OnStop event in its sequence due to this error, 69cc70e

1.6.0-15 (2025-10-23)

  • ZPlatform
    • fix: fixed some typos in logmessages, 80c3fba
  • ZAux
    • fix: RampLinearTImpl Cyclic throwed exception when duration is zero (#107), d68ba09
  • ZEquipment
    • feat: make pwm internal pid reset parametrizeable, 6cda1a4

    • fix: refresh pid cycletime after runasync of pwm if already started (#218)

      If a PWM controller was started with Interval = 0 the PID controller does not do anything because it exits in its cyclic calculation to avoid a div by zero. If an Interval was provided after the PWM controller was started, the cycletime in the pid controller has not been refreshed which needed the PWM to restart in order to work, a59733d

    • fix(AnalogInput2Byte): corrected setting the input value in simulation mode (#179), d63b50b

  • ZExperimental
    • fix(BallufBisM4IoLink): fixed missing library namespace, 78cb56e
    • feat: Implementation of Balluff-RFID reader BIS M-4xxIO-Link (#69), 5b11484
  • ZEquipmentCiA402
    • fix(Lenze i550): fixed an incorrect AxisMotionState and the immediate return of Busy FALSE when calling HaltAsync

      When calling HaltAsync, Busy only returns FALSE after the axis has stopped. The evaluation of AxisMotionState has also been improved so that acceleration and deceleration during a move are now correctly displayed, 8451f94

    • doc: fixed example for keba drive, a6e344c

1.6.0-16 (2025-11-06)

  • ZApplication
    • fix(Unit): Check if _statemachineIntrf is valid (nullpointer exception prevention) (#106), 0e3c5a7
  • ZExperimental
    • feat: add simulation property to balluff RFID reader object (#73), 11d80be

1.6.0-17 (2026-01-14)

  • doc: nuget example, 1c99e0a

  • doc: added nuget example, ca7c780

  • ZCore

    • fix(Step): consecutive changes should be usable to do single step changes in tests (#105), c91c062

    • feat: added ITestContext, ba38824

    • feat(Pid): Conditional Clamping Anti-Windup strategy for faster recovery times in a saturated system (#103)

      Add a new anti-windup strategy based on conditional clamping. This approach provides faster recovery from saturation but may require retuning control parameters, especially in systems that frequently trigger anti-windup

      The existing strategy (PidAntiWindupType.IntegralLimitation) remains the default to avoid breaking changes. The new strategy can be enabled via SetAntiWindupType, and new applications are encouraged to adopt PidAntiWindupType.ConditionalClamping

      Enabling the new method may indirectly affect the following components:

      - ZCore.Pid
      - ZEquipment.PidController
      - ZEquipment.PwmController
      - ZExperimental.AxisController
      

      When using these components with the new anti-windup type in a PLC, verify and retune control parameters to prevent potential machine damage, f76c7ca

    • feat: Implemented IsEqualLrealWithModulo - compare LREALs within a window with Modulo Support (#101), 156aa1c

  • ZAux

    • fix(Context): Context State remains Booting (#113)

      The state of an (application) context remained in booting, even when all objects associated with the context finished their booting sequence already. This fix allows to wait for the booting sequence to be finished using

      PROGRAM MAIN
      VAR
        _context : ZAux.Context('MyContext');
        _axis1 : ZEquipment.AxisSimulated(_context);
      END_VAR
      
      IF NOT _context.Booted THEN
        RETURN;
      END_IF
      
      // < when reaching this line of code,  all objects booted
      
  • ZEquipment

    • fix(AxisSimulated): invalid step selection in MoveVelocityAsync when changing velocity during movement (#230), f862d59

    • feat(Actuator): Listeners are now called during the movement of an actuator

      New ListenerMovementTypes to interact with an actuator during its movement. This is useful for monitoring

      • ListenerMovementType.MovePlus
      • ListenerMovementType.MoveMinus
      • ListenerMovementType.PreError, 4635942
    • fix: state enum entry on statemachine error step (#224), cb5ebaf

    • feat: added impulse and pulsed output custom objects (#222)

      the used output for impulse and pulsed-output is now change/setable from outside via SetDigitalOutput or at construction phase of the object, 6d53318

  • ZApplication

    • fix: check if interfaces and references are set correctly in IoBridge, e17186f
  • ZEquipmentBeckhoff

  • ZExperimental

    • feat(Controllers): support multiple anti-windup methods, cc90db5
    • fix: no parent in um object; renamings regarding data (#74), 9d06d44
  • ZEquipmentCiA402

    • fix: unit tests for moveabsolute sequence, c06b2aa

    • fix(Servotronix): added power on sequence when a change of operation mode from HomingMode to ProfilePositionMode is necessary (#20)

      Wurde die Achse nach einem Homing disabled, dann wurde beim n?chsten Move nur die Betriebsart umgestellt aber kein PowerOn durchgef?hrt, 5f9a2d1

    • feat: changed order of testing setpointacknowledge bit, c579a53

    • fix (AxisCiA402): wait until acknowledge was actualy low for one cycle, 4360e74

    • fix(Keba, Servotronix): fixed axis not in error state if a drive fault occurs while a drive warning is pending

      If a drive fault occurs while a drive warning is already pending, the axis switches to the error state, f47e665

1.6.0-18 (2026-01-20)

  • doc: added an example on how to build a zeugwerk framework object, 61a3b78
  • doc: added unit-statemachine listener example to userguide, bd8b004
  • ZEquipmentBeckhoff
    • fix(BeckhoffDmc): fixed boot problem when using both axis channels of the EL7062 terminal

      The boot problem when using both axis channels of the EL7062 terminal has been fixed, 5e13aad

    • feat(BeckhoffDmc): changed IO-image to simplify linking variables

      To simplify linking variables the IO-image was changed. Now the entire DMC input and output structure can be linked in one step, 95f2175

1.6.0-19 (2026-02-27)

  • ZAux

    • feat(Listeners): Support for inactive states (#115)

      Listeners have been enhanced. Previously, listeners could handle actions before, during, and after sequences attached to states. Now, listeners can also operate on states without sequences, allowing actions to be executed before, during, or after an inactive state, 4a2333c

  • ZEquipment

    • feat(Controllers): support multiple anti-windup methods, 3e92f81

    • fix(Listeners): adapted queue processing due to new listener feature (#235)

      Added activeTargetState variable to manage state transitions, ad4d5e7

    • fix: set name in impl not in output due to new LightCustom object changes (#229), ab996b5

    • feat(Light)!: introduce interface for impulseoutput, pulsedoutput and light (#223)

      BREAKING CHANGE: The signature of the Enable method has been changed, it now requires a boolean input

      Also added additional object where an external DigitalOutput can be used to inject into those objects, d0e8171

    • fix(AxisSimulated): fixed an unhandled step in MoveVelocity sequence of the simulated axis, a2e0f8d

    • fix(ActuatorDigital): corrected initialization of the minus input of the actuator ActuatorDigitalMonoPlusLsPlusMinusUM

      The minus input of the actuator ActuatorDigitalMonoPlusLsPlusMinusUM is now initialized correctly, 8ddd7bf

  • ZApplication

    • feat(UnitListenerAutoStart): Add listener to automatically home and start a unit (#114), 6580bc8

    • feat: added light as separate datatype for iobridge (#108)

      Switched ImpulseOutput and PulsedOutput to controlled-by-interface with newly defined interfaces in ZEquipment, 513dd23

  • ZEquipmentBeckhoff

    • fix(Dmc): added handling of an already active positioning error

      MovePosition and MoveVelocity sequence is aborted if a positioning error is already active and the drive does not switch to the active state, 094f90f

    • fix: if statemachine is on error, reseterror sequence will be called (#48)

      In Beckhoff EL70xx axis implementation in some situations an error reset was not done correctly if called without an actual error signaled in the terminal status. Now the reset is done anyways, 811d655

    • fix(Listeners): adapted queue processing due to new listener feature, b55b99a

    • fix(BeckhoffDmc): fixed wrong position latching, converter no longer needed for booting parameter

      The problem of incorrect position latching when using touch probe functions has been fixed The converter has been removed from the boot parameters, so it no longer needs to be initialized before the boot parameters, cf5bf3d

    • feat(BeckhoffDmc): added new homing methods

      Added homing methods CcwLimitSwitch and CwLimitSwitch, 8608dab

  • ZExperimental

    • fix: if statemachine is on error, reseterror sequence will be called (#82), 2b24a48
    • fix(Listeners): adapted queue processing due to new listener feature, f3d6fda
  • ZEquipmentCiA402

    • fix: if statemachine is on error, reseterror sequence will be called (#25), f60d58c
    • fix(Listeners): adapted queue processing due to new listener feature, fe576f4

1.6.0-20 (2026-03-18)

  • doc: restructed doc, 49332ca

  • feat: added example for UnitListenerAutoStart, 42b1d6f

  • ZCore

    • feat(IoLink): added enum IoLinkStateFlags

      The enumeration IoLinkStateFlags is used to represent a bitdecoded state that can be set for an ethercat-slave with an IO-link port, 2b9b9d5

  • ZPlatform

    • fix(DateTimeImpl): handle edge cases in UnixTimestamp

1.6.0-21 (2026-03-23)

  • ZEquipmentBeckhoff
    • fix: check converter calculations on div0 on dmc axis (#51), 23c3fd8

1.6.0-23 (2026-03-26)

  • ZEquipment

    • fix(AxisSimulated): set axis in simulation mode during initialization (#239)

      The simulation mode for the axis AxisSimulated is now set during initialization Resetting the simulation mode of the axis AxisSimulated is no longer possible, the axis will always be simulated, c704fe0

  • ZEquipmentBeckhoff

    • fix(Dmc): corrected setting simulation mode

      The simulation mode of a DMC axis can now be set by calling theSetSimulation method or by setting the Simulation property, both lead to the same result, d986859

  • ZEquipmentCiA402

    • fix(AxisLenzei550): corrected missing interface for current mode in AxisLenzei550UM, 9134635

    • fix(Lenzei550, Keba, Servotronix): corrected setting simulation mode

      The simulation mode of a Lenzei550, Keba and Servotronix axis can now be set by calling the SetSimulation method or by setting the Simulation property, both lead to the same result, 6721246

1.6.0-24 (2026-03-31)

  • ZAux
    • fix: exception if speed=0 in RampLinear (#109), 7563c9a
    • fix: use absolute values vor duration (#117), 7ff0cae

1.6.0-25 (2026-05-12)

  • feat: submenu on mobile, a67f157

  • ZCore

    • fix(RingBuffer): thread-safety for ringbuffer (#107)

      Concurrent single-producer/single-consumer (SPSC) access could lead to invalid behavior because some operations were assumed to be thread-safe when they were not

      Under concurrent producer/consumer access this could result in race conditions, inconsistent state observation, or incorrect buffer usage

      This issue also affected the logger implementation, which internally uses a RingBuffer. Even when using the Logging object, which synchronizes writers to effectively operate as a single producer, concurrency issues could still occur because the underlying ring buffer semantics were not fully thread-safe

      The concurrency documentation was corrected and the underlying issues that prevented RingBuffer from being thread-safe in supported SPSC scenarios were fixed

      To prevent remaining unsafe usage patterns, a dedicated RingBufferConcurrent type was introduced which exposes only operations that are guaranteed to be safe for concurrent SPSC access

      Documentation now explicitly defines:

      • valid producer/consumer access order
      • publication and consumption semantics
      • limitations of snapshot-style reads
      • unsupported concurrent operations
      • full-buffer synchronization requirements

      Also added explicit SPSC usage examples to help avoid incorrect integration patterns in concurrent applications


    Co-authored-by: Matthias Seehauser matthias.seehauser@zeugwerk.at, ce31b38

  • ZPlatform

    • feat(PlcOpenMotionControl): pass acceleration, deceleration and jerk through to MC function blocks (#115)

      The PlcOpen motion sequences (MoveAbsolute, MoveVelocity, Stop, Halt) now correctly forward the acceleration, deceleration and jerk parameters to the underlying MC function blocks instead of ignoring them

      • PlcOpenMoveAbsoluteSequence: detect changes in acceleration/deceleration/jerk to trigger a command restart, in addition to position and speed changes
      • PlcOpenMoveVelocitySequence: same change-detection extension for acceleration/deceleration/jerk
      • PlcOpenStopSequence: apply Deceleration/Jerk on Execute=TRUE (was erroneously applied on the preceding Execute=FALSE toggle)
      • PlcOpenHaltSequence: apply Deceleration/Jerk on the MC_Halt function block, b223cfe
  • ZEquipment

    • feat(AxisPlcOpen): add Ex-variants of move methods with explicit acceleration, deceleration and jerk (#243)

      Each movement method on AxisPlcOpenMc now has a companion Ex-variant that accepts explicit acceleration, deceleration and jerk parameters, overriding the axis-wide defaults configured in AxisPlcOpenMcParameterDrive for that single call. The original methods are unchanged and continue to use the default parameters New methods on AxisPlcOpenMc:

        MoveAbsoluteExAsync(startToken, position, speed, acceleration, deceleration, jerk)
        MoveRelativeExAsync(startToken, distance, speed, acceleration, deceleration, jerk)
        MoveVelocityExAsync(startToken, velocity, acceleration, deceleration, jerk)
        HaltExAsync(startToken, deceleration, jerk)
        StopExAsync(startToken, deceleration, jerk)
      

      New properties on AxisPlcOpenMcParameterDrive:

      ProfileAcceleration, ProfileDeceleration, ProfileJerk -- used by
      MoveAbsolute/Relative/Velocity
        HaltDeceleration, HaltJerk                             -- used by Halt
        StopDeceleration, StopJerk                             -- used by Stop
      

      A value of 0 for any of these parameters means "use the value configured in the axis hardware/NC configuration", which preserves the previous behaviour

      Usage examples:

        // one-off move with custom dynamics - no permanent side effect
        _axis.MoveAbsoluteExAsync(startToken, position:=100.0, speed:=50.0,
                                  acceleration:=500.0, deceleration:=300.0, jerk:=0.0);
      
        // change the persistent default for all subsequent profile moves
        _axis.Parameter.Drive.ProfileAcceleration := 500.0;
        _axis.Parameter.Drive.ProfileDeceleration := 300.0;
        _axis.MoveAbsoluteAsync(startToken, position:=100.0, speed:=50.0);
      
        // custom stop deceleration for an emergency-style stop
        _axis.StopExAsync(startToken, deceleration:=2000.0, jerk:=0.0);
      
      ```, [92655be](https://github.com/Zeugwerk/ZEquipment/commit/92655be2315a767b551ea52f161aae8101df6b2d)