[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