@Andrax, first of all: thanks for sharing your examples — it’s clear you’re on the right track, especially by thinking in terms of watchdogs and by splitting the sequence into “start → run → done”. That’s already more than many integrations do.
Just for context: I come more from the Mechatrolink / Yaskawa world, but at the motion-control architecture level the concepts are the same (state machines, ACK semantics, watchdogs, reference sync, etc.), so I’m looking at this more from that angle than from any specific CiA-402 detail.
Looking at your two snippets together, it feels like each one gets an important part right:
In the cia402_homecomp (C) version you already have a proper state machine with timeouts (start_timeout / run_timeout), which is exactly the kind of safety supervision you want in an industrial setup to avoid waiting forever for a drive.
In the pseudo-PLC example you’re already trying to tie the logic to real drive signals (bits from 0x6041, speed, etc.), which is also exactly the right direction.
Where they still feel a bit “misaligned” to me is this:
The cia402_homecomp does have watchdogs, but it’s not really driven by the drive’s real status (it relies on cia-homed / cia-error coming from outside, and doesn’t directly check “started / motion / done” conditions itself).
The pseudo-PLC tries to use real status, but the start and motion proof parts are still fragile (e.g. setting bit 4 = 1 doesn’t guarantee a rising edge, and comparing target speed <> actual speed isn’t a very robust proof that motion really started).
From an industrial point of view, the sequence usually looks roughly like this (independent of whether it’s EtherCAT, Mechatrolink, Sercos, etc.):
Generate a start event (pulse or temporary level, depending on the drive), not just keep the bit stuck at 1 forever.
First watchdog: after start, wait for either a real “homing started” indication or a real proof of motion (position change / actual velocity > threshold). If that doesn’t happen within X seconds → fault.
Second watchdog (overall): while homing is running, wait for the real “done” indication from the drive. If it exceeds the overall timeout → fault.
On completion: clear the start and synchronize the reference (pos_cmd with pos_fb) to avoid jumps / following errors when going back to CSP.
So in a way, the idea in your first code (state machine + timeouts) is right, and the idea in your second one (looking at real 0x6041 bits / real behavior) is also right — what’s missing is bringing those two together: a state machine whose transitions are driven by real drive status and real motion, not only by logical external signals.
One small additional point from an industrial perspective: in your C example a homing fault ends up triggering a global E-STOP. In many systems we try to separate those two concepts: a homing/process fault usually leads to an axis fault or a controlled stop/disable of that axis, while E-STOP is reserved for real safety events. That separation often makes diagnostics and recovery much cleaner, while still keeping the safety chain intact.
This is not meant as criticism of what you’ve done — on the contrary, it’s pretty clear you’re already thinking in exactly the right direction (watchdogs, states, safety). It’s more about aligning it with what is usually done in industrial integrations:
start as an event → real confirmation that it started → real confirmation that it finished → reference synchronization.
If we can move cia402_homecomp more in that direction (even if via masks/config per drive), I think it would solve a big part of the homing and mode-switching issues people are running into.