Timer

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Timer

Beitrag von Timm Thaler »

mschnell hat geschrieben:"Vorgibt" schon, dann muss das Timing aber auf wenige Prozent konstant bleiben. Davon kann man bei einem User-Programm, das in einem Betriebssystem läuft i.A. nicht ausgehen.


Das macht auf dem Raspi auch nicht das User-Programm, sondern die Firmware, genauso wie bei RS232, I2C und SPI. Ich schubse ja auch nicht einzelne Bits auf die RS232, sondern schreibe ein Byte und die Firmware / Hardware übernimmt die zeitgenaue Zerlegung in Bits.

Allerdings ist sowas auch in Software machbar, wenn man die Priorität hochsetzt. Das habe ich mal für die softwaretechnische Erzeugung von MM-Steuersignalen für digitale Modellbahn an der RS232 gemacht. Man sollte sowas nur kurzzeitig machen, weil man sonst den Rechner blockiert, und man wissen was man tut.

mschnell hat geschrieben:Hardware-Chips sind ja im Allgemeinen "beliebig" schnell und brauchen das nicht.


Es wird glaube ich bei einigen AD-Wandlern gemacht, wo der Slave den Takt solange verzögert, bis die Wandlung fertig ist. Und es kann bei Eeproms sinnvoll sein, wo ein Page erase oder Page write schon mal ein paar msec dauern kann.

mschnell hat geschrieben:Das I²C-Protokoll - oder sonst irgendeinen getimeten direkten Hardware-Zugriff in einem User-Programm (das in einem Betriebssystem läuft) zu basteln, halte ich ohnehin für ziemlich daneben.


Ich glaube nicht, dass der TO sich das Protokoll gebastelt hat. Ich fürchte, er startet einfach die Wandlung und macht dann ein delay(1000), weil die Wandlung 750msec dauert, und liest dann wieder aus.

Leider findet man diese Unart in vielen "Tutorials" zu den Sensoren. Ok, ich gebe zu, ich mache das auch manchmal, wenn ich etwas teste. Aber nicht für ein Programm, welches dann vielleicht noch eine Gui hat (Memo.Lines.Add...), und wo der Nutzer dann erstmal 4sec nicht weiss, ob das Programm überhaupt noch läuft. Einige OS schießen Programme, die mehr als 2sec hängen gnadenlos ab.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Timer

Beitrag von mschnell »

+1 ! :)
-Michael

Benutzeravatar
six1
Beiträge: 788
Registriert: Do 1. Jul 2010, 19:01

Re: Timer

Beitrag von six1 »

creed steiger hat geschrieben:
Timm Thaler hat geschrieben:
In der Praxis braucht dafür nur der Sensor nicht antworten.



bei den Dallas one wire gibts das Problem bei mir nicht
(w1-gpio w1-therm aufm raspi)
fehlerhafte Werte werden halt Verworfen
bei /sys/bus/w1/devices/ auslesen gibts keinen Timeout
(und der 750ms Abfrageintervall sollte auch reichen)



und man kann die Wandlung des neuen Wertes bereits nach dem "Wert holen" anstoßen, dann ist der DS18B20 neue Wert beim nächsten Auslesen bereits da und man muss keine 750ms warten.
Gruß, Michael

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Timer

Beitrag von Timm Thaler »

six1 hat geschrieben:und man kann die Wandlung des neuen Wertes bereits nach dem "Wert holen" anstoßen, dann ist der DS18B20 neue Wert beim nächsten Auslesen bereits da und man muss keine 750ms warten.


Stimmt, aber wenn man nur alle 60sec ausliest, ist der "neue" Wert dann auch schon wieder 59sec alt.

Ich würde das wie oben beschrieben mit einem Scheduler machen:

Timer auf 1sec
im Timer:
wenn Minute alt <> Minute neu = Zähler auf Null
Zähler hochzählen jede Sekunde
wenn Zähler = 1 Messung starten
wenn Zähler = 2 Messwert auslesen
... weitere Sensoren
wenn Zähler = x Messwerte ausgeben

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Timer

Beitrag von mschnell »

Echt blöd, wenn der Treiber für das Mess-Equipment nicht so geschrieben ist, dass kein Timing im User-Programm erforderlich ist.

Eine "professionelle" Methode wäre:
- Der Treiber erlaubt einen "blocking read" Zugriff, der zurückkommt, wenn ein neuer Messwert vorliegt. Er kann dann direkt beim im Read-Ergebnis den Messwert übergeben.
- Das User-Programm startet einen Worker-Thread, der das (file-) read aufruft und dadurch wartet, bis ein neuer Messwert vorliegt, ohne die CPU zu belasten.
- wenn der Thread aus dem Read zurückkommt schmeißt er ein Event für den mainthread mit TThread.Synchronize (und übergibt dabei den Messwert). Er kann dabei auch den Zeitpunkt notieren, um eine etwas bessere Zeit-Genauigkeit zu bekommen, falls der Treiber den nicht ohnehin mit übergibt, was besser wäre.)
- Dann startet das Mainthread-Event "irgendwann" und weiß den Messwert und den Zeitpunkt für die Auswertung.

-Michael

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Timer

Beitrag von Timm Thaler »

mschnell hat geschrieben:- Der Treiber erlaubt einen "blocking read" Zugriff, der zurückkommt, wenn ein neuer Messwert vorliegt. Er kann dann direkt beim im Read-Ergebnis den Messwert übergeben.


Und wenn kein Messwert vorliegt, bleibt das Programm hängen. Das sind dann die Leute, die mit BlockingRead die RS232 auslesen, weil ihr Gerät ja "immer" Daten sendet - und wenn jemand den Stecker zieht, stürzt das Programm ab.

Genau so sollte man es meiner Meinung nach nicht machen.

mschnell hat geschrieben:Echt blöd, wenn der Treiber für das Mess-Equipment nicht so geschrieben ist, dass kein Timing im User-Programm erforderlich ist.


Mal ehrlich, wie reden hier wahrscheinlich über 1-wire und I2C Sensoren am Raspi. Da ist "der Treiber" eine pascalio Lib, die das Pinwackeln übernimmt. Natürlich kann man einen Treiber für einen DS18S20 schreiben, der darüber sitzt und macht was Du schreibst. Nur verlagert man das Problem dann nur: Wie weiss denn der Treiber, wann der DS fertig mit der Messung ist. Muss er also immer auf Ackn pollen, sprich den Sensor anfragen ob ein Ergebnis fertig ist, oder auch einen Timer setzen. Und dann ist noch das Problem, wie alt ist das Ergebnis. Muss er also eigentlich ständig neu messen lassen, damit bei einer Abfrage auch ein aktuelles Ergebnis vorliegt. Und dann hat jemand 20 DS am Bus. Also muss er die zyklisch ständig durchgehen. Und vielleicht noch ein paar andere Sensoren, dann dürfen sich die Treiber nicht in die Quere kommen bei der Abfrage.

Da hast Du ganz schnell 10% Auslastung, obwohl vielleicht einmal alle 60sec ein Wert gebraucht wird.

Nee, dann lieber: Messung anstoßen, warten, Messwert abfragen.

Das könnte der TO auch mit einem Einmaltimer erledigen, der bei Start der Messung gestartet wird und nur einmal ein Timerereignis gibt, wenn die Messung beendet wird. Bei mehreren Sensoren muss man sich das aber sauber aufbauen, sonst wird das schnell unübersichtlich.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Timer

Beitrag von mschnell »

Timm Thaler hat geschrieben:Und wenn kein Messwert vorliegt, bleibt das Programm hängen. Das sind dann die Leute, die mit BlockingRead die RS232 auslesen, weil ihr Gerät ja "immer" Daten sendet - und wenn jemand den Stecker zieht, stürzt das Programm ab.

???? Nur der Thread bleibt hängen (aber der hängt ja sowieso fast immer im Read) .

Wenn keine Messwerte kommen, passiert genau nichts besonderes. Die GUI läuft im Mainthread weiter.
Sinnvollerweise macht man natürlich im Mainthread mit einem TTimer eine Überprüfung, ob der zeitliche Abstand zwischen den Messwerten (bzw die zeit nach dem Anstoßen einer Messung) nicht zu groß wird. Dann kann man eine Fehlermeldung ausgeben oder das Programm friedlich beenden.

-Michael

Antworten