Forum: PC-Programmierung Raspberry Laufzeit in millisekunden


von Simo (Gast)


Lesenswert?

Hallo,

wie komme ich unter mit C (unter Raspbian auf den Raspberry) an die 
Laufzeit in Millisekunden?

aus der Zum Wörterbuch hinzufügen kenne ich den Befehl millis(); leider 
ist der beim PI nicht Standard implementiert.

Vielen Dank

von Christophe J. (chj)


Lesenswert?


von Rolf M. (rmagnus)


Lesenswert?

Siehe "man clock_gettime".

von asdf (Gast)


Lesenswert?

Simo schrieb:
> aus der Zum Wörterbuch hinzufügen kenne ich den Befehl millis(); leider
> ist der beim PI nicht Standard implementiert.

So weit ich das sehe, ist millis() eine Funktion, die im Arduino 
verwendet wird. Und auf dem PI läuft kein Arduino, sondern Linux.
Weil millis() nicht zum Sprachumfang von C gehört, ist es auch nicht 
sinnvoll, wenn du sagst, daß der PI "nicht standard implementiert" ist.
Schau mal nach den Zeitfunktionen von C. Links dafür hast du ja schon 
bekommen. Und die Suchmaschine wird dir sicher auch einiges verraten. 
Unter anderem auch Beispiele, wie man die C-Funktionen verwendet.

von PittyJ (Gast)


Lesenswert?

man gettimeofday

von Johnny B. (johnnyb)


Lesenswert?

Wenn ich "Millisekunden" im Zusammenhang mit Raspberry und Raspbian 
höre, läuten bei mir die Alarmglocken.
Raspbian ist kein Echtzeitbetriebssystem, dem muss man sich bewusst 
sein. Selbst wenn es so eine Funktion gäbe, wäre die Genauigkeit nicht 
vorhersehbar.

von Peter II (Gast)


Lesenswert?

Johnny B. schrieb:
> Wenn ich "Millisekunden" im Zusammenhang mit Raspberry und Raspbian
> höre, läuten bei mir die Alarmglocken.
> Raspbian ist kein Echtzeitbetriebssystem, dem muss man sich bewusst
> sein. Selbst wenn es so eine Funktion gäbe, wäre die Genauigkeit nicht
> vorhersehbar.

warum sollte die Genauigkeit nicht vorhersehbar sein? Auch eine Rapsi 
hat Timer die sehr genau sind und diese werden dafür nur abgefragt.

Du meinst das Timing eines kompletten Programm, ja das ist nicht auf die 
MS genau vorhersehbar. Aber die Zeit selber ist kein Problem.

von Simo (Gast)


Lesenswert?

vielen Dank für die nachrichten...

joa millis() kenn ich von Arduino <- weiß nich was für nen kack ich da 
oben geschrieben habe, aber vermutlich war ich opfer der Autokorrektur 
und habs nicht gemerkt.

Genauigkeit ist nicht so wichtig... ich möchte im 400ms und im 700ms 
takt 2 tools abfrage / starten

dazu brauch ich eine whileschleife die dauerläuft
1
definiere timer, old1, old2; 
2
dauer1 = 400;
3
dauer2 = 700;
4
5
while(1){
6
  timer = JETZT[ms]
7
8
  if( old1 + dauer1 < timer ) {
9
    old1 = timer //update old1
10
    machwas 1;
11
  }
12
13
  if( old2 + dauer2 < timer ) {
14
    old2 = timer //update old2
15
    machwas 2;
16
  }
17
18
19
}

leider bekomm ichs auf dem PI nicht hin :(

ob das jetzt 50ms eher oder später kommt ist VÖLLIG egal... ebenso kann 
es sein, dass "machwas 1" mit "machwas 2" kollidiert und dann eines auf 
das andere warten muss (das wären dann ~4-6ms), aber das ist völlig 
egal!

Vielen Dank

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Mit Python und pigpio geht es recht genau, ein paar Mikrosekunden sollen 
es angeblich sein. Der Trick ist, schnell zwei Zeitpunkte zu erfassen 
und in Ruhe danach die Zeitdifferenz auszurechnen:

Das hier habe ich vor ein paar Tagen gepostet, aus einem anderen 
Programm umgeschrieben.
https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=134270&start=25
1
def WaitDRDY():
2
    start = pi.get_current_tick()
3
    elapsed = pi.get_current_tick() - start
4
    # Waits for DRDY to go to zero or TIMEOUT seconds to pass
5
    drdy_level = pi.read(17) # ADS1256 /DRDY
6
    while (drdy_level == 1) and (elapsed < 500000):
7
        elapsed = pi.get_current_tick() - start
8
        drdy_level = drdy_level = pi.read(17)
9
    if elapsed >= 800000:
10
        print("WaitDRDY() Timeout\r\n")

von R. M. (rmax)


Lesenswert?

Simo schrieb:

> dazu brauch ich eine whileschleife die dauerläuft

Solche Busy-Loops sind unter Multitasking-Betriebssystemen wie Linux 
meist keine gute Idee, weil sie unnötig Rechenzeit verbraten. 
Stattdessen gibt es Möglichkeiten, einen Prozeß schlafen zu legen "bis 
seine Zeit gekommen ist". Während der Wartezeit kann die CPU dann 
entweder andere Prozesse bearbeiten oder Strom sparen.

Schau Dir mal select() an, damit kann man sowas machen.

: Bearbeitet durch User
von Operator S. (smkr)


Lesenswert?

oben genannt wurde ja schon clock_gettime()
nimm nun noch nanosleep hinzu und schon hast du deine wartefunktion ohne 
busy waiting

Wenns dir nicht um die Genauigkeit geht, kannst du auch sowas machen:
1
struct timespec sleepTime;
2
3
sleepTime.tv_nsec = 100000000; //100ms
4
sleepTime.tv_sec = 0;
5
6
int dauer1 = 0;
7
int dauer2 = 0;
8
while(1){
9
10
  nanosleep(&sleepTime, NULL);
11
12
  if(dauer1 > 3 ) {
13
    dauer1 = 0 //update old1
14
    machwas 1;
15
  } else {
16
    dauer1++;
17
  }
18
19
  if( dauer2 >6 ) {
20
    dauer2 = 0 //update old2
21
    machwas 2;
22
  } else {
23
    dauer2++;
24
  }
25
26
}

so als quick&dirty Lösung, ansonsten 2 Threads machen mit der jeweils 
eigenen nanosleep Zeit.

von Simo (Gast)


Lesenswert?

@Christoph Kessler:
Python kommt nicht in Frage...

@R. Max
Select klingt spannend, leider finde ich nur wenig lösungen dir mir 
helfen, da ich zu schnell im datenbanksektor bin...
evtl. kannst du mir ne genauere erläuterung geben

@Operator S.
die idee ist gut... werde ich nochmal "genauer" verfolgen :) ...

=> trotzalledem würden mich "multithreads" noch mehr interessieren...
wie kann ich zwei sachen "gleichzeitig" abarbeiten, ohne dass diese sich 
in die quere kommen <- bisher habe ich immer nur ein Programm, dass mehr 
oder weniger von oben nach unten abarbeitet ...


Dankööö

von Operator S. (smkr)


Lesenswert?

Schau dir pthread an oder generell POSIX Threads. Ist am Anfang etwas 
hakelig wenn man sich nur sequentielle Programmierung gewohnt ist, aber 
wenn mans mal raus hat, ist man auch schneller gewillt threads 
einzusetzen statt alles in einem. Definitiv die Einarbeitungszeit wert, 
auch wenns etwas länger dauern sollte. Nicht aufgeben!
Bei C++ hättest du auch std::thread, wenn das eine Option für dich ist.

von R. M. (rmax)


Lesenswert?

Simo schrieb:

> @R. Max
> Select klingt spannend, leider finde ich nur wenig lösungen dir mir
> helfen, da ich zu schnell im datenbanksektor bin...
> evtl. kannst du mir ne genauere erläuterung geben

Hier ertsmal die Doku zu select():
http://man7.org/linux/man-pages/man2/select.2.html

Damit kann man auf Ereignisse ("es sind neue Daten angekommen" bzw. "es 
können Daten abgeschickt werden") auf mehreren Filedeskriptoren (offenen 
Dateien oder Netzwerkverbindungen) gleichzeitig warten und zusätzlich 
einen Timeout setzen, nach dessen Ablauf der Aufruf in jedem Fall 
zurückkehrt. Läßt man die Filedeskriptoren weg und setzt nur den 
Timeout, macht select() im Grunde das gleiche wie nanosleep(), 
allerdings mit einer zeitlichen Auflösung in Mikrosekunden statt 
Nanosekunden.

Als Alternative zu einem festen Takt (einfach, aber unflexibel) oder 
Threads (halte ich hier für Overkill) könntest Du jeweils ausrechnen, 
wieviel Zeit bis zum nächsten Ereignis noch vergehen muß und die Zeit 
für select() oder nanosleep() dementsprechend setzen.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

http://abyz.co.uk/rpi/pigpio/
pigpio läuft auch mit C, das ist nicht an Python gebunden. Im 
Raspbian-Image ist es schon vorinstalliert.
Die Quellen sind auf Github:
https://github.com/joan2937/pigpio

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.