I'm not sure what the Matlab equivalent of this is, but assuming that the slave 
follows the normal DC subordinated cycles mode (which I did glance through the 
datasheet but couldn't verify) then the way that the DC sync0 and sync1 cycle 
times need to be set is a little weird at first glance.

Typically the slave will sample on SYNC0 and report on SYNC1, so you want the 
SYNC1 pulse to match your domain packet cycle time and SYNC0 your desired 
sampling rate, but these are specified a bit oddly.  For example, with a domain 
cycle time of 1ms (1kHz) and a desired sampling rate of 4kHz, you need to set 
the Sync0 cycle time to 250000 and the Sync1 cycle time to 750000 (not to 
1000000 as you might have expected).

Some other advice is that for domain cycle times faster than 1ms you will 
definitely need to use the dedicated drivers (not the generic one), and for 
very fast rates you will likely need to use an RTOS (such as Xenomai).  This 
isn't needed if you have a fast sampling rate with a relatively slow domain 
cycle time, but obviously that will increase the data transfer requirements 
each domain cycle.

The unofficial patchset 
(https://sourceforge.net/u/uecasm/etherlab-patches/ci/default/tree/) does 
contain some improvements for DC, especially for subordinated cycles, so if 
you're not already using that then it may be worth a try.

----

Gavin Lambert
Senior Software Developer TOMRA Fresh Food

 


COMPAC SORTING EQUIPMENT LTD | 4 Henderson Pl | Onehunga | Auckland 1061 | New 
Zealand
Switchboard: +49 2630 96520 | https://www.tomra.com

The information contained in this communication and any attachment is 
confidential and may be legally privileged. It should only be read by the 
person(s) to whom it is addressed. If you have received this communication in 
error, please notify the sender and delete the communication.
From: Merkel, Amos
Sent: Thursday, 27 May 2021 12:59 am
To: etherlab-users@etherlab.org
Subject: [Etherlab-users] Distributed Clocks and Oversampling - slave 
configuration of the ELM3604-002


Hi everyone!

I am trying to get an ELM3604-002 by Beckhoff to work in the etherlab 
environment using Simulink and the generic slave block of the etherlab_lib.  
So far, I managed to get the slave operating and working for lower sample 
rates, but keep getting error states and "DC Invalid Sync Cycle Time" messages 
in dmesg for anything higher than 4kHz. Unfortunately, I do not really 
understand how the DC configuration works in detail, and the ELM3604-002 
apparently does not support freerun mode, so I am stuck right now. 

Does anyone have an idea how to fix this? I would be most grateful for any 
hint! 
You will find my Matlab function with the slave struct below.

Best regards,

Amos

%% ELM3604-0002 Generic Slave Struct 
% by Amos Merkel

%% notes 
%    firmware does not support freerun mode
%    Output Port 1..4: Value-Vector Channel 1..4, 
%                           -length depends on oversampling factor 
%                           -vector entry n correspondents to nth value of
%                           timestep, taken at time timestep +
%                           n*Timesteplength/oversampling factor
%    Output Port 5..8: Status Output of Channel 1..4, if activated
%                            -entries are: 1: error 2: Underrange 3: Overrange 
4: Diag
%                            5: TxPDOState
%    configure osm (in 1..15) and t_sample to your need
%    check SDO Configuration below and configure to your needs (see Beckhoff 
documentation for
%    additional options)

%% struct
function rv=elm3604

osm=3;                  % osm:          oversampling mode in range 1..15 for 
the resulting oversampling rates: 1 2 4 5 8 10 16 20 25 32 40 50 64 80 100
tsample=1/5000;%tsample=1e-3;           % tsample:      sample time in s
StatusOutput=true;      % StatusOutput: Add Status Outputs for each Channel

osm=max(min(osm,15),1); % limit os to 1..100
osf=[1 2 4 5 8 10 16 20 25 32 40 50 64 80 100]; %oversampling rates 
corresponding to oversampling mode
os=osf(osm);            % actual oversampling factor

CycleTimeSync1=double(uint32(tsample(1)*(1-1/os)*1e9));

%% -------------Slave Configuration------------------

rv.SlaveConfig.vendor=2;
rv.SlaveConfig.product=hex2dec('50219349');
rv.SlaveConfig.description='ELM3604-0002';
if os>1
    rv.SlaveConfig.dc=[hex2dec('0730') 0 -os -250000 1 1 CycleTimeSync1 0 0 0 
]; % DC-Setup [Assign_Activate Cycle_Time_Sync0 Cycle_Time_Sync0_Factor 
Shift_Time_Sync0 Shift_Time_Sync0_Factor Shift_Time_Sync0_Input 
Cycle_Time_Sync1 Cycle_Time_Sync1_Factor Shift_Time_Sync1 
Shift_Time_Sync1_Factor]

end
%% --------------SyncManager (Sm) Configuration------

rv.SlaveConfig.sm={ ...
    {0, 0, {}}, ...
    {1, 1, {}},...
    {2, 0, {}},...
    {3, 1, {
        {hex2dec('1a00'), [ % PAI TxPDO-Map Status Ch.1
            hex2dec('6000'), 01, 08;            %   No of Samples   8bit
            hex2dec('6000'), 09, 1;             %   Error           1 bit
            hex2dec('6000'), hex2dec('0a'), 1;  %   Underrange      1 bit
            hex2dec('6000'), hex2dec('0b'), 1;  %   Overrange       1 bit
            hex2dec('0000'), hex2dec('00'), 1;  %   Gap             1 bit
            hex2dec('6000'), hex2dec('0d'), 1;  %   Diag            1 bit
            hex2dec('6000'), hex2dec('0e'), 1;  %   TxPDO State     1 bit
            hex2dec('6000'), hex2dec('0f'), 2;  %   Input Cycle Counter       2 
bit
            hex2dec('0000'), hex2dec('00'), 16;  %  Gap             16 bit
            ]},...
           
        {hex2dec('1a00')+osm,[  % PAI TxPDO-Map Samples 1 Ch.1
             horzcat(ones(os,1)*hex2dec('6001'), [1:1:os]', ones(os,1)*32); % 
Chn1 values
            ]},...
            
        {hex2dec('1a21'),[  % PAI TxPDO Status Ch. 2
            hex2dec('6010'), 01, 08;            %   No of Samples   8bit
            hex2dec('6010'), 09, 1;             %   Error           1 bit
            hex2dec('6010'), hex2dec('0a'), 1;  %   Underrange      1 bit
            hex2dec('6010'), hex2dec('0b'), 1;  %   Overrange       1 bit
            hex2dec('0000'), hex2dec('00'), 1;  %   Gap             1 bit
            hex2dec('6010'), hex2dec('0d'), 1;  %   Diag            1 bit
            hex2dec('6010'), hex2dec('0e'), 1;  %   TxPDO State     1 bit
            hex2dec('6010'), hex2dec('0f'), 2;  %   Input Cycle Counter       2 
bit
            hex2dec('0000'), hex2dec('00'), 16;  %  Gap             16 bit
            ]},...
            
        {hex2dec('1a21')+osm,[  % PAI TxPDO-Map Samples 1 Ch.2
             horzcat(ones(os,1)*hex2dec('6011'), [1:1:os]', ones(os,1)*32); % 
Chn2 values
            ]},...
            
        {hex2dec('1a42'),[  % PAI TxPDO Status Ch. 3
            hex2dec('6020'), 01, 08;            %   No of Samples   8bit
            hex2dec('6020'), 09, 1;             %   Error           1 bit
            hex2dec('6020'), hex2dec('0a'), 1;  %   Underrange      1 bit
            hex2dec('6020'), hex2dec('0b'), 1;  %   Overrange       1 bit
            hex2dec('0000'), hex2dec('00'), 1;  %   Gap             1 bit
            hex2dec('6020'), hex2dec('0d'), 1;  %   Diag            1 bit
            hex2dec('6020'), hex2dec('0e'), 1;  %   TxPDO State     1 bit
            hex2dec('6020'), hex2dec('0f'), 2;  %   Input Cycle Counter       2 
bit
            hex2dec('0000'), hex2dec('00'), 16;  %  Gap             16 bit
            ]},...
            
        {hex2dec('1a42')+osm,[  % PAI TxPDO-Map Samples 1 Ch.3
             horzcat(ones(os,1)*hex2dec('6021'), [1:1:os]', ones(os,1)*32); % 
Chn3 values            
            ]},...
            
        {hex2dec('1a63'),[  % PAI TxPDO Status Ch. 4
            hex2dec('6030'), 01, 08;            %   No of Samples   8bit
            hex2dec('6030'), 09, 1;             %   Error           1 bit
            hex2dec('6030'), hex2dec('0a'), 1;  %   Underrange      1 bit
            hex2dec('6030'), hex2dec('0b'), 1;  %   Overrange       1 bit
            hex2dec('0000'), hex2dec('00'), 1;  %   Gap             1 bit
            hex2dec('6030'), hex2dec('0d'), 1;  %   Diag            1 bit
            hex2dec('6030'), hex2dec('0e'), 1;  %   TxPDO State     1 bit
            hex2dec('6030'), hex2dec('0f'), 2;  %   Input Cycle Counter       2 
bit
            hex2dec('0000'), hex2dec('00'), 16;  %  Gap             16 bit      
  
            ]},...
            
        {hex2dec('1a63')+osm,[  % PAI TxPDO-Map Samples 1 Ch.4
             horzcat(ones(os,1)*hex2dec('6031'), [1:1:os]', ones(os,1)*32); % 
Chn4 values            
            ]},...     
        }},...
    };
    
%% Port Configuration
% .output(x).pdo=[ SyncManagerIndex PDOIndex EntryIndex ElementIndex] 
 
% Chn 1 Values
rv.PortConfig.output(1).pdo=horzcat(ones(os,1)*3,ones(os,1),[0:1:(os-1)]',zeros(os,1));
rv.PortConfig.output(1).pdo_data_type=sint(32);
rv.PortConfig.output(1).portname='Chn1_Values';

%Chn 2 Values
rv.PortConfig.output(end+1).pdo=horzcat(ones(os,1)*3,ones(os,1)*3,[0:1:(os-1)]',zeros(os,1));
rv.PortConfig.output(end).pdo_data_type=sint(32);
rv.PortConfig.output(end).portname='Chn2_Values';

%Chn 3 Value
rv.PortConfig.output(end+1).pdo=horzcat(ones(os,1)*3,ones(os,1)*5,[0:1:(os-1)]',zeros(os,1));
rv.PortConfig.output(end).pdo_data_type=sint(32);
rv.PortConfig.output(end).portname='Chn3_Values';

%Chn 4 Value
rv.PortConfig.output(end+1).pdo=horzcat(ones(os,1)*3,ones(os,1)*7,[0:1:(os-1)]',zeros(os,1));
rv.PortConfig.output(end).pdo_data_type=sint(32);
rv.PortConfig.output(end).portname='Chn4_Values';

if StatusOutput
    %Chn1 State
    rv.PortConfig.output(end+1).pdo=[%3 0 0 0;   % no of values
                                     3 0 1 0;   % error
                                     3 0 2 0;   % Underrange
                                     3 0 3 0;   % Overrange
                                     3 0 5 0;   % Diag
                                     3 0 6 0;   % TxPDOState
                                    % 3 0 7 0   % InputCycleCounter             
                   
                                     ];
    rv.PortConfig.output(end).pdo_data_type=1001;
    rv.PortConfig.output(end).portname='Chn1_State';
    %Chn2 State
    rv.PortConfig.output(end+1).pdo=[%3 2 0 0;   % no of values
                                     3 2 1 0;   % error
                                     3 2 2 0;   % Underrange
                                     3 2 3 0;   % Overrange
                                     3 2 5 0;   % Diag
                                     3 2 6 0;   % TxPDOState
                                    % 3 2 7 0   % InputCycleCounter             
                   
                                     ];
    rv.PortConfig.output(end).pdo_data_type=1001;
    rv.PortConfig.output(end).portname='Chn2_State';
    %Chn3 State
    rv.PortConfig.output(end+1).pdo=[%3 4 0 0;   % no of values
                                     3 4 1 0;   % error
                                     3 4 2 0;   % Underrange
                                     3 4 3 0;   % Overrange
                                     3 4 5 0;   % Diag
                                     3 4 6 0;   % TxPDOState
                                    % 3 4 7 0   % InputCycleCounter             
                   
                                     ];
    rv.PortConfig.output(end).pdo_data_type=1001;
    rv.PortConfig.output(end).portname='Chn3_State';
    
    %Chn4 State
    rv.PortConfig.output(end+1).pdo=[%3 6 0 0;   % no of values
                                     3 6 1 0;   % error
                                     3 6 2 0;   % Underrange
                                     3 6 3 0;   % Overrange
                                     3 6 5 0;   % Diag
                                     3 6 6 0;   % TxPDOState
                                    % 3 6 7 0   % InputCycleCounter             
                   
                                     ];
    rv.PortConfig.output(end).pdo_data_type=1001;
    rv.PortConfig.output(end).portname='Chn4_State';

end

 
%% Sdo Configuration
% {SDO Index, SDO SubIndex, Data type, Value; next...}

rv.SlaveConfig.sdo = {  hex2dec('8000'),1,16,107;   % Chn1 measurement 
Configuration 0: none, 97: +-10V 98: +-5V 99: +-2.5V 100: +-1.25V 101: +-640mV 
102 +-320mV 103: +-160mV 104 +-80mV 105: +- 40mV 106: +-20mV 107: 0..20V; 108: 
0..10V
                        hex2dec('8000'),3,16,0;     % Chn1 IEPE AC Coupling 0: 
off 1: 0.001 Hz 2:0.01Hz 3:0.1Hz 4:1Hz 5:10Hz
                        %hex2dec('8000'),4,1,0;     % Chn1 start connection 
test on rising edge
                        hex2dec('8000'),7,8,2;      % Chn1 IEPE Bias Current 0: 
0mA 1: 2mA 2: 4mA
                        
                        hex2dec('8010'),1,16,107;   % Chn2 measurement 
Configuration 0: none, 97: +-10V 98: +-5V 99: +-2.5V 100: +-1.25V 101: +-640mV 
102 +-320mV 103: +-160mV 104 +-80mV 105: +- 40mV 106: +-20mV 107: 0..20V; 108: 
0..10V
                        hex2dec('8010'),3,16,0;     % Chn2 IEPE AC Coupling 0: 
off 1: 0.001 Hz 2:0.01Hz 3:0.1Hz 4:1Hz 5:10Hz
                        %hex2dec('8010'),4,1,0;     % Chn2 start connection 
test on rising edge
                        hex2dec('8010'),7,8,2;      % Chn2 IEPE Bias Current 0: 
0mA 1: 2mA 2: 4mA
                        
                        hex2dec('8020'),1,16,107;   % Chn3 measurement 
Configuration 0: none, 97: +-10V 98: +-5V 99: +-2.5V 100: +-1.25V 101: +-640mV 
102 +-320mV 103: +-160mV 104 +-80mV 105: +- 40mV 106: +-20mV 107: 0..20V; 108: 
0..10V
                        hex2dec('8020'),3,16,0;     % Chn3 IEPE AC Coupling 0: 
off 1: 0.001 Hz 2:0.01Hz 3:0.1Hz 4:1Hz 5:10Hz
                        %hex2dec('8020'),4,1,0;     % Chn3 start connection 
test on rising edge
                        hex2dec('8020'),7,8,2;      % Chn3 IEPE Bias Current 0: 
0mA 1: 2mA 2: 4mA
                        
                        hex2dec('8030'),1,16,107;   % Chn4 measurement 
Configuration 0: none, 97: +-10V 98: +-5V 99: +-2.5V 100: +-1.25V 101: +-640mV 
102 +-320mV 103: +-160mV 104 +-80mV 105: +- 40mV 106: +-20mV 107: 0..20V; 108: 
0..10V
                        hex2dec('8030'),3,16,0;     % Chn4 IEPE AC Coupling 0: 
off 1: 0.001 Hz 2:0.01Hz 3:0.1Hz 4:1Hz 5:10Hz
                        %hex2dec('8030'),4,1,0;     % Chn4 start connection 
test on rising edge
                        hex2dec('8030'),7,8,2;      % Chn4 IEPE Bias Current 0: 
0mA 1: 2mA 2: 4mA                        
                     };
end





-- 
Amos Merkel, M.Sc.
Group leader
Digitalization & Automation

ifas - Institute for Fluid Power Drives and Systems
RWTH Aachen University
Campus-Boulevard 30
52074 Aachen

Tel: +49 241 80-47737
Fax: +49 241 80-647712
-- 
Etherlab-users mailing list
Etherlab-users@etherlab.org
https://lists.etherlab.org/mailman/listinfo/etherlab-users

Reply via email to