Hallo,
ich habe folgendes Programm für Python geschrieben.
1
import time
2
3
anfang=time.time()
4
zeitdifferenz=0
5
counter=0
6
7
while counter<=600:
8
9
"Unterprogrammaufruf"
10
11
while zeitdifferenz<=1:
12
ende=time.time()
13
zeitdifferenz=ende-anfang
14
15
anfang=time.time()
16
zeitdifferenz=0
17
counter+=1
Sinn des ganzen:
Es wird 10 Minuten lang 1x in der Sekunde ein Unterprogramm aufgerufen.
Das Unterprogramm läuft nur wenige Millisekunden. Wenn das Programm
ausgeführt wird, geht die Prozessorlast auf nahezu 100%, und das für die
gesamte Laufzeit von 10 Minuten. Gibt es eine bessere Möglichkeit, die
Wartezeit von 1 Sekunde zu erreichen?
1
time.sleep(1)
möchte ich nicht unbedigt verwenden, da das Unterprogramm nicht immer
die gleiche Laufzeit benötigt, und es so zu Ungenauigkeiten kommt.
Kann man das ganze z.B. mit Interrupts lösen? Bisher habe ich hie
rnichts passendes gefunden. Alle vorschläge gingen in die Richtung von
time.sleep.
Gruß Rüdiger
Hallo,
danke für die schnelle Antwort.
Ich habe es jetzt folgendermasen probiert:
1
import time
2
counter=0
3
4
while counter<=600:
5
6
counter+=1
7
8
anfang=time.time()
9
10
"Unterprogrammaufruf"
11
12
ende=time.time()
13
zeit=ende-anfang
14
15
time.sleep(1-zeit)
Das sieht schon sehr viel besser aus. Die Prozessorlast ist schon
relativ gering.
Ich warte mal noch ab, ob noch weitere Vorschläge kommen. Ansonsten ist
das schon mal ein möglicher Weg. Dieser Weg hat noch eine geringe
Ungenauigkeit in der Zeit, damit könnte ich aber noch leben. Mein erster
Versuch war schließlich auch nicht zu 100% genau.
Gruß Rüdiger
R. F. schrieb:> Es wird 10 Minuten lang 1x in der Sekunde ein Unterprogramm aufgerufen.> Das Unterprogramm läuft nur wenige Millisekunden. Wenn das Programm> ausgeführt wird, geht die Prozessorlast auf nahezu 100%, und das für die> gesamte Laufzeit von 10 Minuten. Gibt es eine bessere Möglichkeit, die> Wartezeit von 1 Sekunde zu erreichen?
Das hat zunächst nichts mit Python zu tun. Wäre in jeder anderen Sprache
auch so. Dein Programm prüft in einer Schleife so schnell wie der
Rechner kann (also vermutlich einige Millionen mal pro Sekunde), ob die
Zeit denn schon abgelaufen ist. Das heißt natürlich, dass es den
Prozessor auch ständig zu 100% mit diesen Massen an Vergleichen
auslastet.
Solche Schleifen sind daher in Multitasking-Systemen zu vermeiden.
Besser ist, den Prozess so lange schlafen zu legen, bis es wieder etwas
zu tun gibt. Dadurch berücksichtigt ihn das Betriebssystem (konkret der
Scheduler) in der Zeit bis dahin nicht, und er verbraucht keine unnötige
Rechenzeit. Das entspricht dem Vorschlag von Peter II.
R. F. schrieb:> Dieser Weg hat noch eine geringe Ungenauigkeit in der Zeit, damit könnte> ich aber noch leben.
Es gibt auch Funktionen, bei denen man die Wartezeit nicht relativ,
sondern absolut angibt, also nicht, wie lange man warten will, sondern
bis wann. Damit bekommt man die Ungenauigkeit weg. Ob das mit Python
portabel geht und wenn ja, wie, weiß ich aber nicht.
Hallo,
wie gewünscht mehr Infos zur Aufgabenstellung.
Ich baue eine Beleuchtungssteuerung für eine Modellbahn, bei welcher
jede Lampe einzeln über den Rechner gesteuert werden kann.
Die Lampen werden von einer Zentrale über den Selectrix-Bus
(Modellbahnspezifisches Bussystem) gesteuert. Die Zentrale erhält ihre
Befehle vom Rechner über eine RS232-Schnittstelle und setzt die Befehle
in das Selecrtrix-System um. Ich muss nur dann neue Befehle senden, wenn
ich einen Schaltzustand ändern möchte. Kommt über die RS232 kein neuer
Befehl, behält die Zentrale den aktuellen Schaltzustand bei.
Mein Python-Programm besteht im wesentlichen aus 3 Teilen:
1. Dem oben stehenden Hauptprogramm. Dieses ruft 1 mal in der Sekunde
die Unterprogramme auf und erzeugt die Zählvariable counter.
2. Ein Unterprogramm für Jedes Haus. Pro Lampe gibt es einen
True/False-Wert. In Abhängigkeit des Counterwertes werden die einzelnen
Lampen auf True oder False gesetzt. Pro Haus werden die einzelnen Werte
in einer Liste zusammengefasst und per return an das Hautprogramm
übergeben.
3. Ein Unterprogramm pro Adresse. Eine Adresse besteht aus 8 Bit und
kann somit 8 Lampen steuern. Das Unterprogramm bekommt die Liste von dem
zugeordneten Haus oder mehreren Häusern übergeben und prüft, ob es eine
Veränderung gab. Wenn nein, passiert nichts. Wenn ja, wird der Wert über
die RS232 gesendet.
Warum fasse ich die Unterprogramme für das Haus und die Adresse nicht
zusammen und spare mir den Umweg über die Listen?
Das hat folgenden Grund. Die Zentrale erwartet pro Adresse immer genau 8
Bit. Jedes Haus hat aber eine andere Anzahl an Lampen. Dadurch haben
viele Häuser mehrere Adressen. weiterhin kommt es vor, dass einige
Adressen Lampen von 2 unterschiedlichen Häusern ansteuern. Dadurch kann
ich alle möglichen Bits effektiv ausnutzen.
Wegen der Übersichtlichkeit bei späteren Änderungen will ich aber pro
Haus eine Datei haben. Deswegen diese Trennung und damit der Umweg üner
die Listen (Arrays).
Eine Anmerkung noch zu dem RS232-Protokoll. Die Zentrale erwartet pro
Adresse 2 Byte. Das erste Byte ist die Adresse (Bit 0 bis 6) und ein
Schteib/Lese-Bit an Bit7. Das zweite Byte sind die Daten für die 8
Schaltkanäle.
Gruß Rüdiger
PS: Im Anhang das Programm. Fertig ist es allerding snoch nicht. Da
fehlen noch unzählige Häuser.
Hallo,
zunächst einmal Danke an alle für eure Mühe, echt klasse!
Der aktuelle Stand ist derzeit folgender:
Ich habe das Programm jetzt auf meinen RaspberryPi kopiert und getestet.
Die zweite von mir gepostete Variante hat eine Abweichung von unter 2
Sekunden auf die gesamten 10 Minuten. Das reicht vollkommen aus, das
merkt bei der Anwendung kein Mensch. Die Prozessorlast ist fast nicht
messbar. Wenn der Pi sonst nichts zu tun hat, liegt die Anzeige bei ca.
1%. Perfekt!
Auf dieser Basis werde ich das Programm erst einmal weiterentwickeln.
Alle anderen geposteten Vorschläge werde ich bei Gelegenheit
ausprobieren bzw. mich einlesen. Für dieses Projekt zwar vorerst nicht
mehr relevant, aber man will ja dazu lernen. Und vielleicht kann man das
erlernte dann im nächsten Projekt gebrauchen, oder irgend wann dieses
Programm verbessern. Falls es noch weitere Varianten gibt, immer her
damit. Das nächste verregnete Wochenende kommt bestimmt!
Das gleiche gilt auch für andere Fehler oder Verbesserungen, welche ihr
findet. Ich bin für alle Anregungen und Tipps dankbar, auch wenn es
jetzt erst einmal funktioniert.
Gruß Rüdiger
R. F. schrieb:> Warum fasse ich die Unterprogramme für das Haus und die Adresse nicht> zusammen und spare mir den Umweg über die Listen?
Weil das, so wie du es jetzt machst einfach Guter Programmierstil[TM]
ist :-) Lob am Freitag dafür!