Schonmal danke für die Hinweise, das hilft ein wenig weiter.
pulseIn zählt die Dauer eines Zustands. Das Hilft mir nicht, da hier gemessen würde, wie lange bei einem Tick das Signal HIGH ist. Ich will aber nicht wissen wie lange es HIGH ist, sondern wie lange es dauert, bis es von HIGH wieder auf HIGH schaltet.
Bei der zweiten Variante müsste ich testen, ob hier der Programmablauf unterbrochen wird. Das kann ich nämlich nicht brauchen, weil ja auch noch andere Sachen laufen.
Egal wie, ich muss die Ticks auf jeden Fall alle zählen, weil ich auch die gefahrene Strecke brauche.
Ich will mal kurz auf volatile und noInterrupt zurück kommen:
Ich hole mir zuerst die aktuellen millis. Danach erst die Anzahl an Ticks. Wenn die Ticks zwischenzeitlich erhöht wurden, dann müsste mir eine höhere Geschwindigkeit errechnet werden, weil ich dann zuviele Ticks in meinem Intervall habe. Genau das passiert aber nicht.
Nach der Zuweisung setze ich die Ticks auf 0 zurück. Wenn hier zwischenzeitlich Ticks erhöht wurden, dann gehen die verloren. Das müsste dann doch aber auch bei deutlich höherer Geschwindigkeit auch so sein. Oder spielt mir da vielleicht die Physik einen Streich und der Schlupf wird so groß, dass das Rad tatsächlich eine deutlich höhere Geschwindigkeit hat? Eigentlich dachte ich, dass das nur beim Beschleunigen oder bei richtig hoher Geschwindigkeit signifikant wird.
Wenn ich jetzt mit nointerrupts arbeite, dann gehen mir doch sicherlich Ticks verloren oder nicht? Das würde ich gerne vermeiden.
Die Idee einfach die Zeit zwischen den Ticks zu zählen ist auch so ne Sache. Schließlich haben wir ja bereits bei 100km/h eine Frequenz von 1000Hz. Bisher berechne ich die Geschwindigkeit alle 100ms also mit 10Hz. Ich frage mich, ob mein Programm dann noch ordentlich läuft oder ob da dann nicht doch der IC irgendwann an seine Grenzen stößt. Aber wahrscheinlich unterschätze ich da den 16Mhz Chip.
Davon unabhängig kann ich dann aber nicht mehr mit millis arbeiten, sondern muss mikros nehmen.
Wäre folgendes eine Lösung (achtet nicht auf die syntax, ich kritzel das nur so hin)?
unsigned long speedMicros
unsigned long speedTicks
speedTrigger() #wird per interrupt gerufen
{
static unsigned long lastMicros
unsigned long actualMicros = micros()
unsigned int diff = actualMicros - lastMicros
lastMicros = actualMicros
speecMicros += lastMicros
speedTicks++
}
calculateSpeed()
{
unsigned long mySpeedMicros = speedMicros
unsigned long mySpeedTicks = speedTicks
speedMicros -= mySpeecMicros
speedTicks -= mySpeedTicks
... geschwindigkeit berechnen und kram machen
}
So sorgt der Interrupt selbst dafür, dass die Anzahl Ticks und die gemessene Zeit zusammen passen. Dennoch kann ich kontrolliert in einem definierten Intervall die Geschwindigkeit bestimmen und meinen restlichen Kram damit machen, ohne den Interrupt damit zu belasten.
Ticks verlieren kann ich nicht. Falls der Interrupt weiter gezählt hat, bleibt das erhalten, da ich nur den alten Wert abziehe.
Nachdem ich diesen Code eben so geschrieben habe fällt mir auf, dass ich auch den bestehenden Code dementsprechend anpassen könnte (statt speedTicks = 0 müsste ich ticks davon abziehen).
Zusammen mit volatile könnte das vielleicht schon die Lösung sein und ich muss den Interrupt nicht aufblähen.