TIA Bitmuster Zeitgesteuert

Zuviel Werbung?
-> Hier kostenlos registrieren
Das kommt davon, wenn man so langsam ist und tausende von Beiträgen eintrudeln, während man noch am Tippen ist. ;) Sorry!
Geht mir auch so. Da habe ich aufwendig das Programm gemalt, derweil sind schon viel mehr Beiträge gekommen.
KOP1.png
Die Variablen des FB_Progressbar
Code:
VAR_Input
  Input : Bool //der Eingang Fusstaster
VAR_Output
  Output : Word //Ausgabe Bitmuster
VAR //(Static)
  Ausgabewert : Word
  Takt : TON_TIME
  Puls : Bool
  FPM  : Bool //Flankenhilfsmerker
VAR_TEMP
  TempWord : Word


Die Spezial-Forderung beim Loslassen habe ich auch übersehen und habe jetzt auch keine Lust, das noch mit einzubauen. Das zerstört die ganze "Schönheit".

Ach ja. Sobald der Bediener den Fußtaster wieder loslässt, soll ich das "fertige" Bitmuster nochmal an das Leitsystem senden.
Diese Forderung halte ich für Quatsch. Der Wert vor dem Loslassen wurde ja schon gesendet. Und wie lange soll der letzte Wert stehen bleiben? Soll da auch noch irgendwann wieder ein Wert 0 gesendet werden?
Wenn der Wert nicht nur vom Partner gepollt wird. sondern aktiv gesendet werden soll, dann ist das am einfachsten zu realisieren, wenn man immer dann sendet (ein Sendeauftragsbit erzeugt), wenn der Wert sich ändert. Das läßt sich arelativ einfach noch einbauen.
 
Zuletzt bearbeitet:
Ich habe es jetzt mit dem Blinker von @JSEngineering programmiert.

1697456573840.png

lvsSndTel128 ist ein FC vom Kunden der einfach nur aufgerufen werden muss um das Telegramm zu senden. Soweit funktioniert auch alles. Sobald ich den Taster starte wird im FC das richtige Bitmuster (0001) angezeigt. Der Timer läuft auch einwandfrei und das Bitmuster "zählt hoch". Sobald ich den Taster wieder loslasse wird das Telegramm erneut gesendet und im FC steht auch wieder das richtige Bitmuster. Anschließend wird das Bitmuster wieder abgelöscht. Jetzt habe ich noch ein kleines Problem. Das Bitmuster sollte eigentlich bei "16#FFFF" aufhören weiterzuzählen. Es fängt aber wieder von vorne an. Mein Gedanke war für IN des "TON_IDB" eine weitere Bedingung einzuführen. Nämlich "... AND NOT #TAMPE[Index] = 16#FFFF THEN ...".
1697457017199.png

Das hat aber leider nicht funktioniert, da jetzt mein Timer gar nicht mehr startet. Verstehe ich nicht wieso. Das gleiche hätte ich bei meiner Berechnung versucht.
Quasi hier
1697456954358.png
noch die Bedingung "AND NOT #TAMPE[Index] = 16#FFFF THEN" eingefügt. Hat auch nicht funktioniert.

Habt ihr Tipps wie ich den Timer bei 16#FFFF stoppen kann?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
lvsSndTel128 ist ein FC vom Kunden der einfach nur aufgerufen werden muss um das Telegramm zu senden. Soweit funktioniert auch alles. Sobald ich den Taster starte wird im FC das richtige Bitmuster (0001) angezeigt. Der Timer läuft auch einwandfrei und das Bitmuster "zählt hoch". Sobald ich den Taster wieder loslasse wird das Telegramm erneut gesendet und im FC steht auch wieder das richtige Bitmuster.
Dus prichst von "erneut gesendet" und am Anfang dieses Threads von "der Empfänger soll die Dauer des Tastendrucks auswerten".... ich hatte es so verstanden, daß das Telegramm zyklisch alle 150ms neu gesendet wird. Wenn ich in Deinen Code schaue, wird es ja wohl nur einmal bei Betätigen der Taste und am Ende einmal beim Loslassen gesendet. Hatte ich Deine Worte falsch verstanden?

Das Bitmuster sollte eigentlich bei "16#FFFF" aufhören weiterzuzählen. Es fängt aber wieder von vorne an.
Ist klar, Du führst eine mathematische Rechenoperation aus und kommst in den Überlauf.
Ich würde da jetzt nicht anfangen, das mit Sonder-IFs zu schmücken, sondern dann eher auf das SHL ausweichen, was PN/DP Dir anfangs schon vorgeschlagen hat. Wenn da FFFF drin steht, und Du ein Bit weiterschiebst, ällt einfach nur die höchstwertige 1 runter, und hinten mußt Du die dann ja eh wieder mit dem OR auffüllen. Also steht wieder FFFF drin.
--> Siehe auch das Code-Beispiel von PN/DP in #21
 
Dus prichst von "erneut gesendet" und am Anfang dieses Threads von "der Empfänger soll die Dauer des Tastendrucks auswerten".... ich hatte es so verstanden, daß das Telegramm zyklisch alle 150ms neu gesendet wird. Wenn ich in Deinen Code schaue, wird es ja wohl nur einmal bei Betätigen der Taste und am Ende einmal beim Loslassen gesendet. Hatte ich Deine Worte falsch verstanden?
Ja genauso hatte ich das gemeint. Einmal beim Betätigen und einmal beim Loslassen.

Ist klar, Du führst eine mathematische Rechenoperation aus und kommst in den Überlauf.
Ich würde da jetzt nicht anfangen, das mit Sonder-IFs zu schmücken, sondern dann eher auf das SHL ausweichen, was PN/DP Dir anfangs schon vorgeschlagen hat. Wenn da FFFF drin steht, und Du ein Bit weiterschiebst, ällt einfach nur die höchstwertige 1 runter, und hinten mußt Du die dann ja eh wieder mit dem OR auffüllen. Also steht wieder FFFF drin.
--> Siehe auch das Code-Beispiel von PN/DP in #21
Ich habe schon eine andere Lösung. Möchte ungern nochmal alles über Bord werfen. Ist zwar nicht "schön" aber dafür selten ;)

1697460331535.png

Sobald das Bitmuster 16#7FFF erreicht starte ich einen zweiten Timer wieder mit 150ms. Ist dieser abgelaufen schreibe ich 16#FFFF in das Bitmuster.
 
Ja genauso hatte ich das gemeint. Einmal beim Betätigen und einmal beim Loslassen.


Ich habe schon eine andere Lösung. Möchte ungern nochmal alles über Bord werfen. Ist zwar nicht "schön" aber dafür selten ;)

Anhang anzeigen 72160

Sobald das Bitmuster 16#7FFF erreicht starte ich einen zweiten Timer wieder mit 150ms. Ist dieser abgelaufen schreibe ich 16#FFFF in das Bitmuster.
Da steigt doch nach Dir keiner mehr durch...
Du brauchst nicht alles über Bord werfen... Nur die Zeile
#TAMPE[#DB_Array_Index] := #TAMPE[#DB_Array_Index] * 2 + 1 gegen
#TAMPE[#DB_Array_Index] := SHL(#TAMPE[#DB_Array_Index], 1) OR 1 tauschen.
Dann kannst Du alle anderen Sonderstricksachen weglassen und jeder sieht, was da passiert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Da steigt doch nach Dir keiner mehr durch...
Du brauchst nicht alles über Bord werfen... Nur die Zeile
#TAMPE[#DB_Array_Index] := #TAMPE[#DB_Array_Index] * 2 + 1 gegen
#TAMPE[#DB_Array_Index] := SHL(#TAMPE[#DB_Array_Index], 1) OR 1 tauschen.
Dann kannst Du alle anderen Sonderstricksachen weglassen und jeder sieht, was da passiert.
Ok überredet. Das ist wirklich viel besser und übersichtlicher. Hat funktioniert


Vielen Dank an alle für die tolle Hilfe und noch eine schöne Woche.
 
Im ersten Schritt die Ausgabevariable (INT oder WORD) mit 1 initialisieren, dann alle 150ms ...
Warum nicht mit 0 "initialisieren", während der FussTaster inaktiv ist? Wenn das BitMuster 0 ist und damit erstmals
Ausgabe := Ausgabe * 2 + 1 ;
gerechnet wird, dann startet Ausgabe mit dem Wert 1 (Ausgabe := 0 * 2 + 1), wie gefordert.

PS: (*) geht nur bis 15 Bit. im 16. Schritt muß -1 ausgegeben werden.. Die SHL-Varianten gehen beliebig oft
-1 ist doch 16#FFFF bzw. 2#11111111 11111111 beim DatenTyp INT, also zum Glück genau das BitMuster, bei dem die "Zählung" gestoppt werden soll.

Was passiert, wenn das BitMuster 01111111 11111111 ist und damit
'BitMuster := BitMuster + BitMuster + 1' gerechnet wird?
Klar, Überlauf, aber wie lautet das Ergebnis? Doch wohl "zufällig" 11111111 11111111 = -1 oder wäre eine CPU da anderer Meinung als der Windows-Rechner?

Sobald das Bitmuster 16#7FFF erreicht starte ich einen zweiten Timer wieder mit 150ms. Ist dieser abgelaufen schreibe ich 16#FFFF in das Bitmuster.
Wozu der zweite Timer? Verstehe ich nicht.
Wenn das BitMuster als INT interpretiert, -1 erreicht hat, darf man nichts mehr draufaddieren.
Etwas allgemeiner formuliert, wenn BitMuster negativ ist, überschreibt man es mit -1.
 
Zuletzt bearbeitet:
Ich glaube, jetzt habe ich die nachgeschobenen Änderungen des Ablaufs berücksichtigt.
Code:
bInTon := FussTaster AND NOT TON.Q ; // TriggerBit für Timer und nächstes BitMuster
TON( IN:=bInTon, PT:=T#150ms );

bTrigTelegr := FALSE ;
IF bFussTaster = bFussTasterZuvor THEN
    ; // idle
ELSIF bFussTaster THEN    // pos. Flanke: Start
    iBitMuster  := 0 ;    // 'iBitMuster' INT STATIC !!!
    wBitMuster  := 1 ;
    bTrigTelegr := TRUE ; // Senden triggern >>>===>
ELSE                      // neg. Flanke: Stopp
    wBitMuster  := INT_TO_WORD( iBitMuster ) ;
    iBitMuster  := 0 ;
    bTrigTelegr := TRUE ; // Senden triggern >>>===>
END_IF ;
bFussTasterZuvor := bFussTaster ; // 'bFussTasterZuvor' BOOL STATIC !!!

IF NOT bInTon THEN
    ; // idle
ELSIF iBitMuster < 0 THEN // "Anschlag" erreicht
    iBitMuster  := -1 ;
ELSE  // sonst nächstes BitMuster bilden
    iBitMuster  := iBitMuster + iBitMuster + 1 ;
END_IF ;
 
Zuletzt bearbeitet:
Zurück
Oben