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.lamb...@tomra.com> Gesendet: Donnerstag, 27. Mai 2021 01:57 An: Merkel, Amos <amos.mer...@ifas.rwth-aachen.de>; etherlab-users@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@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