H.Brill, ja, per API sind mehrere Timer möglich. Wird aber möglicherweise für einen Neueinsteiger zu kompliziert.
Ich hoffe, ich habe die Fragestellung richtig verstanden.
Habe den Code mal geändert, die Ausgänge 1 bis 3 haben nun einen Timer. Zusätzlich habe ich mal in der Proc GetCheckBoxState was vereinfacht und den originalen Code auskommentiert.
Hinzugekommen sind 3 Eingabefelder. Hier werden die Zeiten in Sekunden eingetragen. Bei Klick auf Zufall werden alle Ausgabe, die keine Zeit haben, wie bisher geschalten. Bei einer Zeit <> 0 wird der Timer runtergezählt und dann die Zufallsfunktion für diesen Ausgang geschalten. Dazu sind hinzugekommen die Procs TimerAction und Timertest.
Code
Declare hD%, hB%, schalt%, statusbar%, OK%, hcombo%, s%
Declare comport%, f%
Declare alle_aus%, alle_ein%, zufall%
Declare chk1%, chk2%, chk3%, chk4%, chk5%, chk6%, chk7%, chk8%
Declare daten%, com$, send$
' ----- Hinzugefügt
Declare Timer1%, Timer2%, Timer3% ' Zeiten für die 3 Timer
Declare IsTimer% ' Flag zeigt an, ob Timer aktiv ist, damit keine Doppelfunktionen auftreten
' Doppelfunktionen würden einen Fehler erzeugen
Declare Edit1%, Edit2%, Edit3%
Randomize ' wird hier einmalig gerufen, ist nicht bei jeder Zufallsfunktion notwendig
'daten% = 1 ' wird nicht benötigt, da ja alle Bits entsprechend der Checkboxen gesetzt werden
Proc GetCheckboxStates
' Geht auch einfacher
daten% = SetBit(daten%, 0, (GetCheck(chk1%)))
daten% = SetBit(daten%, 1, (GetCheck(chk2%)))
daten% = SetBit(daten%, 2, (GetCheck(chk3%)))
daten% = SetBit(daten%, 3, (GetCheck(chk4%)))
daten% = SetBit(daten%, 4, (GetCheck(chk5%)))
daten% = SetBit(daten%, 5, (GetCheck(chk6%)))
daten% = SetBit(daten%, 6, (GetCheck(chk7%)))
daten% = SetBit(daten%, 7, (GetCheck(chk8%)))
' If @GetCheck(chk1%)
' daten% = SetBit(daten%, 0, 1)
' Else
' daten% = SetBit(daten%, 0, 0)
' EndIf
' If @GetCheck(chk2%)
' daten% = SetBit(daten%, 1, 1)
' Else
' daten% = SetBit(daten%, 1, 0)
' EndIf
' If @GetCheck(chk3%)
' daten% = SetBit(daten%, 2, 1)
' Else
' daten% = SetBit(daten%, 2, 0)
' EndIf
' If @GetCheck(chk4%)
' daten% = SetBit(daten%, 3, 1)
' Else
' daten% = SetBit(daten%, 3, 0)
' EndIf
' If @GetCheck(chk5%)
' daten% = SetBit(daten%, 4, 1)
' Else
' daten% = SetBit(daten%, 4, 0)
' EndIf
' If @GetCheck(chk6%)
' daten% = SetBit(daten%, 5, 1)
' Else
' daten% = SetBit(daten%, 5, 0)
' EndIf
' If @GetCheck(chk7%)
' daten% = SetBit(daten%, 6, 1)
' Else
' daten% = SetBit(daten%, 6, 0)
' EndIf
' If @GetCheck(chk8%)
' daten% = SetBit(daten%, 7, 1)
' Else
' daten% = SetBit(daten%, 7, 0)
' EndIf
EndProc
Proc SetChkBx
'alle checkboxen neu setzen
Parameters s% 'schalter: 1= alle an; 0= alle aus
If s% = 2
'''Randomize 'ganz wichtig!! wird am Programmanfang einmalig aufgerufen
CaseNot Timer1% : SetCheck chk1%, Rnd(2)
CaseNot Timer2% : SetCheck chk2%, Rnd(2)
CaseNot Timer3% : SetCheck chk3%, Rnd(2)
SetCheck chk4%, Rnd(2)
SetCheck chk5%, Rnd(2)
SetCheck chk6%, Rnd(2)
SetCheck chk7%, Rnd(2)
SetCheck chk8%, Rnd(2)
Else
SetCheck chk1%, s%
SetCheck chk2%, s%
SetCheck chk3%, s%
SetCheck chk4%, s%
SetCheck chk5%, s%
SetCheck chk6%, s%
SetCheck chk7%, s%
SetCheck chk8%, s%
EndIf
EndProc
Proc GetComInput
Parameters id%
Declare in$
in$ = @ReadCom$(f%,8)' 8 Zeichen einlesen
Case @Len(in$):SetText statusbar%, "Antwort : " + Str$(ord(in$))
EndProc
Proc Senden
' 4 Byte - Rahmen zum Senden erstellen
send$ = Chr$(daten%)
WriteCom(f%, send$)
ComError(f%)
GetComInput(f%)
Sleep 1000
EndProc
Proc TimerAction
Declare TimerEnde% ' Zählt, wie viele Timer bei 0 sind
' wenn 3 (also alle) Timer 0 erreicht haben, KillTimer ausführen
If IsTimer% ' Nur ausführen, wenn der Timer aktiv ist!
If Timer1%
Dec Timer1%
SetText Edit1%, Str$(Timer1%)
If Timer1% = 0
Inc TimerEnde%
SetCheck chk1%, Rnd(2)
EndIf
EndIf
If Timer2%
Dec Timer2%
SetText Edit2%, Str$(Timer2%)
If Timer2% = 0
Inc TimerEnde%
SetCheck chk2%, Rnd(2)
EndIf
EndIf
If Timer3%
Dec Timer3%
SetText Edit3%, Str$(Timer3%)
If Timer3% = 0
Inc TimerEnde%
SetCheck chk3%, Rnd(2)
EndIf
EndIf
GetCheckboxStates' Checkboxen auswerten u. Bits setzen
Senden
If TimerEnde% = 3
KillTimer ' alle Timer abgelaufen, Timer löschen
IsTimer% = 0
EndIf
EndIf
EndProc
Proc TimerTest
Declare TimerStart% ' Zählt, wie viele Timer gesetzt sind, mindestens ein Timer <> 0 startet Timer
If GetText$(Edit1%) <> ""
Timer1% = Val(GetText$(Edit1%))
Case Timer1% : Inc TimerStart%
EndIf
If GetText$(Edit2%) <> ""
Timer2% = Val(GetText$(Edit2%))
Case Timer2% : Inc TimerStart%
EndIf
If GetText$(Edit3%) <> ""
Timer3% = Val(GetText$(Edit3%))
Case Timer3% : Inc TimerStart%
EndIf
If TimerStart%
SetTimer 1000 ' Timer auf eine Sekunde einstellen
IsTimer% = 1
EndIf
EndProc
Proc Dialog
'Dialogfenster erzeugen
hD% = @Create("Dialog",%DeskTop,"seriell steuern 8 Ausgänge ",50,350,550,310)
'Funktionsbutton mit erzeugen
hB% = @Create("Button",hD%,"&ENDE",10,100,70,25)
schalt% = @Create("Button", hD%, "&Schalten", 100, 10, 70, 25)
alle_aus% = @Create("Button",hd%,"&alle Aus",10,70,70,25)
alle_ein% = @Create("Button",hd%,"&alle Ein",100,70,70,25)
zufall% = @Create("Button",hd%,"&Zufall",100,100,70,25)
' Hinzugefügt: Eigabefelder für 3 Timer
@Create("Text", hD%, "Timer1", 40, 155, 60, 20)
@Create("Text", hD%, "Timer2", 40, 180, 60, 20)
@Create("Text", hD%, "Timer3", 40, 205, 60, 20)
Edit1% = @Create("Edit", hD%, "", 100, 150, 70, 24)
Edit2% = @Create("Edit", hD%, "", 100, 175, 70, 24)
Edit3% = @Create("Edit", hD%, "", 100, 200, 70, 24)
chk1% = @Create("CheckBox", hD%, "Ausgang 1", 350, 10, 100, 25)
chk2% = @Create("CheckBox", hD%, "Ausgang 2", 350, 40, 100, 25)
chk3% = @Create("CheckBox", hD%, "Ausgang 3", 350, 70, 100, 25)
chk4% = @Create("CheckBox", hD%, "Ausgang 4", 350,100, 100, 25)
chk5% = @Create("CheckBox", hD%, "Ausgang 5", 350,130, 100, 25)
chk6% = @Create("CheckBox", hD%, "Ausgang 6", 350,160, 100, 25)
chk7% = @Create("CheckBox", hD%, "Ausgang 7", 350,190, 100, 25)
chk8% = @Create("CheckBox", hD%, "Ausgang 8", 350,220, 100, 25)
' erste Checkbox setzen
SetCheck chk1%, 0
statusbar% = @Create("StatusWindow", hD%, "Ready !")
Clear OK%' OK% auf 0 setzen
' --- Hinzugefügt, unsichtbares Hauptfenster, damit Timer möglich ist
WindowStyle 112
Window 0, 0 - 0, 0
' --- Zeitintervall 1 Sekunde
WhileNot Ok%' solange OK% gleich 0 ist
'----- Hier in der Schleife warten wir mit WaitInput auf Benutzer - Eingaben
' Wir verwenden die in XProfan 10 neue Funktion @Clicked() statt @GetFocus()
WaitInput
' --- Hinzugefügt
Case %wmTimer : TimerAction
'----- Programm wird beendet
If @Clicked(hB%)
'ENDE wurde angeklickt, OK% wird auf 1 gesetzt und somit
' die Schleife verlassen, das Fenster gelöscht und das Programm beendet.
Ok% = 1
'----- Fenster wird geschlossen
ElseIf %Key = 2
' Hier wird das 'X' (rechts oben Schließen) ausgewertet
OK% = 1
'---- Zufalls Routine, Ausgänge werden per Zufall gesetzt!
ElseIf @Clicked(zufall%)
' Ausgänge in zufälliger Reihenfolge schalten
'@Rnd(255 + 12) - 12
TimerTest
SetChkBx(2)
GetCheckboxStates' Checkboxen auswerten u. Bits setzen
senden
'----- einzeln gesetzte Ausgänge werden gesetzt
ElseIf @Clicked(schalt%)
' Relais schalten.
daten% = 0
GetCheckboxStates' Checkboxen auswerten u. Bits setzen
Senden
' alle Ausgänge ein bzw. ausschalten
'----- alle Ausgänge werden gesetzt
ElseIf @Clicked(alle_ein%)
daten% = setbit(daten%, 128, 1)
SetChkBx 1'checkboxen einschalten
GetCheckboxStates' Checkboxen auswerten u. Bits setzen
senden
'----- alle Ausgänge werden ausgeschaltet
ElseIf @Clicked(alle_aus%)
daten% = setbit(daten%, 128, 0)
SetChkBx 0'checkboxen ausschalten
GetCheckboxStates' Checkboxen auswerten u. Bits setzen
senden
EndIf
EndWhile
'Dialogfenster (incl. Button, usw.) entfernen
@DestroyWindow(hD%)
' --- Hinzugefügt, Timer löschen, falls noch aktiv
If IsTimer%
KillTimer
IsTimer% = 0
EndIf
EndProc
' Relaiskarte initialisieren
daten% = 0
f% = @OpenCom("COM4", 1024, 1024)
SetCom("COM4: 38400, N, 8, 1")
Senden
' Hier wird die Dialogbox (Procedur) aufgerufen
Dialog
' Programm Ende
CloseCom(f%)
End
Alles anzeigen
Ich hoffe, das paßt so.
Gruß Volkmar