Timer bzw. Funktion "pausieren"

  • VB.NET

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Timer bzw. Funktion "pausieren"

    Hallo,

    ich hätte da ein kleines dringliches Problem. Wir nutzen zur Zeitmessung eine Lichtschranke welche via Arduino seriell mit dem Computer verbunden ist. Der Auslöseeffekt durch die Lichtschranke ist dass sie von irgendeiner kleinen Zahl auf > 0 geht. Das ganze wird am Computer ausgelesen und dementsprechend in einer DatagridView aufgelistet. Das ganze mache ich über einen Timer.

    VB.NET-Quellcode

    1. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    2. If TextBox1.TextLength > 0 Then
    3. Button1.PerformClick()
    4. TextBox1.Clear()
    5. End If
    6. End Sub


    Die Textbox wird gefüllt von einem DataReceived Command.

    Das funktioniert auch alles wunderbar aber... wenn die Lichtschranke durchbrochen ist wird das Signal durchgehend ausgegeben und somit aktuell die DatagridView total zugespammt. Uns ist es aber wichtig dass nach dem 1. Auslösen das heißt >0 dann für 3 Sekunden das Signal gestoppt wird. Ich hoffe dass konnte ich jetzt gut formulieren? Vielleicht ein wenig einfacher. Unser Anwendungsfall: Ich habe einen Timer laufen der permanent eine Zeit aktualisiert und zwar ist das die aktuelle Computerzeit hh:mm:ss:xxx sobald die Lichtschranke durchbrochen wird zieht er diese Uhrzeit und trägt sie in einer Liste ein.

    Auto kommt -> Lichtschranke unterbricht Signal geht raus Signal wird eingetragen in Tabelle und solange wie die Lichtschranke durchbrochen ist wird auch die Tabelle zugeschrieben. Das möchten wir nicht!. Wir möchten, Auto kommt -> Lichtschranke unterbricht 1 Signal das ankommt wird genommen dann wird 3 Sekunden gewartet (sollte immernoch das Auto dazwischen sein darf es rück wieder auslösen) aber auch danach wieder 3 Sekunden warten etc etc...

    Am besten wäre es eigentlich wenn ich meine gegebene Funktion einfach kurz pausieren könnte nachdem sie aufgerufen wurde.

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. msg = SerialPort1.ReadExisting
    3. Me.Invoke(New Action(
    4. Sub()
    5. TextBox1.Clear()
    6. TextBox1.Text += msg
    7. End Sub))
    8. End Sub


    Jetzt meine Frage, wie bekomme ich das am gescheidetsten hin. Ich hatte es über das Intervall des Timers selbst probiert das klappt auch aber verfälscht natürlich den Wert da er dann je nach Tick mal früher oder später auslöst. Ich hoffe ihr könnt mir helfen :thumbsup:

    Mit freundlichen Grüßen
    Frederik

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „HoneyPot“ ()

    Mir fallen da ein, zwei Kleinigkeiten im Code auf:
    1. Warum Button1.PerformClick und nicht direkt den Click-Handler aufrufen? Was macht Button1 eigentlich? Gib deinen Controls aussagekräftige Namen, damit man am Name erkennen kann, wofür sie zuständig sind.
    2. Wenn du zuerst TextBox1.Clear aufrufst (auch hier aussagekräftige Namen), dann ist in der TextBox ja leer. TextBox1.Text += msg fügt dem bestehenden Text am Ende mehr Text hinzu. Da in der TextBox ja kein Text mehr drin steht, kommt am Ende das gleiche heraus, wie wenn du den Text einfach ersetzt ([tt]TextBox1.Text = msg[tt]), und dann kannst du dir das Clear auch sparen.

    Dann was Größeres:
    Die SerialPort-Klasse ist ziemlich vermurkst. Das DataReceived-Event feuert nur sehr inkonsistent. Hier ist erklärt, wie man die Klasse richtig verwendet: Serial Port

    So. Jetzt zum eigentlichen Problem:
    Du solltest beim Arduino den Code abändern, dass nur dann eine Nachricht an den PC gesendet wird, wenn sich der Zustand der Lichtschranke ändert. Das könnte so aussehen:

    C-Quellcode

    1. void setup()
    2. {
    3. pinMode(...);
    4. PreviousState = digitalRead(...);
    5. }
    6. bool PreviousState;
    7. void loop()
    8. {
    9. bool NewState = digitalRead(...);
    10. if (NewState != PreviousState)
    11. {
    12. PreviousState = NewState;
    13. Serial.write(NewState ? 0x01 : 0x00);
    14. }
    15. }

    Am PC weißt du dann: Wannimmer du ein 1-Byte empfängst, dann wurde die Lichtschranke ausgelöst, und wannimmer du ein 0-Byte empfängst, wurde sie... entausgelöst.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @HoneyPot Willkommen im Forum. :thumbup:
    Warum nutzt Du nicht das TextChange-Event der TextBox?
    ====
    Ganz anders:
    Lies das Port im Timer_Tick aus, dann bist Du im Main-Thread und musst nicht invoken.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!