[Etherlab-users] Distributed Clocks and Oversampling - slave configuration of the ELM3604-002

Merkel, Amos Amos.Merkel at ifas.rwth-aachen.de
Thu May 27 11:49:11 CEST 2021


Hi Gavin,

thanks a lot for your explanations! 

I had the effect with two different PCs with quite different hardware and setup and the 4kHz seemed a pretty fixed limit, so I am expecting my problem to be more in the area of my DC Configuration instead of the drivers. 
The patchset I know and use, but so far I have avoided using dedicated drivers, so maybe this is worth a try as well. 

Right now I do not have access to the hardware - pandemic home office - but I will try your suggestions as soon as I can. 

Thanks again! 

-- 
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

www.ifas.rwth-aachen.de | Twitter | Facebook | YouTube | LinkedIn


-----Ursprüngliche Nachricht-----
Von: Gavin Lambert <gavin.lambert at tomra.com> 
Gesendet: Donnerstag, 27. Mai 2021 01:57
An: Merkel, Amos <Amos.Merkel at ifas.rwth-aachen.de>; etherlab-users at etherlab.org
Betreff: RE: Distributed Clocks and Oversampling - slave configuration of the ELM3604-002

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 at 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


More information about the Etherlab-users mailing list