Beispielprogramm 7 (Allgemeine Dezimierung in der PLC)
Die EL3751/ ELM3xxx Klemmen können eine Dezimierung ihrer Basisabtastrate fmax nur durch ganzzahlige Vielfache durchführen, siehe dazu das Kapitel „Dezimierung“. Um auch beliebige andere Abtastraten fZiel < fmax für einen Kanal zu realisieren, kann beispielsweise wie folgt vorgegangen werden:
- Klemme/ Kanal mit maximaler Abtastrate betreiben und die Daten über EtherCAT/Oversampling in die Steuerung (PLC) übertragen
- Dort in der PLC/ C++ auf der Zeitachse in die gewünschte Abtastrate umrechnen, z.B. mittels linearer Interpolation auf Basis der Zeitstempel je Eingangswert (Sample). Da die EL3751/ ELM3xxx auf DistributedClocks-basierend zeit-äquidistante Samples liefern, ist das einfach möglich.
Folgende Abbildung zeigt einen Ausschnitt eines mit 50/44,1 = 1/0,882 dezimierten sinusförmigen Signals: - Grün: entspricht Original- Eingangssignal analog, ca. 432 Hz
- Blau (O): entspricht Abtastung der EL3751/ ELM3xxx mit fmax = 10.000 Sps bzw. einem Abtastintervall von 100 µs
- Rot (X): entspricht in PLC umgerechnetes Signal auf 8820 Sps (Faktor 0,882) und damit ein Zeitintervall von ca. 113,37.. µs
- Hinweis: Der Begriff „Dezimierung“ wird hier sowohl angewendet auf die Rechnung in der Klemme (siehe dazu das Kapitel „Dezimierung“) als auch auf die Umrechnung im PLC-Programm. Im Folgenden ist dabei die Umrechnung in der PLC gemeint.
- Da hierbei das Zeitintervall der angestrebten Abtastung nach der Dezimierung in PLC i.d.R. keine ganze (endliche) Zahl mehr ist, wird für die Darstellung im PLC/Scope Wert/Zeit-Paare verwendet, d.h. jedem Y-Wert ist ein X-Zeitwert zugeordnet. Solche Wert/Zeit-Paare lassen sich mit dem TwinCAT ScopeView im XY-Modus einfach darstellen. Siehe hierzu auch unter infosys.beckhoff.com:
TwinCAT3 → TExxxx | TC3 Engineering → TE13xx | TC3 ScopeView → Konfiguration → XY‑Graph - Außerdem hat die Umrechnung Folgen für die Weiterverarbeitung in PLC/C/ADS:
- Üblicherweise ist ein PLC/EtherCAT/TwinCAT-System so eingestellt dass je Zyklus eine konstante Anzahl Samples verarbeitet wird – das ist nun i.d.R. nicht mehr der Fall: es kommt von Zyklus zu Zyklus zu einer unterschiedlicher Anzahl Samples die zu verarbeiten sind (Angabe durch die Programmvariable nResultNoOfSamples).
- Blieb ein Zeitstempel pro Signalwert bisher relativ bedeutungslos, so führt jedoch die hier angewandte Art der Umsetzung des Dezimierungsvorgangs dazu, dass der jeweilige Zeitstempel pro Signalwert elementar zu beachten ist.
- Die nicht konstante Anzahl von Samples wird vom TwinCAT XY‑Scope nicht sichtbar, weil hier einige Werte sporadisch doppelt gezeichnet werden, ist jedoch zu bedenken; ggf. wäre für die programmatische Weiterverarbeitung die Verwendung eines Zwischenpuffers zu empfehlen.
- Zur Orientierung der aktuell gültigen Sample-Zahl pro Taskzyklus stellt das Programm die Variable nResultNoOfSamples zur Verfügung, die angibt, welche Werte in der Arrayvariable gültige Werte in einem Taskzyklus enthalten (gibt die Feldnummer - 1 an).
Im Folgenden dient das Beispielprogramm als Orientierungshilfe, das auch die XY-Darstellung im TwinCAT Scope enthält. Wegen der o.a. Problematik der nicht konstant vorhandenen Anzahl gültiger Abtastwerte liefert das Programm für das Scope das Array-Paar aVarDecResult_TS und aVarDecResult mit der gleichen Anzahl von Elementen wie für den Eingangswert aSamples_1(Wert = nOVS ). Kommt es in einem Taskdurchlauf zu weniger Werten, wird der letzte Wert einfach wiederholt eingetragen (entspricht etwa „sample & hold“). Für die Aufzeichnung wurde das ScopeView wie folgt konfiguriert:
Eigenschaft | Wert | |
---|---|---|
ScopeNodeProperties | ViewDetauilLevel | ExtendedXYOnly |
Record time | 00:00:00:05 | |
ChartXYNodeProperties | Default Display Width | 0,00:00:00,050:000 |
Max Data Points | 200000 | |
XYChannelNodeProperties | Marks | On |
Mark Size | 5 | |
Mark Color | (andere Farbe als „Line Color“) |
Für eine veranschaulichende Darstellung wurde zunächst die Aufzeichnung des ScopeView gestartet und dann das Programm, das auf eine Sekunde begrenzt die Dezimierten Werte lieferte:
IF nOVS_CycleCount = 1000000000 THEN
;
bEnable := FALSE;// Stop after 1s just for recording
ELSE
...
Diese Zeile kann selbstverständlich für weitere Anpassungen auskommentiert werden:
//bEnable := FALSE;// Stop after 1s just for recording
Hinweise:
- die Zielabtastrate fZiel sollte in der Nähe der Samplerate fmax liegen, so dass es über die Implementierung möglich ist, ein Zeitintervall zwischen zwei dezimierten Werten auch auszuwerten. Die gewünschte Dezimierung erfordert u.U. eine Anpassung weiterer Parameter wie Taskzykluszeit, Oversamplingfaktor, etc. sowohl in der Konfiguration als auch als Variableninitialisierung im Beispielprogramm (siehe Abbildung „Vorgang der variablen Dezimierung des Beispielprogramms“ zur Funktionsweise des Programcodes).
- Grundsätzlich werden durch den Konvertierungsvorgang in diesem Beispielprogramm bei einer Dezimierung mit gebrochenen rationalen Faktoren Verzerrungen im Ergebnis in Bezug zur ursprünglichen Signalform verursacht (siehe Signalverlauf). Konkret entstehen Abweichungen vom originalen Signalverlauf nur in den Abschnitten, wo der zeitliche Ableitungswert (die Steigung) nicht konstant ist. Z.B. werden Eingangswerte eines Sinussignals in den nichtlinearen Bereichen durch die im Programm vorgenommene Interpolation verzerrt:
Im Frequenzspektrum wird dies z.B. durch eine Berechnung mit 20 Hz Sinussignal, abgetastet mit 500 Sps und dezimiert auf 441 Sps wie folgt anschaulich: - Wenn auf dem Datenstrom keine der fZiel entsprechenden Tiefpassfilterung vorgenommen wird, wird es zu Aliasing-Effekten kommen! Es ist deshalb ratsam z.B. mit der TC3 Controller Toolbox oder der TC3 Filter Lib in der PLC eine Tiefpassfilterung vorzunehmen, bevor die Umrechung/Dezimierung vorgenommen wird. Entsprechende Filter können einfach mit dem TE1310 FilterDesigner erstellt werden. Siehe hierzu unter www.beckhoff.de:
Automation → TwinCAT 3 → TE1xxx | TC3 Engineering → TE1310 | TC3 Filter Designer
Alternativ können natürlich auch die in den EL3751/ ELM3xxx verfügbaren Filter schon auf die passende Tiefpass-Frequenz gesetzt werden, auch dazu ist der TwinCAT Filter Designer hilfreich. - Einträge des Dezimierungsfaktors im Programm (nDecimationValue) sollten einen Wert > 1 haben. Der Programmcode unterstützt lediglich das „downsampling“.
Beispiel: Stellt eine Klemme wie ELM3602‑0002 (2-Kanal-IEPE-Auswertung) einen Datenstrom mit Oversampling von 50 kSps bei 100µs Zykluszeit zur Verfügung, so kann dieser Beispielcode eine Dezimierung auf 44,1 kSps vornehmen. Im Beispielprogramm wären dazu die Zyklusticks in der Taskkonfiguration von 5 auf 1 sowie die entsprechende Programmvariable nTaskCycle_ns von 500000 auf 100000 zu ändern. Siehe folgenden Bildausschnitt des ScopeView XY:
Der Dezimierungsfaktor ist durch Eintrag des Wertes „50/44.1“ für nDecimationValue im Beispiel vorgegeben. Wird dieses Beispiel für die EL3751 mit 500 µs Zykluszeit und 5x Oversampling verwendet, wird das Abtastintervall von 100 µs, das von der EL3751 kommt, zu ca. 113,378.. µs umgerechnet. Dementsprechend ist dieses Beispiel ausgelegt.
Die Dezimierung im Programm ist frei wählbar und muss mit Oversamplingfaktor und Taskzykluszeit abgestimmt konfiguriert sein. Die Variable nOVS muss den gleichen Oversamplingfaktor enthalten, wie dieser über die Prozessdatenkonfiguration eingestellt ist.
Download Beispielprogramm 7:
- Konfiguration: IPC + EK1100 + EL3751 + EL9011:
Programmlink - Konfiguration: IPC + EK1100 + ELM3602‑0002 + EL9011:
Programmlink
Hinweis: Bei Verwendung einer EtherCAT-Box wie EPP35xx entfällt der EtherCAT-Koppler EK1100.
Allgemeiner Hinweis
Der Zeitpunkt der Passage der EtherCAT Frames an der Klemme unterliegt Schwankungen, dem EtherCAT‑Frame-Jitter. Falls diese Schwankungen groß im Verhältnis zur Zykluszeit sind, werden u.U. Daten verspätet von der Klemme abgeholt, es kommt in der Scope-Darstellung zu Aussetzern/ Dopplungen. Mit der TwinCAT EtherCAT Diagnose können solche Effekte diagnostiziert werden. In dem Beispielprogramm zur ELM3602 steht zu dieser Kontrolle die Variable nEqualTimeStampsCnt zur Verfügung, die inkrementiert wird, falls ein solcher Ausfall auftritt. Abhilfe schafft die Veränderung der DC ShiftTime der Klemme, siehe dazu die EtherCAT Systemdokumentation.
Deklarationsteil
// THIS CODE IS ONLY AN EXAMPLE - YOU HAVE TO CHECK APTITUDE FOR YOUR APPLICATION
PROGRAM MAIN
VAR CONSTANT
// User decimation factor e.g. 50 to 44.1 kSps:
nDecimationValue :LREAL := 50/44.1; // 50/20;
nOVS :BYTE := 5; // Oversampling factor
nTaskCycle_ns :UDINT := 500000; // PlcTask configured cycle time in ns
nOVSTimeInterval_ns :UDINT := LREAL_TO_UDINT(nTaskCycle_ns/nOVS); // OVS interval
nDecTimeInterval_ns :LREAL := nDecimationValue * nOVSTimeInterval_ns; // Decimation interval
END_VAR
VAR
aSamples_1 AT%I* :ARRAY[0..nOVS-1] OF DINT; // Link to the terminal PDO
aOVS_SampleSets :ARRAY[0..(2*nOVS)-1] OF DINT; // 2 OVS sample sets
nVarDecResult :DINT; // The calculated interpolated value
tVarDecResult :LREAL; // Decimation timestamp
aVarDecResult :ARRAY[0..nOVS-1] OF DINT; // Decimation result values
aVarDecResult_TS :ARRAY[0..nOVS-1] OF LREAL; // Decimation result timestamps
nResultNoOfSamples :BYTE; // This is for the user for further processing
nDivVar :INT; // Value for selection of the target input element
tDecVar_InTaskCycle :LREAL:=0; // Time span for all decimation timestamps within a task cycle
i :BYTE:=0; // Common loop counter
nDX :LREAL; // X-Difference: target input element to decimation element
nDY :DINT; // Y-Difference: two values for interpolation
sVal :LREAL; // Slope for calculation of new value
bEnable :BOOL:=FALSE; // Start/Stop conversion to decimation values
nOVS_CycleCount :ULINT := 0; // Time value for every OVS sample
// Values for testing
bTEST_VALUES_ENABLED :BOOL := FALSE; // No input value needed, if TRUE
nPhi :LREAL := 1.4; // Start angle for sinus simulation
// For visualization only:
aOVS_Samples :ARRAY[0..nOVS-1] OF DINT; // 2 OVS sample sets (value)
aOVS_Samples_TS :ARRAY[0..nOVS-1] OF ULINT; // 2 OVS sample sets (timestamp)
END_VAR
Ausführungsteil
// 500 µs Task
FOR i:= 0 TO nOVS-1 DO
// Shift OVS set to left and update on right:
aOVS_SampleSets[i] := aOVS_SampleSets[i+nOVS]; // Transfer "samples set" to the left side
IF bTEST_VALUES_ENABLED THEN
// Simulate values:
aOVS_SampleSets[i+nOVS] := LREAL_TO_DINT(1000000 * SIN(nPhi));
nPhi := nPhi + 0.01;//0.003141592653;
ELSE
// Fill current new samples set on right:
aOVS_SampleSets[i+nOVS] := aSamples_1[i];
END_IF
END_FOR
IF bEnable THEN
nResultNoOfSamples := 0; // Use for further processing
FOR i := 0 TO nOVS-1 DO
nDivVar := TRUNC_INT(tDecVar_InTaskCycle/nOVSTimeInterval_ns);
// Check, if new value is in grid
IF (nDivVar = i) THEN
nResultNoOfSamples := nResultNoOfSamples + 1;
// Calc slope by the left and right element values (dy/dx):
nDY := aOVS_SampleSets[i+1] - aOVS_SampleSets[i];
sVal := DINT_TO_LREAL(nDY)/nOVSTimeInterval_ns;
// Get the time (difference) from the left side element start to the desired time point:
nDX := tDecVar_InTaskCycle
- TRUNC_INT(tDecVar_InTaskCycle/nOVSTimeInterval_ns)
* UDINT_TO_LREAL(nOVSTimeInterval_ns);
// Calc timestamp
tVarDecResult := nDX + ULINT_TO_LREAL(nOVS_CycleCount);
// Calc new value:
nVarDecResult :=
LREAL_TO_DINT(DINT_TO_LREAL(aOVS_SampleSets[i]) + sVal * nDX);
// next decimation time step
tDecVar_InTaskCycle := tDecVar_InTaskCycle + nDecTimeInterval_ns;
tDecVar_InTaskCycle := tDecVar_InTaskCycle
- INT_TO_UDINT(TRUNC_INT(tDecVar_InTaskCycle/nTaskCycle_ns))
* nTaskCycle_ns;
END_IF
// Fill timestamp and new value allocated to the field element of its timestamp
aVarDecResult_TS[i] := tVarDecResult;
aVarDecResult[i] := nVarDecResult;
// For visualization of the original input:
aOVS_Samples[i] := aOVS_SampleSets[i];
aOVS_Samples_TS[i] := nOVS_CycleCount;
// Count the task cycle timestamp
nOVS_CycleCount := nOVS_CycleCount + nOVSTimeInterval_ns;
END_FOR
END_IF
IF nOVS_CycleCount = 1000000000 THEN
bEnable := FALSE;// Stop after 1s just for recording
IF NOT bEnable THEN
bEnable := TRUE; // OVS‑Samples transferred complete into both array sets
END_IF
END_IF