Json-Datei mit Kurvendaten auslesen

Koernerbrot

Level-2
Beiträge
20
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen,

ich baue gerade ein kleines Nebenprogramm, welches zum Start des Hauptprogrammes Json-Dateien einlesen soll, um die Motoren mit individuellen Camming Kurven zu bestücken. Alles schön und gut, befolge ich den Starting-Guid im Infosys zur jsonxml Bibliothek ( https://infosys.beckhoff.com/index....1031/tcplclib_tc3_jsonxml/3916587275.html&id= ). Syntax verstanden und auf mein Problem hin umgewandelt, heraus kam das hier als meine Variablenliste:

C-ähnlich:
FUNCTION_BLOCK Json_Parser_Kontraer
VAR_INPUT
    Execute            : BOOL;
    FilePath        : STRING;
END_VAR
VAR_OUTPUT
    Cam_REF            : MC_CAM_REF;
    Busy            : BOOL;
    Error            : BOOL;
    Done            : BOOL;
END_VAR
VAR
    jsonParser        : FB_JsonDomParser;
    jsonProp        : SJsonValue;
    jsonRoot        : SJsonValue;
    jsonIterator     : SJsonValue;
    jsonIteratorEnd : SJsonValue;
    
    ArrayOutput        : ARRAY[0..359,0..1] OF LREAL;
    x                : INT;
    y                : INT;
    Status            : INT;
END_VAR

Und das als mein eigentlicher Code:

Code:
IF Execute = TRUE THEN
    //Datei öffnen und nach Master Array suchen
    jsonParser.LoadDocumentFromFile('C:\Kurventest\Kontraerbewegung_Beispiel.json',Execute);
    jsonRoot := jsonParser.GetDocumentRoot();
    IF jsonRoot <> 0 THEN
        jsonProp := jsonParser.FindMember(jsonRoot, 'Master');
    ELSE
        Error := TRUE;
        RETURN;
    END_IF
    //Überprüfen ob der Array nicht leer ist
    IF (jsonProp <> 0) THEN
        jsonIterator := jsonParser.ArrayBegin(jsonProp);
        jsonIteratorEnd := jsonParser.ArrayEnd(jsonProp);
        WHILE jsonIterator <> jsonIteratorEnd DO
            IF (jsonProp <> 0) THEN
                ArrayOutput[x,0] := jsonParser.GetInt(jsonIterator);
            ELSE
                Error := TRUE;
                RETURN;
            END_IF
            jsonIterator := jsonParser.NextArray(jsonIterator);
            x := x + 1;
        END_WHILE
        x := 0;
    //Das selbe wird nochmal für den "Slave" wiederholt
        jsonProp := jsonParser.FindMember(jsonRoot, 'Slave');
        jsonIterator     := jsonParser.ArrayBegin(jsonProp);
        jsonIteratorEnd := jsonParser.ArrayEnd(jsonProp);
        WHILE jsonIterator <> jsonIteratorEnd DO
            IF (jsonProp <> 0) THEN
                ArrayOutput[x,1] := jsonParser.GetINT(jsonIterator);
            ELSE
                Error := TRUE;
                RETURN;
            END_IF
            jsonIterator := jsonParser.NextArray(jsonIterator);
            x := x + 1;
        END_WHILE
        x := 0;
    
    //Array in MC_CAM_REF schieben
        IF SIZEOF(ArrayOutput) > 0 THEN
            Cam_REF.pArray         := ADR(ArrayOutput);
            Cam_REF.ArraySize     := SIZEOF(ArrayOutput);
            Cam_REF.TableType    := MC_TABLETYPE_EQUIDISTANT;
            Cam_REF.NoOfRows    := 360;
            Cam_REF.NoOfColumns := 2;
            Done                 := TRUE;
            Busy                := TRUE;
        ELSE
            Error := TRUE;
            RETURN;
        END_IF
    ELSE
        Error := TRUE;
        RETURN;
    END_IF
END_IF

Ausprobiert und ... Error, jsonProp bleibt 0 obwohl im jsonRoot etwas drinnen steht wenn es startet. Daraufhin habe ich selber nach Fehlern geguckt, auch welche gefunden, aber alle nur in den anderen Teilen meines Codes. KI gefragt: Hat nur Verbesserungsvorschläge fürs Error Handling, Externen von Beckhoff selber gefragt: Sieht ihm alles richtig aus, weiß nicht warum es nicht klappen sollte.

Ich selber bin überfragt, liegt es daran das ich die Dateien auf meinem PC liegen habe und nicht auf der PLC selber liegen? (Ist so ne Beckhoff SpS mit Touchscreen, läuft Windows 10 drauf) Meine Json Datei hat auch das richtige Format und ich habe es auch mit einer kleineren Datei versucht. (Original sind es zwei Arrays mit jeweils 360 Werten, zum Testen bin ich mal auf jeweils 6 Werten runtergegangen.)

Die Funktion wird in meinem Hauptprogramm als Funktionsbaustein implementiert um 4 unterschiedliche Kurven lesen zu können zum testen habe ich jetzt aber Manuell ein Dateinspeicherort festgelegt.
 
Findet er das jsonProb vom Master nicht oder vom Slave? Oder von Beiden?

Wenn im JsonRoot was drin steht, müsste auch die Datei geöffnet worden sein. Es könnte Sinn machen das jsonRoot vor dem 2. Durchlauf noch mal zu ermitteln.

Dein Json müsste in etwa so aussehen:

JSON:
{
  "Master": [1, 2, 3],
  "Slave": [4, 5, 6]
}

Du könntest mit der IsArray-Methode dann noch testen ob die jsonProp als Array erkannt wird.


Code:
IF Execute = TRUE THEN
    //Datei öffnen und nach Master Array suchen
    jsonParser.LoadDocumentFromFile('C:\Kurventest\Kontraerbewegung_Beispiel.json',Execute);

    FOR i := 0 TO 1 DO
         sArrayName := 'Master';
 
         IF i > 0 THEN
                sArrayName := 'Slave';
         END_IF;

         jsonRoot := jsonParser.GetDocumentRoot();
         IF jsonRoot = 0 THEN
              Error := TRUE;
              RETURN;
          ELSE
              jsonProp := jsonParser.FindMember(jsonRoot, sArrayName);
  
              //Überprüfen ob der Array nicht leer ist
              IF (jsonProp = 0) AND jsonParser.IsArray(jsonProp) THEN
                  Error := TRUE;
                  RETURN;
              ELSE
                  jsonIterator := jsonParser.ArrayBegin(jsonProp);
                  jsonIteratorEnd := jsonParser.ArrayEnd(jsonProp);
                  WHILE jsonIterator <> jsonIteratorEnd DO
                      IF (jsonProp <> 0) THEN
                          ArrayOutput[x,i] := jsonParser.GetInt(jsonIterator);
                      ELSE
                          Error := TRUE;
                          RETURN;
                      END_IF
                      jsonIterator := jsonParser.NextArray(jsonIterator);
                      x := x + 1;
                    END_WHILE
                    x := 0;
              END_IF
          END_IF;
   END_FOR;

    //Array in MC_CAM_REF schieben
    IF SIZEOF(ArrayOutput) = 0 THEN
        Error := TRUE;
        RETURN;
    ELSE
        Cam_REF.pArray         := ADR(ArrayOutput);
        Cam_REF.ArraySize     := SIZEOF(ArrayOutput);
        Cam_REF.TableType    := MC_TABLETYPE_EQUIDISTANT;
        Cam_REF.NoOfRows    := 360;
        Cam_REF.NoOfColumns := 2;
        Done                 := TRUE;
        Busy                := TRUE;

    END_IF
END_IF
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Er füllt jsonRoot zwar aus, aber in der findmember(...,'Master') Zeile wird jsonProp nicht beschrieben, durch meine Fehlererkennung wird er somit direkt rausgeleitet also Slave wird nicht berührt bisher.
 
Eventuell liegt es auch daran, dass das Lesen der Datei nicht fertig ist.

Code:
IF Execute THEN
      jsonParser.LoadDocumentFromFile('C:\Kurventest\Kontraerbewegung_Beispiel.json',Execute, hrErrorCode => hr);
END_IF;

// File Load done
IF NOT Execute AND SUCCEEDED(hr) THEN
    //Datei öffnen und nach Master Array suchen
 
    FOR i := 0 TO 1 DO
         sArrayName := 'Master';
 
         IF i > 0 THEN
                sArrayName := 'Slave';
         END_IF;

         jsonRoot := jsonParser.GetDocumentRoot();
         IF jsonRoot = 0 THEN
              Error := TRUE;
              RETURN;
          ELSE
              jsonProp := jsonParser.FindMember(jsonRoot, sArrayName);
 
              //Überprüfen ob der Array nicht leer ist
              IF (jsonProp = 0) AND jsonParser.IsArray(jsonProp) THEN
                  Error := TRUE;
                  RETURN;
              ELSE
                  jsonIterator := jsonParser.ArrayBegin(jsonProp);
                  jsonIteratorEnd := jsonParser.ArrayEnd(jsonProp);
                  WHILE jsonIterator <> jsonIteratorEnd DO
                      IF (jsonProp <> 0) THEN
                          ArrayOutput[x,i] := jsonParser.GetInt(jsonIterator);
                      ELSE
                          Error := TRUE;
                          RETURN;
                      END_IF
                      jsonIterator := jsonParser.NextArray(jsonIterator);
                      x := x + 1;
                    END_WHILE
                    x := 0;
              END_IF
          END_IF;
   END_FOR;

    //Array in MC_CAM_REF schieben
    IF SIZEOF(ArrayOutput) = 0 THEN
        Error := TRUE;
        RETURN;
    ELSE
        Cam_REF.pArray         := ADR(ArrayOutput);
        Cam_REF.ArraySize     := SIZEOF(ArrayOutput);
        Cam_REF.TableType    := MC_TABLETYPE_EQUIDISTANT;
        Cam_REF.NoOfRows    := 360;
        Cam_REF.NoOfColumns := 2;
        Done                 := TRUE;
        Busy                := TRUE;

    END_IF
END_IF
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Liegt die Datei zum lesen dort wo das SPS Programm ausgeführt wird? Wenn nicht probiere mal die zu lesende Datei auf deine SPS zu kopieren und dann das Programm nochmals ausführen.
 
Ich habe es gestern vorm Feierabend noch hinbekommen. Es waren zwei Fehler:

1. Datei lag nicht im IPC hätte ich mir ja denken können das der nicht auf mein PC zugreifen kann. 🙄
2. Habe ich meinen Execute nun nur mit Positiver Flanke, da der FB zum Lesen der Json sein Execute automatisch wieder ausschaltet und es somit zu einer art Dauerschleife kam.
 
Zurück
Oben