Schnelles Loggen mit Datenpuffer

Um Daten auch im Millisekunden Takt in eine Datenbank zu loggen, müssen diese zuvor zusammengefasst werden, bevor sie über den TwinCAT Database Server zur Datenbank übertragen werden. Diese sogenannten Datenpuffer können in ihrer Größe je nach Anforderung variieren. In dem Beispiel werden 100 Datensamples in einem Puffer zusammengefasst, bevor sie mit dem TwinCAT Database Server übertragen werden. Um keine Lücken durch den Schreibvorgang zu erhalten, müssen mehrere Puffer angelegt werden, in denen die Datensamples zusammengefasst werden. In dem Beispiel sind insgesamt 20 Puffer mit Hilfe eines 2-Dimensionalen Arrays angelegt.

Datensample

Definition:

TYPE ST_Data :
STRUCT
    Timestamp        : LINT;
    fAM              : LREAL;
    fPeak            : LREAL;
    fPulse           : LREAL;
    fSawtooth        : LREAL;
    fSine            : LREAL;
    fSquare          : LREAL;
    fStairs          : LREAL;
    fTriangular      : LREAL;
END_STRUCT
END_TYPE

Jeden Zyklus wird ein Element des Datenpuffers befüllt. Im Beispiel geschieht dies im 10ms Takt. Somit enthält ein Puffer Daten eines Zeitraums von 1s. Ist ein Puffer mit 100 Elementen gefüllt, wird durch ein weiteres Array signalisiert, dass die 100 Elemente nun mit dem Baustein FB_PLCDBCmdEvt übertragen werden können. Hierfür kann der gesamte Puffer dem Baustein übergeben werden. Jedes einzelne Element wird dann vom TwinCAT Database Server zur Datenbank übertragen. Dieses Beispiel kann auch mit anderen Bausteinen umgesetzt werden. Beachten Sie dabei, dass nicht alle Funktionsbausteine Arrays unterstützen.

Auszug aus dem Baustein FB_Record_tbl_Signals

( „State-Machine“ => State: Recording)


    2://Recording
        bRecording := TRUE;

        //Fill buffer
        stData[nWriteBufferIndex, nWriteIndex].Timestamp := nTimestamp;
        stData[nWriteBufferIndex, nWriteIndex].fAM := fAM;
        stData[nWriteBufferIndex, nWriteIndex].fPeak := fPeak;
        stData[nWriteBufferIndex, nWriteIndex].fPulse := fPulse;
        stData[nWriteBufferIndex, nWriteIndex].fSawtooth := fSawtooth;
        stData[nWriteBufferIndex, nWriteIndex].fSine := fSine;
        stData[nWriteBufferIndex, nWriteIndex].fSquare := fSquare;
        stData[nWriteBufferIndex, nWriteIndex].fStairs := fStairs;
        stData[nWriteBufferIndex, nWriteIndex].fTriangular := fTriangular;

        //Set buffer index
        nWriteIndex := nWriteIndex + 1;
        IF nWriteIndex = 100 THEN
            nWriteIndex := 0;
            aWriteSQL[nWriteBufferIndex]:= TRUE;
            nWriteBufferIndex := nWriteBufferIndex + 1;

            IF nWriteBufferIndex = 20 THEN
                nWriteBufferIndex := 0;
            END_IF

            IF aWriteSQL[nWriteBufferIndex] THEN
                nState := 255;
                RETURN;
            END_IF
        END_IF

        //Write buffer element (100 samples) to database
        IF aWriteSQL[nSQLIndex] THEN
            IF fbPLCDBCmd.Execute(nDBID, ADR(sCmd), SIZEOF(sCmd),
                                 ADR(stData[nSQLIndex,0]), SIZEOF(stData[nSQLIndex,0]) * 100,
                                 ADR(aPara), SIZEOF(aPara)) THEN
                IF fbPLCDBCmd.bError THEN
                    nState := 255;
                ELSE
                    nRecords := nRecords + 100;

                    aWriteSQL[nSQLIndex] := FALSE;

                    nSQLIndex := nSQLIndex + 1;
                    IF nSQLIndex = 20 THEN
                        nSQLIndex := 0;
                    END_IF

                    IF NOT bRecord THEN
                        bRecording := FALSE;
                        nState := 0;
                    END_IF
                END_IF
            END_IF
        END_IF
….

Anhang:

In diesem Best Practise wird mit Hilfe eines Funktionsgenerator Bausteins verschiedene Signale erzeugt, die in eine Datenbank geloggt werden können. Die Syntax des INSERT Kommandos ist allgemeingültig, wurde aber im speziellen mit einer MS SQL Datenbank getestet. Das unten angefügte ZIP enthält den kompletten Programmcode in Form eines Tnzip.

Download:TF6420_BestPractise_Buffer.zip