Seite 2 von 3

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 14:31
von __deets__
Es ist auch nur eine Kleinigkeit - so wie zu wissen wo die Bremse beim Auto ist auch nur eine Kleinigkeit ist. Aber man kommt nicht drum rum das zu wissen.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 15:07
von RudiOnTheAir
Läuft...Reichte nicht, nur nach SEQUENCE zu triggern, sondern das [pos][1] musste da noch mit rein.

Die LED wird jetzt angesteuert. Hab zwar noch ne Warnung, weil der Channel already in use ist. Aber das findet sich, denke ich... Spannend wird es jetzt, wie syncron das ganze geht, wenn das auf zwei getrennten Raspis läuft..
Und das Tutorial... Sehr umfangreich. Hab da aber nicht die Lösung gefunden, weil ich da dieses Problem nicht finden konnte. Gibt viele Beispiele. Auch das googlen nach Codefragmenten ist schwierig, wenn man nicht die richtigen Fragen stellt. (Zitat: Das fünfte Element;)

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 15:18
von __deets__
Ich weiss nicht, was "Reichte nicht, nur nach SEQUENCE zu triggern, sondern das [pos][1] musste da noch mit rein." uns sagen soll. Das klingt nicht wirklich danach als ob du verstanden hast, was deine GPIO-Modifikation wirklich an problemen hatte. Wie dem auch sei, das Tutorial muss man durcharbeiten, nicht durchsuchen. Und da lernt man dann auch, warum es einen Unterschied zwischen

Code: Alles auswählen

while True:
    print('a')
print('b')
und

Code: Alles auswählen

while True:
    print('a')
    print('b')
gibt.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 15:48
von RudiOnTheAir
Ja, das mit dem einrücken hatte ich gesehen. Der Editor Geany zeigt das ja sogar an, wenn ich diese Klammern im Code richtig deute.

Und das Tut durcharbeiten, ist zeitlich nicht drin. So gerne ich das auch machen würde. Mit diesem kleinen Programm geht es erstmal nur um einen Versuch, wie genau diese Berechnungen sind, und wie gross die Abweichungen sind. Wenn das ausreichend ist, wird es daran gehen, eine eigenen Hardware dafür zu entwickeln. Die dann aber wahrscheinlich irgendein SOC sein wird, auf dem dann was ganz abgespecktes laufen muss.

Der aktuelle Stand ist dieser:

Code: Alles auswählen

import time
import math
import bisect
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(40, GPIO.OUT)

SEQUENCE = [
            (1000, True),
            (2000, False),
            (7000, True),
            (3000, False),
            (5000, True),
            (2000, False),
]


PERIOD = sum(t for t, _ in SEQUENCE) / 1000.0  # in seconds


def main():
    absolute_sequence = [0]
    for ts, _ in SEQUENCE:
        absolute_sequence.append(absolute_sequence[-1] + ts)
    del absolute_sequence[0]

    while True:
        time.sleep(.1)
        offset = int(math.fmod(time.time(), PERIOD) * 1000)
        pos = bisect.bisect_left(absolute_sequence, offset)
	if SEQUENCE[pos][1] == True:
	 	GPIO.output(40, GPIO.HIGH)
	else:
		GPIO.output(40, GPIO.LOW)
#        print(offset, pos, SEQUENCE[pos][1])

if __name__ == '__main__':
    main()

GPIO.cleanup()



Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:02
von __blackjack__
@RudiOnTheAir: Die aktuelle Stand sieht falsch aus weil da teilweise Tabulatorzeichen zum Einrücken benutzt werden. Konvention ist vier Leerzeichen pro Ebene, keine Tabs.

Man vergleicht nicht mit literalen Wahrheitswerten. Da kommt wieder ein Wahrheitswert bei heraus. Entweder der, den man sowieso schon hatte, dann hätte man auch gleich den nehmen können, oder dessen Gegenteil. Dafür gibt es ``not``.

Das ``if``/``else`` ist aber sowieso überflüssig, denn beide Zweige unterscheiden sich ja nur durch diesen Wahrheitswert den man bereits hat, und einfach nur einsetzen braucht, in die eine Zeile die da in beiden Zweigen steht.

Edit: GPIO Setup/Cleanup gehören nicht auf Modulebene sondern ins Hauptprogramm und das Aufräumen sollte man durch ein ``try``/``finally`` absichern, so dass es auch ausgeführt wird wenn das Programm durch eine Ausnahme abgebrochen wird.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:20
von RudiOnTheAir
Fraglich jetzt, ob das nur quick and dirty ist, aber der korrekten Berechnung grundsätzlich nicht im Weg steht, oder ob das hinderlich ist für die Genauigkeit. Als erstes Ergebnis ist festzustellen, das die LED sichtbar unsyncron an und aus gehen. Man muss aber schon genau hinsehen. Genaueres kann dann das Oszi sagen... Ich habe den NTP Pool n.de.pool.ntp.org eingetragen und die beiden Raspi hängen an unterschiedlichen LAN Anschlüssen.

Die Tabs kann ich ja noch rausnehmen. Wie das mit dem if/else dann aussehen muss, ist mir noch nicht klar. Wie gefragt. Macht das was an Temp oder Genaugkeit? Ich will morgen mal einen festen NTP vorgeben, damit die Dinger nicht aus dem Pool was raussuchen...

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:23
von __deets__
Die Wartezeit von 0.1 ist ja auch grob, und eine Fehlerquelle dafuer. Man kann auch kuerzer warten.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:37
von RudiOnTheAir
Das Programm muss doch die Berechnungen noch schaffen.? Oder ist das überhaupt kein Problem.?

Interessant ist, je länger ich die beiden LED im Auge behalte... Mal ist die eine minimal vorrauseilend, mal die andere. Die beiden Pi sind auch noch unterschiedlich. Einer hat kein Onboard WLAN, das ist wohl ein altes Modell. Ist vieleicht ein unfairer Vergleich...

Will mal 0.01 probieren. Hab grad gelesen, das die Genaugkeit davon letztlich vom OS abhängt....

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:40
von Sirius3
Warum rechnest Du nicht einfach aus, wie lange Du schlafen mußt?

Code: Alles auswählen

def main():
    next_time = time.time()
    next_time -= next_time % -PERIOD
    while True:
    for delay, on in SEQUENCE:
        GPIO.output(40, on)
        next_time += delay / 1000
        time.sleep(next_time - time.time())

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:46
von RudiOnTheAir
Ähm, das blicke ich jetzt nicht. Ist es nicht so, das die Timer vom genauen Takt des Rechner abhängen. Und wenn der eine Schwankung hat...? Das Ziel ist es an verschiedenen Orten einen syncronen Takt zu erzeugen. Die einzige Referenz ist NTP bzw. DCF77 / GPS...

EDIT:

Hab die SleepZeit jetzt auf 0.01

Sieht besser aus. So rein optisch.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:48
von __blackjack__
@RudiOnTheAir: Dieses Konstrukt…

Code: Alles auswählen

    if SEQUENCE[pos][1] == True:
        GPIO.output(40, GPIO.HIGH)
    else:
        GPIO.output(40, GPIO.LOW)
…ruft `output()` letztlich mit 1 als zweitem Argument auf wenn ``SEQUENCE[pos][1]`` den Wert `True` ergibt (also 1 als Zahl betrachtet) und mit 0 wenn ``SEQUENCE[pos][1]`` den Wert `False` (also 0 als Zahl betrachtet). Das heisst das ist nichts anderes als einfach nur diese eine Zeile:

Code: Alles auswählen

    GPIO.output(40, SEQUENCE[pos][1])
`time.time()` hängt natürlich von irgendeinem Timer ab, aber das sollte ”Wall clock”-Werte liefern. In Sekunden.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:50
von __deets__
@Sirius3: Da ist ein Einruekungsfehler drin. Und time.sleep darf nicht negativ sein, was es bei dir (EDIT: glaube ich..) aber wird, wenn man in der Periode nicht zufaellig richtig liegt. Aber die Grundidee ist cool, weil es auf das doch etwas schwergewichtigere bisecten verzichtet 👍

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 16:51
von __deets__
RudiOnTheAir hat geschrieben: Mittwoch 5. Februar 2020, 16:46 Ähm, das blicke ich jetzt nicht. Ist es nicht so, das die Timer vom genauen Takt des Rechner abhängen.
Ja und? In Sirius3 code wird doch die wall-clock time.time() verwandt. Genauso wie in meinem. Das ist die offizielle Zeitbasis, die via NTP (oder spaeter DCF) auch drift-kompensiert ist.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 17:02
von RudiOnTheAir
Hmm, der "Sirius3" Code ersetzt jetzt welchen Part.? Alles unterhalb von PERIOD = sum... bis vor if __name...?

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 17:28
von Sirius3
Das ganze nochmal komplett, mit allen nötigen Korrekturen:

Code: Alles auswählen

import time
from RPi import GPIO

LED_PIN = 40
SEQUENCE = [
    (1000, True),
    (2000, False),
    (7000, True),
    (3000, False),
    (5000, True),
    (2000, False),
]

PERIOD = sum(t for t, _ in SEQUENCE) / 1000.0  # in seconds

def main():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(LED_PIN , GPIO.OUT)
    try:
        next_time = time.time()
        next_time -= next_time % -PERIOD
        while True:
            for delay, on in SEQUENCE:
                GPIO.output(LED_PIN, on)
                next_time += delay / 1000.0
                time.sleep(max(0, next_time - time.time()))
    finally:
        GPIO.cleanup()
	
if __name__ == '__main__':
    main()
Da das GPIO.output hoffentlich nicht länger dauert als die Pause dazwischen, sollte time.sleep niemals negative Werte annehmen. Ich habe aber zur Sicherheit ein max eingebaut, die Schleife synchronisiert sich danach wieder von alleine, falls der NTP die Zeit mehrere Sekunden vorsetzen sollte.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 18:20
von RudiOnTheAir
Danke. Ich teste das morgen. Wird auch interessant zu sehen, wie lange das dauert wenn NTP weg ist weil kein Netzwerk. Wann das sichtbar weg driftet. Ich vermute nur wenige Stunden.
Das Puls Pausen Verhältnis ist übrigens sehr variabel. Kann also auch nur kurz on sein und dann eine lange Pause oder umgekehrt.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 18:35
von __blackjack__
@RudiOnTheAir: Wieso sollte das nach wenigen Stunden driften? NTP ist ja nur zum synchronisieren und nicht um ständig die Zeit vorzugeben. So furchtbar ungenau/schwankend sollten die Timer im Raspi nicht sein, und um einen konstanten Drift sollte sich der Kernel kümmern.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 18:47
von __deets__
Doch, ich kann mir gut vorstellen, dass der recht stark driftet. Der PI hat keine RTC, und AFAIK keinen Quartz. Wie auch immer genau er seinen Takt herstellt, wenn es zB Temperatur-Schwankungen gibt, wird das um ein paar Prozent abweichen. Eine RTC zu verbauen waere beim NTP-Szenario ein Weg das einzudaemmen. Da aber DCF77 verwandt werden soll, ist das denke ich mal eh kein Problem - das koennte zumindest permanent die System-Zeit korrigieren. Ob es das tut weiss ich aber auch nicht. Gleiches gilt auch fuer NTP, wie oft das eigentlich gestartet wird - kA.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Mittwoch 5. Februar 2020, 19:01
von RudiOnTheAir
Der NTPD läuft ja permanent. Und wie oft der schaut kann man einstellen. AFAIK ist der Max Wert für den Interval 1024 Sekunden.

Re: Taktgeber, NTP Sync, syncroner Start

Verfasst: Donnerstag 6. Februar 2020, 09:53
von RudiOnTheAir
Zur Info für technisch Interessierte an diesem Aufbau.

Die beiden LED sind für das Auge syncron. Das Oszi sieht natürlich trotzdem einen kleinen Versatz. Konkret sind das im Mittel 4,1 ms. Code von Siruis...

Siehe Bild.

Bild

Jetzt kommt der Test, wie schnell das wegläuft ohne NTP...