<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-NZ" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">The following function get the time from the slave at which the EtherCAT frame went through it<o:p></o:p></p>
<p class="MsoNormal">ecrt_master_reference_clock_time(master->master, &master->reference_time);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The following function will update the masters time with the last slaves time plus the app time period<o:p></o:p></p>
<p class="MsoNormal">ecrt_master_application_time(master->master, master->reference_time+master->app_time_period);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">One problem is that the ecrt_master_application_time() call may not be exactly one master->app_time_period value beyond the slaves reference time.  There are many sources of jitter in your application, from the realtime wakeup time to various
 amounts of processing time since the wakeup to the above function call.  So you need to relate the ecrt_master_application_time() to your app's clock time.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Another thing you need to do for option B is relate the previous master->reference_time to the ecrt_master_reference_clock_time() and adjust your apps's time base to account for drift.  You can then sleep and wake up your rt thread in keeping
 with your slaves time period.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US">Graeme.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Ignacio Rosales Gonzalez [mailto:narogon@gmail.com]
<br>
<b>Sent:</b> Wednesday, 24 January 2018 12:57 a.m.<br>
<b>To:</b> Graeme Foot <Graeme.Foot@touchcut.com><br>
<b>Cc:</b> Boris Skegin <boris.skegin.de@googlemail.com>; etherlab-users@etherlab.org<br>
<b>Subject:</b> Re: [etherlab-users] Sync problems and DC mode<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt">Thanks for your reply Graeme! <o:p>
</o:p></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt">I would try your changes for the A method (a EtherCAT master is the master clock:) putting domain_queue the first.<o:p></o:p></p>
</div>
<p class="MsoNormal">By the way for the B method (Slave DC master is the master clock) what is wrong in this approach?:<br>
<br>
  // send process data<br>
  rtapi_mutex_get(&master->mutex);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">  // queue domain data<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">ecrt_domain_queue(master->domain);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">  <o:p></o:p></p>
</div>
<p class="MsoNormal">//get the DC slave reference clock time and save in master->reference_time<o:p></o:p></p>
<div>
<p class="MsoNormal">ecrt_master_reference_clock_time(master->master, &master->reference_time);
<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">// sync slaves to ref clock<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">ecrt_master_sync_slave_clocks(master->master); <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">//update master time with time got from dc ref slave<br>
  ecrt_master_application_time(master->master, master->reference_time+master->app_time_period);
<br>
 <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">// send domain data<br>
  <br>
  ecrt_master_send(master->master);<br>
  rtapi_mutex_give(&master->mutex);<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Best regards,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Ignacio Rosales<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">2018-01-23 2:18 GMT+01:00 Graeme Foot <<a href="mailto:Graeme.Foot@touchcut.com" target="_blank">Graeme.Foot@touchcut.com</a>>:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal">As Boris says, master->app_time needs to actually match your PC's time (converted to your app's timeframe).<br>
<br>
Another change you could try is as below.  From line 1115:<br>
<br>
  // send process data<br>
  rtapi_mutex_get(&master->mutex);<br>
<br>
  // queue domain data<br>
  ecrt_domain_queue(master->domain);<br>
<br>
  // update application time<br>
  master->app_time = rt_get_app_time();<br>
  ecrt_master_application_time(master->master, master->app_time);<br>
<br>
  // sync ref clock to master<br>
  ecrt_master_sync_reference_clock(master->master);<br>
<br>
  // sync slaves to ref clock<br>
  ecrt_master_sync_slave_clocks(master->master);<br>
<br>
  // send domain data<br>
  ecrt_master_send(master->master);<br>
  rtapi_mutex_give(&master->mutex);<br>
<br>
<br>
You want as constant a time between calling ecrt_master_application_time() and ecrt_master_send() as possible.  The calls to ecrt_domain_queue() call takes variable amounts of processing time, so do that first.  Also call ecrt_master_sync_reference_clock()
 every cycle to ensure the reference slave gets lot of small updates rather than a few big updates.  This helps all slaves keep sync better.  It also avoids another source of variable processing time between ecrt_master_application_time() and ecrt_master_send().<br>
<br>
<br>
Graeme.<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal"><br>
<br>
-----Original Message-----<br>
From: etherlab-users [mailto:<a href="mailto:etherlab-users-bounces@etherlab.org">etherlab-users-bounces@etherlab.org</a>] On Behalf Of Boris Skegin<br>
Sent: Tuesday, 23 January 2018 2:07 p.m.<br>
To: <a href="mailto:etherlab-users@etherlab.org">etherlab-users@etherlab.org</a>; Ignacio Rosales Gonzalez <<a href="mailto:narogon@gmail.com">narogon@gmail.com</a>><br>
Subject: Re: [etherlab-users] Sync problems and DC mode<br>
<br>
Hello.<br>
<br>
> With this version<br>
> <<a href="https://github.com/narogon/linuxcnc-ethercat/commit/e4ab86ba6167ced53" target="_blank">https://github.com/narogon/linuxcnc-ethercat/commit/e4ab86ba6167ced53</a><br>
> 2e49904059df580062b2d97#diff-059a684a933530837771b5a249433ff3><br>
> (also as attachment lcec_main.c) I get the servos sync and OP but it<br>
> seems that the PDO doesn't arrive for some of the slaves (no idea why).<br>
<br>
master->app_time += master->app_time_period;  means that you just sum<br>
up constant cycle times of  the LinuxCNC thread. So any latency information gets lost here.<br>
<br>
Rather  make  master->app_time  be equal to something like<br>
rt_get_time() transferred to EtherCAT time.<br>
<br>
I also think that a proper value for sync0Shift  can help a lot.<br>
<br>
If however nothing of that helps, then proceed  to  Graeme Foot's option b) .<br>
<br>
BTW, what exactly is your kernel and network card and do you really use an adopted ( non-generic) network driver?<br>
<br>
Regards,<br>
boris<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
etherlab-users mailing list<br>
<a href="mailto:etherlab-users@etherlab.org">etherlab-users@etherlab.org</a><br>
<a href="http://lists.etherlab.org/mailman/listinfo/etherlab-users" target="_blank">http://lists.etherlab.org/mailman/listinfo/etherlab-users</a><o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>