TIA Bitmuster Zeitgesteuert

SPSnewbie91

Level-2
Beiträge
186
Reaktionspunkte
10
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen.

Erst mal zur Software und Hardware.
TIA V18
CPU 1518F-4 PN/DP

Ich stehe vor folgendem Problem. Ich soll über einen Fußtaster bestimmte Bitmuster an ein übergeordnetes Leitsystem schicken. Das Bitmuster besteht aus 16 Bit. Als erstes soll ich das Bitmuster (0000 0000 0000 0001) schicken, sobald der Bediener den Fußtaster betätigt. Anschließend soll alle 150ms ein Bit mehr belegt werden. Sprich nach 150ms (0000 0000 0000 0011) nach weiteren 150ms (0000 0000 0000 0111) usw... Das Leitsystem wertet anschließend dieses Bitmuster aus um zu erfahren, ob der Bediener den Fußtaster "lange" oder "kurz" betätigt hat. Ich weiß es ginge viel einfacher und ist unnötig kompliziert, aber das ist nun Mal so Vorgabe vom Kunden.
Ich habe ein paar Sachen ausprobiert, aber irgendwie komme ich nicht auf das gewünschte Ergebnis.

1697436445243.png
Bitte verzeiht mir wenn das amateurhaft aussieht. Aber das bin ich nun mal noch. Ein Amateur :).
Vielleicht kann mir jemand ja einen Gedankenstoß geben, wie ich das am Besten lösen könnte.

Gruß
SPSnewbie91
 
Ach ja. Sobald der Bediener den Fußtaster wieder loslässt, soll ich das "fertige" Bitmuster nochmal an das Leitsystem senden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das sollte mit SHL funktionieren, alle 150ms mit einer steigenden Flanke die 16 Bit nach links schieben. Falls es endlos weitergehen soll, kannst du das mit ROL machen. Schau mal bei den TIA_Anweisungen unter "Schieben und Rotieren".
Und beim Loslassen des Fußtaster die fallende Flanke detektieren und das entsprechende Bitmuster senden.
 
Im ersten Schritt die Ausgabevariable (INT oder WORD) mit 1 initialisieren, dann alle 150ms
Ausgabe := Ausgabe * 2 + 1; (*) oder Ausgabe := SHL(Ausgabe, 1) OR Ausgabe; oder Ausgabe := SHL(Ausgabe, 1) OR 1;
)kann sein daß die Syntax nicht ganz korrekt ist)

PS: (*) geht nur bis 15 Bit. im 16. Schritt muß -1 ausgegeben werden.. Die SHL-Varianten gehen beliebig oft
 
Zuletzt bearbeitet:
Ich würde das Ganze als Schrittkette umsetzen - so kannst du aus meiner Sicht am Einfachsten sicherstellen, dass deine Timer passend geschaltet werden, das Aufschieben (hier würde ich es auch so wie Harald machen) und das Absetzen der Info an das Leitsystem ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das sollte mit SHL funktionieren, alle 150ms mit einer steigenden Flanke die 16 Bit nach links schieben. Falls es endlos weitergehen soll, kannst du das mit ROL machen. Schau mal bei den TIA_Anweisungen unter "Schieben und Rotieren".
Und beim Loslassen des Fußtaster die fallende Flanke detektieren und das entsprechende Bitmuster senden.
Danke. Ich schau mir diese Funktionen gleich mal an
 
Das sollte mit SHL funktionieren, alle 150ms mit einer steigenden Flanke die 16 Bit nach links schieben. Falls es endlos weitergehen soll, kannst du das mit ROL machen. Schau mal bei den TIA_Anweisungen unter "Schieben und Rotieren".
Und beim Loslassen des Fußtaster die fallende Flanke detektieren und das entsprechende Bitmuster senden.
Nur mal zum Verständnis. Mit SHL wird das Bit nur um eine Stelle nach Links verschoben oder? Das heißt aus 0001 wird 0010 und danach 0100 oder? Ich brauche aber alle 150ms 0001 --> 0011 --> 0111 usw. oder verstehe ich das falsch?
 
Ich habe es jetzt schon mal so hinbekommen, dass sobald ich den Taster betätige das Bitmuster ...0001 gesendet wird und anschließend nach dem Senden der Timer startet. Sobald der Timer abgelaufen ist überschreibe ich das Bitmuster über eine positive Flanke mit der von @PN/DP aufgeführten Berechnung. Ich habe hier die Zeit höher als 150ms gewählt um den Timer besser beobachten zu können. Jetzt bräuchte ich noch irgendeine Möglichkeit, dass sich der Timer selbstständig neu startet. Hier muss ich noch den Fußtaster jedes Mal neu betätigen.

1697443554406.png
 
Nur mal zum Verständnis. Mit SHL wird das Bit nur um eine Stelle nach Links verschoben oder? Das heißt aus 0001 wird 0010 und danach 0100 oder? Ich brauche aber alle 150ms 0001 --> 0011 --> 0111 usw. oder verstehe ich das falsch?

Deswegen diese Vorschläge von PN/DP, Du siehst entweder ein +1 oder ein OR, was damit zusammenhängt, daß damit immer das niederwertigste Bit neu gesetzt wird.

Ausgabe := Ausgabe * 2 + 1; (*) oder Ausgabe := SHL(Ausgabe, 1) OR Ausgabe; oder Ausgabe := SHL(Ausgabe, 1) OR 1;

Du schiebst Dein Bitmuster und setzt das niederwertigste Bit neu.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nicht genau, was Du in #9 machen willst... warum nutzt Du eine Einschaltverzögerung mit 3s und verarbeitest den Ausgang dann in Deinem R_Trig? Was genau ist R_Trig bei Dir? Ich hätte erwartet, Dein 150ms-Blinker, um das Bitmuster zu erhöhen. Aber warum die 3s? Warum die Verknüpfung?
 
Code:
IF NOT alle150msFlanke THEN
    ; // nix
ELSEIF FussTaster THEN
    diBitMuster := diBitMuster + diBitMuster + 1 ; // zu "rechnendes" Muster Typ DINT, statisch
ELSE
    diBitMuster := 0 ;
END_IF 
wBitMuster  := DINT_TO_WORD( diBitMuster ) ; // auszugebendes Muster Typ WORD
diBitMuster := WORD_TO_DINT( wBitMuster ) ;

Habe weggelassen, woher alle 150ms die TriggerFlanke kommt.
 
Zuletzt bearbeitet:
Code:
IF NOT alle150msFlanke THEN
    ; // nix
ELSEIF FussTaster THEN
    diBitMuster := diBitMuster + diBitMuster + 1 ; // zu "rechnendes" Muster Typ DINT
ELSE
    diBitMuster := 0 ;
END_IF  
wBitMuster := DINT_TO_WORD( diBitMuster ) ; // auszugebendes Muster Typ WORD

Habe weggelassen, woher alle 150ms die TriggerFlanke kommt.
Im ELSE mißachtest Du aber seine Anforderung, daß er nach dem Loslassen das Bitmuster nochmal schicken soll.

Ach ja. Sobald der Bediener den Fußtaster wieder loslässt, soll ich das "fertige" Bitmuster nochmal an das Leitsystem senden.

Mit dem ELSE löschst Du es aber unmittelbar ab und er hat keine Chance mehr, das zu verschicken.

PS: Die "alle150msFlanke" muß natürlich mit dem Fußtaster gestartet werden, ansonsten kann sie den ersten Zyklus nicht sicher mit 150ms ausführen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich verstehe nicht genau, was Du in #9 machen willst... warum nutzt Du eine Einschaltverzögerung mit 3s und verarbeitest den Ausgang dann in Deinem R_Trig? Was genau ist R_Trig bei Dir? Ich hätte erwartet, Dein 150ms-Blinker, um das Bitmuster zu erhöhen. Aber warum die 3s? Warum die Verknüpfung?
Mein Gedanke war den TON Timer über den TOF selbständig wieder neu anlaufen zu lassen, da ich ja nicht vom Fußtaster runter gehe. Dann wollte ich über eine Positive Flanke des TON_Timer.Q jedes Mal das Bitmuster mit der dargestellten Berechnung erhöhen. Wenn ich es ohne Flanke mache steht sofort 'FFFF' im Bitmuster.
 
Einen Blinker machst Du über

Code:
/* PSEUDO Code*/
Blinker : BOOL := False;
TON(IN:= Fußtaster AND NOT Blinker; PT:=T#150ms);
Blinker := TON.Q;

If Blinker Then
    /* verändere Bitmuster */
end_if
 
Im ELSE mißachtest Du aber seine Anforderung, daß er nach dem Loslassen das Bitmuster nochmal schicken soll.
Das kommt davon, wenn man so langsam ist und tausende von Beiträgen eintrudeln, während man noch am Tippen ist. ;) Sorry!
Mit dem ELSE löschst Du es aber unmittelbar ab und er hat keine Chance mehr, das zu verschicken.
Den ELSIF-Zweig könnte man so abändern, dass hier zunächst das letzte Muster noch einmal gesendet wird, bevor man es löscht.
Dadurch wird es ja eine ganz neue Aufgabe ... mache ich mir später mal Gedanken drüber.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Einen Blinker machst Du über

Code:
/* PSEUDO Code*/
Blinker : BOOL := False;
TON(IN:= Fußtaster AND NOT Blinker; PT:=T#150ms);
Blinker := TON.Q;

If Blinker Then
    /* verändere Bitmuster */
end_if
Wenn ich es so mache wie du, dann habe ich nach Ablauf der Zeit "FFFF" als Bitmuster

1697446151876.png
 
Du setzt auch in jedem Zyklus den Blinker auf False. Das war in meinem Pseudo-Code als Initialisierung geschrieben, um definiert die Variable im ersten Zyklus auf False zu setzen (eigentlich unnötigt, da Initialisierungen i.d.R. mit 0 bzw. False stattfinden, aber ...).
So wie Du es schreibst, schaltet der TON nie wieder ab, weil er keinen Wechsel des Blinker-Bits bekommt. Und damit ist der Blinker nach dem TON dauerhaft 0 und Dein IF ist dauerhaft aktiv.
 
Du setzt auch in jedem Zyklus den Blinker auf False. Das war in meinem Pseudo-Code als Initialisierung geschrieben, um definiert die Variable im ersten Zyklus auf False zu setzen (eigentlich unnötigt, da Initialisierungen i.d.R. mit 0 bzw. False stattfinden, aber ...).
So wie Du es schreibst, schaltet der TON nie wieder ab, weil er keinen Wechsel des Blinker-Bits bekommt. Und damit ist der Blinker nach dem TON dauerhaft 0 und Dein IF ist dauerhaft aktiv.
Stimmt. Mein Fehler. Danke.
 
Zurück
Oben