Schrittweite bei Analogeingang

Zuviel Werbung?
-> Hier kostenlos registrieren
Um ein Ende zu finden:
Nimm 2 Variablen USINT.
Variable1 auf Byte6
Variable2 auf Byte7

iAbstand := (Variable1 * 256) + Variable2

Wobei man da drauf achten sollte, dass einem die implizite Typkonvertierung einem da nicht an unerwarteter Stelle ein Vorzeichen reinmogelt.
Je nach dem welcher Datentyp für die Konstante 256 angenommen wird, da weiß ich nicht wie Codesys standardmäßig vorgeht. Wenn signed dann hast du da ein Vorzeichen, das Ergebnis der Klammer ist damit auch signed und Variable2 wird vor der Addition auch auf signed erweitert.
 
Das macht ja quasi aus einem 8 Bit ein 16 Bit. Hätte das dann nicht auch mit 128 funktioniert?
NEIN!
Wenn das höherwertige Byte durch Multiplikation mit 128 oder durch Schieben nach links um 7 BitPositionen "bewegt" wird (statt mit * 256 oder SHL 8 ),
dann positionierst Du 2 Bits (Bit 7 und 8 des ursprünglichen Wortes) an dieselbe BitPosition (Bit 7).
1. Im höherwertigen Byte steht dann nur der halbe Wert von dem, was dort stehen müsste.
2. Verknüpfst Du dann die beiden Bestandteile des Wortes mit ODER, dann "kollidieren" die beiden Bytes an der BitPosition 7 - die beiden Bytes überschneiden sich!
3. Verknüpfst Du statt mit ODER durch eine Addition, dann hast Du ebenfalls die Kollision/Überschneidung, aber zusätzlich kann sich ein Überlauf in die Bits 8..15 ergeben.
4. Du darfst nicht darauf spekulieren, dass der unter 3. genannte Überlauf im Stande ist, den Fehler aus 1. zu reparieren. ;)

Anmerkung:
Ob Du das nach links geschobene bzw. multiplizierte Byte mit dem rechts verbliebenen Byte per ODER oder per Addition "vereinigst", ist "normalerweise" egal.
ABER, "normalerweise" setzt voraus, dass alle BitPositionen in beiden Worten 0 sind, die aus dem jeweils anderen Wort übernommen werden sollen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Thomas scheint zumindest ohne Minus zu klappen. Der Wert geht danach in meinen LIN_TRAFO, der mir den Wert umrechnet und das Minus bei IN_MIN = 0 wahrscheinlich sowieso kappen würde, oder?

Ich werde morgen mal testen ob ich das WORD rausbekomme und so noch auf andere Weise an den Wert komme. Mein Denkfehler, dass man mit einer WORD Variablen zwei Bytes im
Prozessabbild einsammelt ist zwar jetzt weg aber das mit der Rechnung muss ich nochmal versuchen nachzuvollziehen. Die Antwort von Larry hat mich nochmal ein bisschen mehr ins Grübeln gebracht.

Edit: Habe die Antwort von Heini nicht berücksichtigen können.
Ich glaube, dass mit dem SHL 8 hat mir geholfen.
Ich schiebe alles nach links und fülle dann mit der zweiten Variable auf so zusagen, in dem ich sie addiere und habe dann meine 16 Bit, die ich in iAbstand speichere.

Durch das schieben nach links, rechts ja nur Nullen sind geht das aber wenn man nur um 7 schiebt überschneidet es sich weil eine Null zu wenig rein kommt bzw. reingekommen ist vorher.

Das liegt jetzt allerdings alles daran, dass es ein USINT ist, oder?
 
Zuletzt bearbeitet:
1. Mein Denkfehler, dass man mit einer WORD Variablen zwei Bytes im Prozessabbild einsammelt ist zwar jetzt weg ...

2. Das liegt jetzt allerdings alles daran, dass es ein USINT ist, oder?
Zu 1.:
Ich bin noch nicht davon überzeugt, dass es ein Denkfehler war. Mit WORD sollte es gehen. Vielleicht ist es eine Einschränkung von CodeSys, die mir nicht bewusst ist?

Zu 2.:
Wie meinst Du das? Was liegt alles daran, dass es ein USINT ist?

Die DatenTypen wie BYTE, WORD, DWORD, LWORD, USINT, UINT, UDINT, ULINT, SINT, INT, DINT, LINT, REAL und LREAL beinhalten immer 2 Informationen:
a) ihre Länge bzw. aus wie vielen Bytes sie bestehen (1 oder 2 oder 4 oder 8 ) und
b) ihre Bedeutung bzw. wie der Inhalt zu interpretieren ist (binär alias logisch alias BitMuster oder vorzeichenlose GanzZahl oder GanzZahl mit Vorzeichen oder GleitPunktZahl oder ... .

Ausnahmen sind STRING und WSTRING. Sie sagen nichts darüber aus, wie lang sie sind, sondern nur, wie viele Bytes pro Zeichen sie belegen (STRING 1 Byte und WSTRING 2 Bytes).

Eine weitere Ausnahme kann BOOL sein. BOOL sagt zwar eindeutig aus, dass es eine 1-Bit Information ist, aber häufig wird eine grössere Menge an Bits belegt, um nur das eine Bit an Information "zu verpacken". Dies liegt daran, dass die Prozessoren nicht von Hause aus einzelne Bits adressieren können (die Belange der SPS-Programmierung wurden bei ihrer Entwicklung schlicht vergessen/ignoriert :ROFLMAO:).
Bei den heutigen, geringen Kosten für Speicher liegt es dann nahe, eine grössere "VerpackungsEinheit" für einzelne Bits zu ver[sch]wenden.

Zurück zu a) und b):
Code:
            | binär |G a n z z a h l|Gleit- |  Ganzzahl [s] |Ganzzahl [ms]|
            |logisch|nur pos|pos&neg| -Punkt|   86400 s/d   |86400000 ms/d|
------------+-------+-------+-------+-------+---------------+-------------+---------
1 Byte Länge|  BYTE | U[B]S[/B]INT |  [B]S[/B]INT |   -   |       -       |      -      | [B]S[/B]=Short
------------+-------+-------+-------+-------+---------------+-------------+---------
2 Byte Länge|  WORD |  UINT |   INT |   -   |       -       |      -      |
------------+-------+-------+-------+-------+---------------+-------------+---------
4 Byte Länge| [B]D[/B]WORD | U[B]D[/B]INT |  [B]D[/B]INT |  REAL | DATE          | TIME        | [B]D[/B]=Double
            |       |       |       |       | DATE_AND_TIME | TIME_OF_DAY |
------------+-------+-------+-------+-------+---------------+-------------+---------
8 Byte Länge| [B]L[/B]WORD | U[B]L[/B]INT |  [B]L[/B]INT | [B]L[/B]REAL |       -       |      -      | [B]L[/B]=Long
Meinst Du, es liegt an der Länge von USINT oder an der "VorzeichenLosigkeit"?
 
Vielen Dank nochmal für deine ausführliche Erklärung.

Ich habe gerade als ich die Antwort getippt habe schon selbst gemerkt warum die zweite Frage Quatsch war. Ich verschiebe ja mit der Multiplikation um 256 nur den Wert. Ich dachte erst, dass ich bei einem Eingangsbyte in INT anders vorgehen müsste wobei ich ja nur das verketten von BYTE 1 und 2 auch verschieben müsste allerdings dann um mehr stellen als 8.

Das Vorzeichen habe ich jetzt tatsächlich komplett missachtet... Bzw. scheint es CODESYS von alleine richtig zu machen.

Ich habe somit übrigens auch gestern einen exakten 12 Bit IO-Link Wert für das Messsignal bekommen. Nur das ich im zweiten Byte um vier geshiftet habe. Die IODD verrät ja wo die Prozessdaten liegen
 
Zurück
Oben