[etherlab-users] Slave DC start time calculation
Gavin Lambert
gavin.lambert at tomra.com
Mon May 21 02:57:02 CEST 2018
I would be inclined to treat that as an error, or as DC sync outputs disabled. (It does need to treat all parameters == 0 as valid but disabled.) The sync1 cycle time can’t be used directly as a sync0 cycle time anyway – the whole thing is meaningless if there isn’t a sync0 cycle time.
The fact that sync1 cycle isn’t actually a cycle time makes me a little wary of the whole idea of separating cycle and shift like this.
Remember that ecrt_slave_config_dc(sc, 250000, 0, 750000, 0) causes a SYNC0 cycle of 250us and a SYNC1 cycle of 1000us – it’s impossible to calculate the latter without a SYNC0 cycle time.
From: Graeme Foot [mailto:Graeme.Foot at touchcut.com]
Sent: Monday, 21 May 2018 12:36
To: Gavin Lambert <gavin.lambert at tomra.com>; Philippe Leuba <pleuba at swissonline.ch>
Cc: etherlab-users at etherlab.org
Subject: RE: [etherlab-users] Slave DC start time calculation
Hi,
That bit I'm unsure of. It's based on the assumption that if the sync0 cycle time is zero, then sync1 won't occur. So it will set the sync0 cycle time to the requested sync1 cycle time instead (and adjusting the sync0 shift time), setting sync1 cycle and shift times to zero, meaning sync1 will be triggered at the same time as sync0, at the time sync1 was meant to be triggered.
This is to avoid the mod (%) call occurring on a zero sync0_cycle_time.
Is there a better alternative for this case?
Graeme.
From: Gavin Lambert [mailto:gavin.lambert at tomra.com]
Sent: Monday, 21 May 2018 11:52 AM
To: Graeme Foot <Graeme.Foot at touchcut.com<mailto:Graeme.Foot at touchcut.com>>; Philippe Leuba <pleuba at swissonline.ch<mailto:pleuba at swissonline.ch>>
Cc: etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: RE: [etherlab-users] Slave DC start time calculation
Why are you adjusting dc_sync[0] from sync1_*? That doesn’t seem like it would ever be a sensible thing to do, unless I’m missing something.
From: Graeme Foot [mailto:Graeme.Foot at touchcut.com]
Sent: Monday, 21 May 2018 11:20
To: Philippe Leuba <pleuba at swissonline.ch<mailto:pleuba at swissonline.ch>>; Gavin Lambert <gavin.lambert at tomra.com<mailto:gavin.lambert at tomra.com>>
Cc: etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: RE: [etherlab-users] Slave DC start time calculation
I would propose the attached patch (completely untested).
This allows the sync1 offset to be used in a fashion compatible with any existing codebase (hopefully) by adding the sync1 cycle time together with the sync1 shift time, then splitting them out based on the sync0 cycle time. The only braking case I can think of is if someone has used a sync1 shift parameter, not noticing that it is currently not doing anything.
It will also handle a case where the combined time, that will be passed to register 0x9A4, will be negative (logging a config error). It will also handle a case where the sync0 cycle time is zero (not sure if this is allowed with a non-zero sync1 cycle???) and set up the dc to set the sync0 cycle time instead, adjusting the sync0 shift time by the sync1 shift time.
Philippe, in your case you would then call:
ecrt_slave_config_dc(sc, 0x0700, 500000, 250000, 0, 1000);
or (for backwards compatibility)
ecrt_slave_config_dc(sc, 0x0700, 500000, 250000, 1000, 0);
Graeme.
From: etherlab-users [mailto:etherlab-users-bounces at etherlab.org] On Behalf Of Philippe Leuba
Sent: Friday, 18 May 2018 8:11 PM
To: Gavin Lambert <gavin.lambert at tomra.com<mailto:gavin.lambert at tomra.com>>
Cc: etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: Re: [etherlab-users] Slave DC start time calculation
Good idea, this should work for different kind of slaves and did not break backward compatibility.
How to proceed now ?
Philippe
On May 18, 2018, at 7:24 AM, Gavin Lambert <gavin.lambert at tomra.com<mailto:gavin.lambert at tomra.com>> wrote:
I don’t think it makes sense to start using the sync1_shift_time parameter, as that would introduce incompatibility with other code (that perhaps hasn’t upgraded to that build yet, or hasn’t noticed or doesn’t care about the change in start time), and introduce some additional ambiguity.
In theory (completely untested air code) something like this might be more correct:
cycle = sync0->cycle_time + sync1->cycle_time – (sync1->cycle_time % sync0->cycle_time);
From: Philippe Leuba [mailto:pleuba at swissonline.ch]
Sent: Friday, 18 May 2018 16:34
To: Gavin Lambert <gavin.lambert at tomra.com<mailto:gavin.lambert at tomra.com>>
Cc: Graeme Foot <Graeme.Foot at touchcut.com<mailto:Graeme.Foot at touchcut.com>>; etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: Re: [etherlab-users] Slave DC start time calculation
Hi Gavin,
Thanks for the detailed explanation, this explain why the code is like it is. This works for slaves that are doing oversampling but not for mine that just want to shift the SYNC1 a bit.
Now if we want a solution working for all kind of possibles slave configurations we will need to use the sync1_shift_time parameter of the ecrt_slave_config_dc into the loop...
What do you think ?
Philippe
On May 18, 2018, at 5:15 AM, Gavin Lambert <gavin.lambert at tomra.com<mailto:gavin.lambert at tomra.com>> wrote:
The SYNC1 Cycle register (0x09A4) is a little weird; it acts as both a cycle and shift in one register, depending on the value of the SYNC0 Cycle (0x09A0).
* Where SYNC0 Cycle is X and SYNC1 Cycle is 0, SYNC0 and SYNC1 occur at the same time – thus same cycle, no shift.
* Where SYNC0 Cycle is X and SYNC1 Cycle is less than X, SYNC1 occurs at (SYNC1 Cycle) ns after the SYNC0, but otherwise at the same cycle rate – thus it acts as a shift.
* Where SYNC0 Cycle is X and SYNC1 Cycle is equal to X, SYNC1 occurs at every second SYNC0 – thus it acts as a 2X cycle with no shift.
* Where SYNC0 Cycle is X and SYNC1 Cycle is equal to 2X, SYNC1 occurs at every third SYNC0 – thus it acts as a 3X cycle with no shift.
* Where SYNC0 Cycle is X and SYNC1 Cycle is greater than X but not an exact multiple, it acts as a combination of cycle and shift as above.
(Under the hood, it always does behave as a shift that fires exactly once non-overlapping offset from the SYNC0 pulse. Or to put it another way, SYNC0 starts the timer but doesn’t reset it if already running, and it fires SYNC1 once when the timer finishes.)
The ecrt_slave_config_dc method essentially just sets the cycle values into the registers directly, while using the sync0_shift to calculate the overall DC start time relative to the master cycle. The sync1_shift parameter is ignored and should always be 0 because there’s nothing it can actually do with it.
Exactly what these mean is slave-specific; some slaves want a simple shift at the same cycle rate because they use one to control output timing and the other to control input timing. Other slaves might want a subordinated cycle (SYNC1 occurring at the master cycle rate, SYNC0 occurring more frequently) because they want to oversample inputs. Or there can be a number of other scenarios. The slave documentation should tell you what settings you need relative to your master cycle.
For what it’s worth, I do have a subordinated slave – it uses ecrt_slave_config_dc(sc, 250000, 100000, 750000, 0) to make SYNC0 pulse every 0.25ms, SYNC1 pulse every 1ms (yes, 1ms, not 0.75ms), and both to be offset from the 1ms master cycle by about 100us – although that’s a little arbitrary.
I assume the change was probably motivated by this sort of slave configuration (since it does extend the “true” cycle time of the slave, from a certain point of view), but simple addition is probably wrong when a non-multiple sync1 cycle time is used to introduce any kind of shift into the mix.
From: etherlab-users [mailto:etherlab-users-bounces at etherlab.org] On Behalf Of Graeme Foot
Sent: Friday, 18 May 2018 13:03
To: Philippe Leuba <pleuba at swissonline.ch<mailto:pleuba at swissonline.ch>>; etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: Re: [etherlab-users] Slave DC start time calculation
Hi,
This piece of code is getting a start time that is in sync with the initial app time from a multiple of the sync0/sync1 cycle times, adjusted by the sync0 shift time.
https://download.beckhoff.com/download/Document/io/ethercat-development-products/ethercat_esc_datasheet_sec2_registers_2i7.pdf
says the sync1 cycle time is the "Time between SYNC1 pulses and SYNC0 pulse in ns".
However https://infosys.beckhoff.com/english.php?content=../content/1033/tcsystemmanager/reference/ethercat/html/EtherCAT_DistributedClocks.htm&id= (Twincat DC settings) and the information for my yaskawa drives are saying that the sync1 cycle time should be a multiple of the sync0 cycle time, and the sync1 offset is the offset between the sync0 and sync1 interrupts.
The master code doesn’t even look like it uses the sync1 shift time, and information from my Yaskawa slave says it's sync1 cycle time is readonly and matches the sync0 cycle time.
So:
- It looks like the first documents registers 0x09A4:0x09A7 should actually be called sync1 shift time.
- It does not look like there is currently any slave support for a different (from sync0) sync1 cycle time.
(anyone got a slave out there that does?)
- The EtherLab master should not be using sync1 cycle time in the calculation you mention below.
- The EtherLab master should be sending sync1 shift time to 0x09A4:0x09A7 instead of the sync1 cycle time.
- TwinCAT is probably using its cycle time "multiple" parameters to figure out how often to send the PDO requests for each slave (just a guess).
In your case, set the second to last parameter to zero, i.e.:
ecrt_slave_config_dc(sc, 0x0700, 500000, 250000, 0, 0);
You have already adjusted the sync0 shift time (third to last parameter) anyway.
Regards,
Graeme.
From: etherlab-users [mailto:etherlab-users-bounces at etherlab.org] On Behalf Of Philippe Leuba
Sent: Friday, 18 May 2018 7:11 AM
To: etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
Subject: Re: [etherlab-users] Slave DC start time calculation
Hi,
I have changed how to calculate the slave start time by taking only the sync0->cycle_time as cycle time.
The results is good and I can see in the log that the 'remainder' is almost the same for all slaves.
@Florian: Why did you did this change on 2016-09-16 ?
Best regards
Philippe
On May 16, 2018, at 6:22 PM, Philippe Leuba <pleuba at swissonline.ch<mailto:pleuba at swissonline.ch>> wrote:
Hi All,
I can not understand how to configure correctly my slaves with the ecrt_slave_config_dc() function.
I use nine EL7211-9014 servo controllers and the XML declarations is:
<Dc>
<OpMode>
<Name>DC</Name>
<Desc>DC-Synchron</Desc>
<AssignActivate>#x700</AssignActivate>
<CycleTimeSync0 Factor="1">0</CycleTimeSync0>
<ShiftTimeSync0 Input="0">30000</ShiftTimeSync0>
<CycleTimeSync1 Factor="-1">0</CycleTimeSync1>
<ShiftTimeSync1>1000</ShiftTimeSync1>
</OpMode>
</Dc>
SYNC0 and SYNC1 should be fired at each cycle.
My realtime cycle is at 500us, so initially I used:
ecrt_slave_config_dc(sc, 0x0700, 500000, 30000, 1000, 0);
but I sometimes faced some hiccup on some motor movements (almost always on the same motor, but sometimes not), most probably due to frames late regarding SYNC events, so I increased the sync1_shift to half of the cycle time:
ecrt_slave_config_dc(sc, 0x0700, 500000, 250000, 1000, 0);
This help, but I’m still not convinced that it is correct.
How can I debug this, I did not see any error on slaves COEs 1c32 or 1c33 ?
Startup debug messages are the followings:
EtherCAT DEBUG 0-12: Checking for synchrony.
EtherCAT DEBUG 0-12: 19 ns difference after 1 ms.
EtherCAT DEBUG 0-12: app_start_time=64456682505935
EtherCAT DEBUG 0-12: app_time=64460192975876
EtherCAT DEBUG 0-12: start_time=64460292975876
EtherCAT DEBUG 0-12: cycle=501000
EtherCAT DEBUG 0-12: shift_time=250000
EtherCAT DEBUG 0-12: remainder=263941
EtherCAT DEBUG 0-12: start=64460293462935
EtherCAT DEBUG 0-12: Setting DC cyclic operation start time to 64460293462935.
EtherCAT DEBUG 0-12: Setting DC AssignActivate to 0x0700.
-
-
-
EtherCAT DEBUG 0-13: Checking for synchrony.
EtherCAT DEBUG 0-13: 9 ns difference after 1 ms.
EtherCAT DEBUG 0-13: app_start_time=64456682505935
EtherCAT DEBUG 0-13: app_time=64460854977928
EtherCAT DEBUG 0-13: start_time=64460954977928
EtherCAT DEBUG 0-13: cycle=501000
EtherCAT DEBUG 0-13: shift_time=250000
EtherCAT DEBUG 0-13: remainder=444993
EtherCAT DEBUG 0-13: start=64460955283935
EtherCAT DEBUG 0-13: Setting DC cyclic operation start time to 64460955283935.
EtherCAT DEBUG 0-13: Setting DC AssignActivate to 0x0700.
I’m really surprised that the remainder can be so different, so I looked in the source code and can not understand the logic:
// set DC start time
start_time = master->app_time + EC_DC_START_OFFSET; // now + X ns (X being 100000000 = 100 ms)
if (sync0->cycle_time) {
// find correct phase
if (master->has_app_time) {
u64 diff, start;
u32 remainder, cycle;
diff = start_time - master->app_start_time;
cycle = sync0->cycle_time + sync1->cycle_time;
remainder = do_div(diff, cycle);
start = start_time + cycle - remainder + sync0->shift_time;
Why the cycle is the sum of the two sync->cycle_time, in my case 501000, should not it be: sync0->cycle_time (500000) ?
This was changed on 2016-09-16, but It seems it was right before.
I can see that sync0->cycle_time is written to register 9A0 (500000)
and sync1->cycle_time is written to register 9A4 (1000), this is correct.
It seems to me that the sync1_cycle parameter of the ecrt_slave_config_dc() is handled as as sync1_shift, this is really confusing.
Is it normal, can someone explain this ?
Philippe
_______________________________________________
etherlab-users mailing list
etherlab-users at etherlab.org<mailto:etherlab-users at etherlab.org>
http://lists.etherlab.org/mailman/listinfo/etherlab-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.etherlab.org/pipermail/etherlab-users/attachments/20180521/ecf498c6/attachment-0003.htm>
More information about the Etherlab-users
mailing list