Ich bin mir nicht sicher ob der Thread hier richtig ist, möglicherweise gehört er eher in "Programmierstrategien" oder auch den "Stammtisch"...
Beflügelt von diesem Thread habe ich mir gedacht ich ersetze den sonntäglichen Mittagsschlaf dadurch dass ich mir mal einen FB bastele der ähnlich funktioniert wie die Funktionen die ich seit Jahren von RSLogix gewohnt bin... Pustekuchen :shock:
Wenn man sich auf einen bestimmten Datentypen einschießt ist das ja alles noch recht überschaubar, zumal wenn man mit fest definierten Array-Längen arbeitet. Will ich aber nicht.
Deklarationen in der Form
werden in der verwendeten Version 2.3.9 mit kopfschütteln seitens CoDeSys quittiert. Alles klar, ich habe schon mal von Pointern gehört, die Siemens Leute brauchten dazu glaube ich AWL, aber wie funktionierts in CoDeSys?
[F1] gedrückt und den Mund nicht mehr zubekommen, die Hilfe ist einen Lacher wert *ROFL* Ich bins gewohnt nicht unbedingt an die Hand genommen zu werden, aber da kam ich mir schon etwas allein gelassen vor.
Hürde Nummer 1 ist genommen, Datentypen schießen mir ins Hirn, ich will nicht viel, aber wenigstens alles was in 32 Bit ausgedrückt werden kann mit einem FB verarbeiten...
REAL in DWORD kopieren? No Señor...
Hat sich da in Version 3 etwas getan? Ich würde gern die Länge des ersten Elements in Bytes ermitteln, den Pointer dann entsprechend positionieren und die benötigte Anzahl an Bytes umladen / einfügen / schreiben etc. Da ich dem Pointer ja schon einen Datentyp zuweisen muss definiere ich damit ja schon die Anzahl der zu bearbeitenden Bits... Wahrscheinlich gibt es dazu eine ganz einfache Lösung, Ideen? Anregungen? Fehler? Man werfe mir Schlagworte um die Ohren, ich kann Google benutzen...
Da ich beruflich zum Glück noch die Finger davon lassen darf belasse ich es jetzt mal dabei, falls jemand mal lachen möchte folgt unten noch ein wenig Code, das ganze kann ein Element in den (bis zu 32766 Elemente langen) FIFO-Speicher laden, ein Element aus dem FIFO-Speicher entladen, automatisch ein Element entladen wenn der Speicher voll ist (Laufspeicher für Historien etc.), have fun :mrgreen:
Aufruf:
Beflügelt von diesem Thread habe ich mir gedacht ich ersetze den sonntäglichen Mittagsschlaf dadurch dass ich mir mal einen FB bastele der ähnlich funktioniert wie die Funktionen die ich seit Jahren von RSLogix gewohnt bin... Pustekuchen :shock:
Wenn man sich auf einen bestimmten Datentypen einschießt ist das ja alles noch recht überschaubar, zumal wenn man mit fest definierten Array-Längen arbeitet. Will ich aber nicht.
Deklarationen in der Form
Code:
length: INT;
foo: ARRAY[0..length] OF DINT;
[F1] gedrückt und den Mund nicht mehr zubekommen, die Hilfe ist einen Lacher wert *ROFL* Ich bins gewohnt nicht unbedingt an die Hand genommen zu werden, aber da kam ich mir schon etwas allein gelassen vor.
Hürde Nummer 1 ist genommen, Datentypen schießen mir ins Hirn, ich will nicht viel, aber wenigstens alles was in 32 Bit ausgedrückt werden kann mit einem FB verarbeiten...
REAL in DWORD kopieren? No Señor...
Hat sich da in Version 3 etwas getan? Ich würde gern die Länge des ersten Elements in Bytes ermitteln, den Pointer dann entsprechend positionieren und die benötigte Anzahl an Bytes umladen / einfügen / schreiben etc. Da ich dem Pointer ja schon einen Datentyp zuweisen muss definiere ich damit ja schon die Anzahl der zu bearbeitenden Bits... Wahrscheinlich gibt es dazu eine ganz einfache Lösung, Ideen? Anregungen? Fehler? Man werfe mir Schlagworte um die Ohren, ich kann Google benutzen...
Da ich beruflich zum Glück noch die Finger davon lassen darf belasse ich es jetzt mal dabei, falls jemand mal lachen möchte folgt unten noch ein wenig Code, das ganze kann ein Element in den (bis zu 32766 Elemente langen) FIFO-Speicher laden, ein Element aus dem FIFO-Speicher entladen, automatisch ein Element entladen wenn der Speicher voll ist (Laufspeicher für Historien etc.), have fun :mrgreen:
Code:
FUNCTION_BLOCK FIFO
VAR_INPUT
LoadValue: POINTER TO DWORD;
UnloadValue: POINTER TO DWORD;
FirstElement: POINTER TO DWORD;
END_VAR
VAR
i: INT;
Size: UDINT;
DestPointer: POINTER TO DWORD;
SourcePointer: POINTER TO DWORD;
END_VAR
VAR_IN_OUT
Ctrl: ST_CTRL;
END_VAR
Size := SIZEOF(FirstElement^);
IF Ctrl.Full AND Ctrl.Autounload AND Ctrl.Load THEN
SourcePointer := FirstElement + ((Ctrl.Position - 1) * Size);
UnloadValue^ := SourcePointer^;
Ctrl.Position := Ctrl.Position - 1;
END_IF;
IF Ctrl.Load AND (Ctrl.Position < Ctrl.Length) THEN
Ctrl.Done := FALSE;
FOR i := (Ctrl.Position) TO 1 BY -1 DO
DestPointer := FirstElement + (i * Size);
SourcePointer := FirstElement + ((i-1) * Size);
DestPointer^ := SourcePointer^;
END_FOR;
FirstElement^ := LoadValue^;
Ctrl.Position := Ctrl.Position + 1;
Ctrl.Done := TRUE;
END_IF;
IF Ctrl.Unload AND (Ctrl.Position > 0) THEN
Ctrl.Done := FALSE;
SourcePointer := FirstElement + ((Ctrl.Position - 1) * Size);
UnloadValue^ := SourcePointer^;
SourcePointer^ := 0;
Ctrl.Position := Ctrl.Position - 1;
Ctrl.Done := TRUE;
END_IF;
IF Ctrl.Position = 0 THEN
Ctrl.Empty := TRUE;
ELSE
Ctrl.Empty := FALSE;
END_IF;
IF Ctrl.Position < Ctrl.Length THEN
Ctrl.Full := FALSE;
ELSE
Ctrl.Full := TRUE;
END_IF;
Aufruf:
Code:
PROGRAM PLC_PRG
VAR
AddElement: BOOL;
RemoveElement: BOOL;
FIFO: FIFO;
BufferCtrl: ST_CTRL;
Value: DINT;
Buffer: ARRAY[0..15] OF DINT;
Unload: DINT;
END_VAR
BufferCtrl.Enable := TRUE;
BufferCtrl.Autounload := TRUE;
BufferCtrl.Length := 16;
BufferCtrl.Load := AddElement;
BufferCtrl.Unload := RemoveElement;
FIFO(
LoadValue:= ADR(Value),
UnloadValue := ADR(Unload),
FirstElement:= ADR(Buffer[0]),
Ctrl := BufferCtrl);
IF BufferCtrl.Done THEN
AddElement := FALSE;
RemoveElement := FALSE;
END_IF;