# Twincat 3 Spliting Array



## Vijolica555 (22 März 2019)

Hallo,

Ich habe Data : ARRAY [0..nRecBytes] OF BYTE. nRecBytes ist cca 800. Ich möchte split array auf cca 30 arrays wo Data _ = 32. Jemand weiß wie das zu machen?
Einfach Beispiel:
ich habe:
Data : ARRAY [0..10] OF BYTE := [5,6,7,8,32,6,5,32,9,6,32];
Ich brauche:
Data1 : ARRAY [0..4] OF BYTE :=[5,6,7,8,32]
Data2 : ARRAY [0..2] OF BYTE :=[6,5,32]
Data3 : ARRAY [0..2] OF BYTE :=[9,6,32]_


----------



## Heinileini (22 März 2019)

```
[FONT=courier new]for i := 0 to nRecBytes
    k := [/FONT][FONT=courier new][COLOR=#222222]nRecBytes mod 32
[/COLOR][/FONT][LEFT][FONT=courier new][COLOR=#222222]    j := int(nRecBytes/32)
    aZiel[j, k] := aQuell[i]
    next i
[/COLOR][/FONT][/LEFT]
```

PS: Dein einfaches Beispiel ist aber ein kompliziertes Beispiel, weil die ZielArrays unterschiedlich viele Elemente haben


----------



## PN/DP (22 März 2019)

```
aZiel : ARRAY [0..nSplit, 0..nRecBytes] OF BYTE;

j := 0; //nSplit-Index
k := 0; //Byte-Index
FOR i := 0 TO nRecBytes DO
    aZiel[j, k] := aQuell[i];
    IF aQuell[i] = 32 THEN
        j := j + 1; //nächstes Split/Ausgabe-Array
        k := 0;
    ELSE
        k := k + 1;
    END_IF;
END_FOR;
```
Eventuell erzeugt Dein ST-Compiler effizienteren Code wenn Du das umkopieren und prüfen jedes Bytes so formulierst:

```
FOR i ...
    c := aQuell[i];
    aZiel[j, k] := c;
    IF c = 32 THEN
        ...
```

Eleganter und Ressourcen-schonender wäre, wenn Du nicht in "ca." 30 Teil-Arrays zerlegst/umkopierst, sondern ein ARRAY mit 30 "Zeigern" (und evtl. Längen) verwendest. Dann brauchst Du immer nur den Index des Bytes nach dem Byte = 32 merken (und falls nötig die Anzahl Zeichen bis zum (einschließlich?) Byte mit der nächsten 32).

Wenn Deine ca. 30 Ausgabe-Arrays tatsächlich unterschiedliche Namen haben müssen (Data1, Data2, ...), dann müsstest Du nach dem Splitten noch 30 mal aus dem Array aZiel in die 30 Ausgabe-Arrays umkopieren. 
Wenn das Umkopieren oder schon das Splitten in nur einer Schleife in die 30 verschiedenen Arrays stattfinden soll, dann brauchst Du einen Pointer (auf die Ausgabe-Arrays) und bei dem "j := j + 1;" ein CASE-Konstruct, wo Du dem Pointer je nach Wert von j die Anfangsadresse des jeweiligen Ausgabe-Array zuweist:

```
j := 0;
bPointer := ADR(Data1);
FOR i := 0 TO nRecBytes DO
    bPointer^ := aQuell[i];
    IF aQuell[i] = 32 THEN
        j := j + 1; //nächstes Split/Ausgabe-Array
        CASE j OF
          1: bPointer := ADR(Data2);
          2: bPointer := ADR(Data3);
          3: bPointer := ADR(Data4);
          ...
          29: bPointer := ADR(Data30);
        END_CASE;
    ELSE
        bPointer := bPointer + 1;
    END_IF;
END_FOR;
```

Harald


----------



## Vijolica555 (25 März 2019)

Vielen dank, das hilft viel. 

Wissen sie vielleicht auch wie BYTEARR zu UINT_16 konvertieren ?


----------



## PN/DP (25 März 2019)

Meinst Du, wie Du eine Zeichenfolge von ASCII-Zeichen in einen UINT16 konvertieren kannst?
Twincat kenne ich nicht, doch da sollte es sowas wie STRING_TO_UINT geben oder spezielle/eigene Konvertierfunktionen/Bibliotheken.

Zeige uns mal ein Beispiel, aus welchen Byte-Werten Du welchen UINT-Wert erhalten willst. Und: ist die Anzahl Bytes immer gleich lang? Gibt es Vor-Nullen oder -Leerzeichen bei kleinen Zahlen? Woran sieht man das Ende der Bytefolge?

Harald


----------



## Vijolica555 (25 März 2019)

So ich habe Antwort Telegramm von Sensor. Diese Telegramm lese ich als BYTE ARRAY weil ist zu Lang für Hexstring. Wie gesagt diese Array ist lang herum 800 bytes (Je nach Befehl sende ich) Alle Parameter sind getrennt mit Leer = 32 = {SPC} in ASCII = 20 in Hex. Das ist warum brauchte ich Array Splitting. 
Ich habe 157 Werte, die ich in das UINT konvertieren muss, damit ich weitere Berechnungen durchführen kann.
ARRAYs zur konvertieren haben normalerweise 1-4 BYTES + End byte:32 und in BYTES sind normalerweise zwei nummern.

so Data_2 : ARRAY [0..3] OF BYTE := [57, 48, 55, 32]; --> 32 ist nur {SPC}, 57 48 55 ist Tail es brauche ich in UINT.
Nummern sind ohne null an Anfang. Beispiel: 55 anstatt 055


----------



## PN/DP (25 März 2019)

Dein Bild würde heißen: Du hast die Bytefolge 57,48,55,32 entspricht 16#39,16#30,16#37,16#20 entspricht '907 ' als Zeichenfolge - und die willst Du zu 907 dezimal konvertiert haben?

Ist das das selbe Telegramm wie Du oben in #1 gefragt hast? Oben wolltest Du die 800 Bytes in 30 Teile splitten, jetzt schreibst Du daß da 157 Zahlenwerte drin stecken? 
(Vielleicht verrätst Du mal wie Dein Sensor heißt und wo das Telegramm beschrieben ist - dann brauchen wir Dir nicht jede Information aus der Nase ziehen  )
Brauchst Du die gesplitteten Teil-Arrays auch noch für andere Zwecke als für die Umwandlung zu UINT? Wenn nicht, dann brauchst Du nicht splitten und umkopieren und vielleicht nochmal in STRING umkopieren und dann in UINT konvertieren - wenn sowieso jedes empfangene Zeichen einzeln angefaßt wird, dann kannst Du auch gleich in UINT konvertieren nach dem Schema:
- wenn das Zeichen ein Leerzeichen (Trennzeichen) ist (' ' = 16#20 = 32 dezimal), dann schalte zum nächsten Ausgabewert und initialisiere den mit 0
- sonst ziehe den ASCII-Code für die Ziffer 0 ab ('0' = 16#30 = 48 dezimal)
- wenn dabei ein Wert < 0 oder > 9 rauskommt, dann ist das Zeichen keine Ziffer ---> Telegramm-Formatfehler? ---> ggf. Fehlerbehandlung
- wenn der Wert 0 .. 9 ist dann multipliziere den Ausgabewert mit 10 und addiere die Ziffer

Harald


----------



## Vijolica555 (25 März 2019)

>>Dein Bild würde heißen: Du hast die Bytefolge 57,48,55,32 entspricht 16#39,16#30,16#37,16#20 entspricht '907 ' als Zeichenfolge - und die willst Du zu 907 dezimal konvertiert haben?
Ich will 2311 dezimal konvertiert haben.

>>Ist das das selbe Telegramm wie Du oben in #1 gefragt hast? Oben wolltest Du die 800 Bytes in 30 Teile splitten, jetzt schreibst Du daß da 157 Zahlenwerte drin stecken?
wahr. Ich dachte, dass dieser Teil nicht mit {SPC} getrennt ist. Ich lag falsch.

>>Vielleicht verrätst Du mal wie Dein Sensor heißt und wo das Telegramm beschrieben ist - dann brauchen wir Dir nicht jede Information aus der Nase ziehen :wink: 
Haha Sorry   Sensor ist SICk TIM561 2D Laser, TCPIP communication. https://www.sick.com/media/docs/7/2...NAV310_LD_OEM15xx_LD_LRS36xx_en_IM0045927.PDF
 Oben ist Doku und da statt Antwort entwider in Hex, Binary oder ASCII Code. Ich glaube ich kann Hex Code in TwinCat nur als String lesen? Dann bekomme ich nicht ganze Antwort. Wenn lese ich als ARRAY OF BYTE dann mein Structur ist ein bisschen änderst und ich habe zwischen jeden Data {SPC}. und ich benutze 2111 Port obwohl in Doku statt das 2112 Binary telegram ist besser und immer gleich lang aber leider erhalte ich kein Antworttelegramm, wenn ich versuche, über 2112 eine Verbindung herzustellen


----------



## PN/DP (25 März 2019)

Wenn aus der Zeichenfolge '907 ' der Dezimalwert 2311 werden soll, dann müßte die Zeichenfolge den Hex-Wert 16#0907 meinen (ohne führende 0).
Welches Telegramm empfängst Du da eigentlich? Und hast Du die Frame-Start-/Ende-Zeichen <STX> und <ETX> schon entfernt?

Wenn in Deinem Empfangspuffer bis zu 160 Werte mit Leerzeichen getrennt liegen, dann kannst Du anstatt Split gleich in ein Array mit 160 UINT-Werten konvertieren:


```
aData  : ARRAY [0..nRecBytes] OF BYTE; [COLOR="#008000"]//Empfangspuffer Data von Sensor[/COLOR]
aWerte : ARRAY [0..159] OF UINT;
c : BYTE;

j := 0;
aWerte[j] := 0;
FOR i := 0 TO nRecBytes DO
    c := aData[i];
    IF c = ' ' THEN     [COLOR="#008000"]//Leerzeichen {SPC} = ' ' = 16#20 = 32 dez[/COLOR]
        j := j + 1;     [COLOR="#008000"]//nächster Wert[/COLOR]
        IF j > 159 THEN
            EXIT;       [COLOR="#008000"]//zu viele Werte im Telegramm![/COLOR]
        END_IF;
        aWerte[j] := 0;
    ELSE
        c := HEXASCNIBBLE_TO_BYTE(asc:=c); [COLOR="#008000"]//'0'..'9', 'A'..'F', 'a'..'f' --> 0..15[/COLOR]
        IF c = 255 THEN
            c := 0;     [COLOR="#008000"]//unzulässiges Zeichen ---> sollte Fehlerbehandlung[/COLOR]
        END_IF;
        aWerte[j] := SHL(in:=aWerte[j], n:=4) OR c;  [COLOR="#008000"]//oder: aWerte[j] := aWerte[j] * 16 + c;[/COLOR]
    END_IF;
END_FOR;
```


```
[COLOR="#008000"]//a) alternativ für HEXASCNIBBLE_TO_BYTE:[/COLOR]
        CASE c OF
          '0'..'9': c := c - '0';        [COLOR="#008000"]//ASCII '0'..'9' --> dez 0 .. 9[/COLOR]
          'A'..'F': c := c - 'A' + 10;   [COLOR="#008000"]//ASCII 'A'..'F' --> dez 10 .. 15[/COLOR]
          'a'..'f': c := c - 'a' + 10;   [COLOR="#008000"]//ASCII 'a'..'f' --> dez 10 .. 15[/COLOR]
        ELSE
            c := 0;     [COLOR="#008000"]//unzulässiges Zeichen ---> sollte Fehlerbehandlung[/COLOR]
        END_CASE;

[COLOR="#008000"]//b) alternativ für HEXASCNIBBLE_TO_BYTE:[/COLOR]
        IF c >= '0' AND c <= '9' THEN
            c := c - '0';                [COLOR="#008000"]//ASCII '0'.. --> dez 0 .. 9[/COLOR]
        ELSIF c >= 'A' AND c <= 'F' THEN
            c := c - 'A' + 10;           [COLOR="#008000"]//ASCII 'A'..'F' --> dez 10 .. 15[/COLOR]
        ELSE
            c := 0;     [COLOR="#008000"]//unzulässiges Zeichen ---> sollte Fehlerbehandlung[/COLOR]
        END_IF;
```

Harald


----------



## Vijolica555 (8 April 2019)

Hallo. 
Es tut mir leid für die späte Antwort. Vielen Dank für Ihre Antwort.

So... Das ist mein ARRAY in HEXIDECIMAL BYTEs:



_>>Welches Telegramm empfängst Du da eigentlich?_
Es ist lang cca 780.. Mehr dann haln sind 16#20 oder {SPC} oder ' '... Ich brauche ARRAY[0..156] OF UDINT. Jeder Wert, den ich brauche, wird mit drei Bytes geschrieben:


Hat jemand eine Ahnung, wie man einfach ein Hex-Array bekommt, wie im Handbuch geschrieben ist? Oder wie bekommt man gerade diese 157 Uint-Werte heraus? Werte liegen nicht immer am selben Ort. Ich orientiere mich, wenn ich finde 16#39 and 16#44 --> 157 (Anzahl der Werte).

>>Und hast Du die Frame-Start-/Ende-Zeichen <STX> und <ETX> schon entfernt?
Nein, erste und letzte BYTE sind 16#2 und 16#3 aka  <STX> und <ETX>


----------



## PN/DP (8 April 2019)

Vijolica555 schrieb:


> _>>Welches Telegramm empfängst Du da eigentlich?_
> Es ist lang cca 780.. Mehr dann haln sind 16#20 oder {SPC} oder ' '... Ich brauche ARRAY[0..156] OF UDINT.


Ich meinte, wie nennt sich das Telegramm offiziell nach der Kommunikationsbeschreibung von Sick? Das Telegramm ist die Antwort auf welche Anfrage/Command?
(Damit man unabhängig von Deinen schwammigen Aussagen belastbare Angaben bekommt.)



Vijolica555 schrieb:


> So... Das ist mein ARRAY in HEXIDECIMAL BYTEs:
> Anhang anzeigen 45237


Du bekommst Deine 157 Ganzzahlwerte als hexadezimal-Zeichen, jeweils mit Leerzeichen getrennt. Genau das wandelt mein Programmcode aus Beitrag #9, egal mit wievielen Hexadezimal-Ziffern die Werte codiert sind, und egal ob mit oder ohne führende Nullen. Du müsstest jetzt nur noch das <STX> am Anfang auswerten/entfernen (den Empfangspuffer um 1 Zeichen versetzt weiterreichen, oder durch '0' ersetzen, oder im Konvertier-Code abprüfen), und beim <ETX> die Konvertierung beenden.

```
aData  : ARRAY [0..nRecBytes] OF BYTE; [COLOR="#008000"]//Empfangspuffer Data von Sensor mit 157 Werten[/COLOR]
aWerte : ARRAY [0..156] OF UINT;
c : BYTE;

IF aData[0] <> 2 THEN               [COLOR="#008000"]//<STX> = 16#02 = 2 dez[/COLOR]
    Fehlerbehandlung();             [COLOR="#008000"]//Formatfehler: Telegramm beginnt nicht mit <STX>[/COLOR]
ELSE
    j := 0;
    aWerte[j] := 0;
    FOR i := 1 TO nRecBytes DO
        c := aData[i];

        IF c = 3 THEN               [COLOR="#008000"]//<ETX> = 16#03 = 3 dez[/COLOR]
            IF j <> 156 OR aData[i - 1] = ' ' THEN
                Fehlerbehandlung(); [COLOR="#008000"]//falsche Anzahl Werte im Telegramm![/COLOR]
            END_IF;
            EXIT;                   [COLOR="#008000"]//Telegramm-Ende erreicht[/COLOR]
        END_IF;

        IF c = ' ' THEN             [COLOR="#008000"]//Leerzeichen {SPC} = ' ' = 16#20 = 32 dez[/COLOR]
            j := j + 1;             [COLOR="#008000"]//nächster Wert[/COLOR]
            IF j > 156 THEN
                Fehlerbehandlung(); [COLOR="#008000"]//zu viele Werte im Telegramm![/COLOR]
                EXIT;
            END_IF;
            aWerte[j] := 0;
        ELSE
            c := HEXASCNIBBLE_TO_BYTE(asc:=c); [COLOR="#008000"]//'0'..'9', 'A'..'F', 'a'..'f' --> 0..15[/COLOR]
            IF c = 255 THEN
                c := 0;             [COLOR="#008000"]//unzulässiges Zeichen ---> sollte Fehlerbehandlung[/COLOR]
            END_IF;
            aWerte[j] := SHL(in:=aWerte[j], n:=4) OR c;  [COLOR="#008000"]//oder: aWerte[j] := aWerte[j] * 16 + c;[/COLOR]
        END_IF;
    END_FOR;
END_IF;
```




Vijolica555 schrieb:


> Jeder Wert, den ich brauche, wird mit drei Bytes geschrieben:


Wie kommst Du da drauf? Und ist das garantiert immer so?
Ab arrReceive[63] sind mehrere Werte nur 1 Zeichen lang, Dein Beispiel arrReceive[116]+arrReceive[117] = 16#9D = 157 ist nur 2 Zeichen lang, ...



Vijolica555 schrieb:


> Werte liegen nicht immer am selben Ort. Ich orientiere mich, wenn ich finde 16#39 and 16#44 --> 157 (Anzahl der Werte).


Heißt das, in dem Empfangs-Telegramm sind noch mehr Werte, und die 157 Werte die Dich interessieren liegen gar nicht am Anfang? Muß man den Anfang der Werte womöglich erst suchen oder abzählen?

Wieso brauchst Du jetzt auf einmal UDINT?
Warum schreibst Du immer nur ca. ... ?
Kannst Du bitte exakte und vollständige Aussagen machen, auf die man sich dann auch verlassen kann?

Also wenn sich hier mit beinahe jedem Post von Dir die Aufgabe ändert, dann habe ich keine Lust mehr. Außerdem habe ich Dir mittlerweile genug Beispielcode gezeigt, daß Du den Rest alleine hinkriegen solltest. Viel Erfolg.

Harald


----------



## Heinileini (8 April 2019)

PN/DP schrieb:


> . . . Heißt das, in dem Empfangs-Telegramm sind noch mehr Werte, und die 157 Werte die Dich interessieren liegen gar nicht am Anfang? Muß man den Anfang der Werte womöglich erst suchen oder abzählen? . . .


Diesen Eindruck hatte ich zunächst auch, aber das kann eigentlich nicht so sein.
Die Anzahl der Werte hat doch nichts zu tun mit den Inhalten der einzelnen Werte! Ein Telegramm, in dem mir für jedes Element (nur) die laufende Nr des Elements geliefert wird, ist doch nutzlos - ausser zum Testen! Wo wären denn da noch die Inhalte (Werte) versteckt, auf die es eigentlich ankommt?

Die zuletzt gelieferten ScreenShots zeigen Daten, die ausnahmslos als ASCII-Zeichen interpretiert werden können (nicht müssen), aber es sind nicht nur Leerzeichen (=Space) und Ziffern, sondern auch Buchstaben. Was haben die zu bedeuten? Die bieten sich ja nicht gerade an, in INT, UINT oder sonstige Zahlen gewandelt zu werden.
Wie Harald schon schrieb, müssten wir erfahren, welche Bytes welche Bedeutung haben bzw. wie gruppiert sind. 
Wenn Du uns wenigstens verrätst, welches der im pdf beschriebenen Telegramme wir uns ansehen sollen . . .

So wie bisher kommen wir nicht weiter.

Lass Dich durch Begriffe wie Hex und ASCII nicht verwirren/entmutigen - ist ganz einfach und da können wir weiterhelfen.

Gruss, Heinileini

PS:
Die meisten Buchstaben in den ScreenShots liegen im Bereich A bis F und könnten Bestandteile von HexZahlen sein, aber I, S und T definitiv nicht.


----------



## Vijolica555 (9 April 2019)

Hello PN/DP und Heinileini,

Es tut mir leid, hier erkläre ich noch ein bisschen:

Telegram Listing:
https://www.sick.com/media/docs/7/2...NAV310_LD_OEM15xx_LD_LRS36xx_en_IM0045927.PDF

Ich kommunikate durch TCP/IP mir FBs:
FB_ClientServerConnection;
FB_SocketSend;
SocketReceive;


```
CASE nStep OF 


0:     
    bEnable := TRUE;
    nStep := nStep +5;


5: fbConnect(
    sSrvNetID    := sSrvNetId, 
    nMode        := CONNECT_MODE_ENABLEDBG, 
    sRemoteHost    := sRemoteHost, 
    nRemotePort    := nRemotePort, 
    bEnable        := bEnable, 
    tReconnect    := T#5S, 
    bBusy        => , 
    bError        => , 
    nErrId        => , 
    hSocket        => hSocket, 
    eState        => eState);
    
    IF fbConnect.estate = eSOCKET_SUSPENDED THEN
        bEnable := FALSE;
        nStep := 0;
        ELSE 
            nStep := nStep + 5;
    END_IF
    


10: //Send sRN LMDscandata
    sCommand := 'sRN LMDscandata';
// Add [STX] / [ETX] framing to the command
IF fbConnect.eState = eSocket_CONNECTED  THEN
    sCommandWithFraming:= Tc2_Standard.INSERT(STR1:= sCommand, STR2:= '$02', POS:= 0);
    sCommandWithFraming:= Tc2_Standard.INSERT(STR1:= sCommandWithFraming, STR2:= '$03', POS:= LEN(sCommandWithFraming));
END_IF
    nStep := nStep + 5;
    
15:
    bExecuteSend := TRUE;
    
fbSend(
    sSrvNetId    := sSrvNetId, 
    hSocket        := hSocket, 
    cbLen        := SIZEOF(sCommandWithFraming), 
    pSrc        := ADR(sCommandWithFraming), 
    bExecute    := bExecuteSend, 
    tTimeout    := , 
    bBusy        => , 
    bError        => , 
    nErrId        => );
    
    IF NOT fbSend.bBusy AND NOT fbSend.bError THEN
        nStep := nStep + 5;
        bExecuteSend := FALSE;
    END_IF
    
20:
    bExecuteReceive := TRUE;
fbReceive(
    sSrvNetId    := sSrvNetId, 
    hSocket        := hSocket, 
    cbLen        := SIZEOF(arrReceive), 
    pDest        := ADR(arrReceive), 
    bExecute    := bExecuteReceive, 
    tTimeout    := , 
    bBusy        => , 
    bError        => , 
    nErrId        => , 
    nRecBytes    => nRecBytes);
    
    IF NOT fbReceive.bBusy AND NOT fbReceive.bError THEN
        nStep := nStep + 5;
        bExecuteReceive := FALSE;
    END_IF
    
END_CASE
```

"sRN LMDscandata" ist Command für empfangenes Telegramm: Telegram Listing PDF Seite 65-74.
Telegram ist zusammengesetzt von: 
Command type (string), 
Command (string), 
Version Numer (uint_16), 
Device Numme(uint_16)r, 
Serial Nummer(uint_32), 
Device Status(uint_x), 
telegram Counter(uint_16), 
Scan Couter(uint_16), 
Time since startup(uint_32), 
time of transmission(uint_32), 
Input status(Uint_x), 
Output status(uint_x), 
Reserved Byte A(uint_16), 
Scanning frequency(uint_32), (= 15Hz)
measurement frequency(uint_32), (=16,2kHz)  
number of encoders(uint_16), (= 0) 
Number of 16 bit channels(uint_16), (= 1) 
measured data contents((string), (=DIST1) 
Scalling factor(real),  
Scalling offset(real),
 Starting angle(int_32), (= 62) 
Angular step width((uint_16), (3.33) 
number of data(uint_16), (= 157) 
Data_1..Data_n (uint_16),                              *Teil das brauche ich*
Number of 8 bit channels (uint_16), (= 0) 
Position(uint_16), (= 0) 
name (uint_16), (= 1) 
Devicename (string), 
comment(uint_16) ,(=0)
time information(uint_16),(=0) 
Event information(uint_16), (=0) 

= 31 Telegram parts (für mein Sensor, in PDF ist mehr Möglichkeiten). Telegram parts sind entwider Zahlen entwider Buchstaben. 157 UINT Werte die ich brauche können sie sehen auf Seite 70: Data_1--Data_n (Wie weiß ist das da ist 157 Werte? Sensor ist so Parametrisiert und ein Telegram part vor ist Amout of data.

Was mein Problem ist das leider ich erhalte ARRAY of BYTEs so, das jede Buchstabe und jede Zahle ist in einiges BYTE und in zwischen telegram part in ein {SPC}. Und Dan ich cca 780 BYTEs.. Warum cca: weil "Time since start up in µs", "Scan counter", uzw sind nicht immer gleiche nummers.

Teil das ich brauche ist nicht in Anfang. Das ich warum habe ich gesagt ok viellicht kann ich finde drei BYTEs:  16#39 AND  16#44 AND  16#20 - > das ist Amout of Data und ist vor die Werter das ich brauche. 




> Ich meinte, wie nennt sich das Telegramm offiziell nach der Kommunikationsbeschreibung von Sick? Das Telegramm ist die Antwort auf welche Anfrage/Command?
> (Damit man unabhängig von Deinen schwammigen Aussagen belastbare Angaben bekommt.)



Command: sRN LMDscandata
Antwort: SRA LMDscandata



> Du bekommst Deine 157 Ganzzahlwerte als hexadezimal-Zeichen, jeweils mit Leerzeichen getrennt. Genau das wandelt mein Programmcode aus Beitrag #9, egal mit wievielen Hexadezimal-Ziffern die Werte codiert sind, und egal ob mit oder ohne führende Nullen. Du müsstest jetzt nur noch das <STX> am Anfang auswerten/entfernen (den Empfangspuffer um 1 Zeichen versetzt weiterreichen, oder durch '0' ersetzen, oder im Konvertier-Code abprüfen), und beim <ETX> die Konvertierung beenden.



Ich muss erte mall suche für Teil mit 157 Werte.



> _Jeder Wert, den ich brauche, wird mit drei Bytes geschrieben:_
> Wie kommst Du da drauf? Und ist das garantiert immer so?
> Ab arrReceive[63] sind mehrere Werte nur 1 Zeichen lang, Dein Beispiel arrReceive[116]+arrReceive[117] = 16#9D = 157 ist nur 2 Zeichen lang, ...


ich meinte für diese 157 werte



> Heißt das, in dem Empfangs-Telegramm sind noch mehr Werte, und die 157 Werte die Dich interessieren liegen gar nicht am Anfang? Muß man den Anfang der Werte womöglich erst suchen oder abzählen?


Ja


> Wieso brauchst Du jetzt auf einmal UDINT?


typo


> Warum schreibst Du immer nur ca. ... ?


Wie gesagt ich habe mehr Telegramm parts und die sind nicht immer gleich lang. 



> Wo wären denn da noch die Inhalte (Werte) versteckt, auf die es eigentlich ankommt?


normalerweise 24. Telegrammteil, aber hier dachtet ich dac kann ich suche für 23. telegrammteil die in diese Beispiel ist immer 157 (Wenn in einer anderen Umgebung, an einer anderen Maschine, nicht notwendig). 



> Die zuletzt gelieferten ScreenShots zeigen Daten, die ausnahmslos als ASCII-Zeichen interpretiert werden können (nicht müssen), aber es sind nicht nur Leerzeichen (=Space) und Ziffern, sondern auch Buchstaben. Was haben die zu bedeuten? Die bieten sich ja nicht gerade an, in INT, UINT oder sonstige Zahlen gewandelt zu werden.
> Wie Harald schon schrieb, müssten wir erfahren, welche Bytes welche Bedeutung haben bzw. wie gruppiert sind.
> Wenn Du uns wenigstens verrätst, welches der im pdf beschriebenen Telegramme wir uns ansehen sollen . . .



genau. Da sind auch Parameterwerte von Sensor, Nameusw. ..Seite 65-74.:
https://www.sick.com/media/docs/7/2...NAV310_LD_OEM15xx_LD_LRS36xx_en_IM0045927.PDF


Ich hoffe, ich habe etwas besser erklärt.


----------



## Vijolica555 (30 April 2019)

Hallo,


Ich habe upadate fü mein empfangenes Array. Jetzt die Position ist fixed und ist klaar was und wo zu suchen. 
ich habe:
arrReceived : ARRAY [0..411] OF BYTE;


Die tail das interessierte mich ist arrReceived[85..398]. Das ist 314 BYTE werte. Jede information ist in zwei BYTE geschrieben. Dann habe ich 157 informationen. Die muss ich von Hex (16#07,16#DE) nach Dec (2014) konventieren. 


.....
arrReceived    : ARRAY [0..411] OF BYTE;
aValues        : ARRAY [0..156] OF UINT;
...


ich habe problem mit zwei BYTE nach ein UINT wert zu konventieren. Haben sie viellight eine Idee?


Danke.


----------



## Heinileini (30 April 2019)

Vijolica555 schrieb:


> Die muss ich von Hex (16#07,16#DE) nach Dec (2014) konventieren.


Da ist nichts zu konvertieren, nur die zwei Bytes zu einem Wort zusammenfassen.
Hex (16#07,16#DE) = Hex (16#07DE) = Dec (2014)


----------



## PN/DP (30 April 2019)

Kann man bei Deinem Programmiersystem ein Alignment von 1 einstellen?
Du könntest Deinen Empfangspuffer strukturieren und direkt die UINT entnehmen:

```
//Alignment muß 1 sein, weil UINT-Array auf ungerader Adresse beginnt

arrReceived : STRUCT
  aDavor  : ARRAY [0..84] OF BYTE;
  aValues : ARRAY [0..156] OF UINT;
  aDanach : ARRAY [399..411] OF BYTE;
END_STRUCT;
```
Oder mit MEMCPY direkt die Bytes 85..398 in das UINT-Array kopieren.

Müssen bei Deiner SPS eventuell noch H-Byte und L-Byte getauscht werden (SWAP)? Dann die UINT aus den je 2 BYTE zusammensetzen (z.B. aValues[x] := SHL(arrReceived_, 8 ) OR arrReceived[i+1];__ ) oder aus dem arrReceived.aValues --> SWAP --> aValues

Harald_


----------



## Vijolica555 (6 Mai 2019)

Hallo,

ahaa Ich wusste nicht, dass ich kann so einfach in UINT mein BYTE speichern. Und jaa ich musste H-Byte und L-Byte ändern und das funktioniert mit ROL(arrReceived_,8).

Danke!_


----------



## PN/DP (6 Mai 2019)

Wenn es bei Deinem Programmiersystem ein "ROL(word, 8)" gibt, dann kann man auch so die Bytes tauschen (Swap). Wichtig ist nur, daß man die richtigen/zusammengehörigen 2 Bytes als UINT/Word liest, und das ist bei Dir nicht ganz einfach weil die UINT auf ungeraden Adressen im Empfangspuffer liegen - wie hast Du das bei Dir gelöst?

PS: Welches Programmiersystem verwendest Du eigentlich?

Harald


----------



## Vijolica555 (7 Mai 2019)

Leider finde ich SWAP nicht (Programmiersystem ist twinCAT 3), aber ist auch so gut. Ich überprüfe die Werte und die Transformation ist gut:




```
arrReceive        : ARRAY [0..iReceiveBufferSize] OF  BYTE; 
arrData        : ARRAY [0..156] OF UINT;
arrData_1        : ARRAY [0..156] OF UINT;
_________________________________________

MEMCPY(ADR(arrData),ADR(arrReceive[85]),314);

FOR i:=0 TO 156 DO
    arrData_1[i] := ROL(arrData[i],8);
END_FOR
```


----------

