Projektvorstellung: Kettenölung und Griffheizung die 2.

Ich bin mittlerweile fertig mit Version 3.0.

  • Kettenölung wie gewohnt mit Tachosignal, Geschwindigkeitsanzeige und Zielgeschwindigkeit
  • Automatische Heizgriffsteuerung jetzt mit getrennt ansteuerbaren Griffen. Somit Ausgleich von Griffunterschieden möglich (Gashülse)
  • Windchill wieder integriert: Die Griffe regeln unter 50km/h die Leistung um max. 50% runter (linear nach Geschwindigkeit)
  • Konfiguration komplett über Wlan mit integriertem Webserver. Hotspot am Handy aktivieren, einschalten, Display zeigt die IP und dann einfach im Browser öffnen. Keine extra App nötig
  • OTA Update möglich. Somit ist nur initial eine USB Verbindung nötig, danach kann jederzeit im eingebauten Zustand die Software aktualisiert werden

Das ganze Projekt ist OpenSource. Aktuell ist nur Sourcecode und Schaltplan online. Ich will noch ein Wiki schreiben, damit man weiß, was zu tun ist und wie man anschließen muss.

Wie ist es bei dir bezüglich des Tachosignals?

Nutzt du geschirmte Leitungen um das Signal vom Geschwindigkeitssensor des Motorrads abzugreifen, oder nutzt du einen eigenen Hallsensor (ebenfalls geschirmt) ?

Ich steh gerade vor dem Problem, dass ich sobald ich den Motor starte, nur noch störungen bekomme, heisst:

Die Impulse zählen unendlich hoch, aber nur wenn der Motor läuft.

Habe schon in dem Thread:

https://forum.arduino.cc/index.php?topic=388859.15

gelesen, und die Hardware wie da aufgebaut (wie beim rehoiler), aber das war nutzlos.

Ich greife zur Zeit das Tachosignal vorne am Kombiinstrument mittels Nadel und Krokodilklemmen ab, die freischwebend zu meinem Arduino (der vor dem Motorrad auf dem Boden liegt) gehen, und von da auf den Interrupt gehen. In Reihe zur Impulsleitung ist eine Diode verbaut, paralell zu GND dahinter ein 1nF Keramikondensator.

Einen Tiefpass mit 1,5kOhm und 10nF habe ich ebenfalls schon getestet, kam kein erfolg.

Zum schluss bleibt mir nur noch die Lösung mittels geschirmter Leitung (Ist schon bestellt), oder aufgabe.

Hoffentlich liest der Threadersteller hier noch weiter :slight_smile:

Meine Leitung ist ein einfacher Leitungsdraht ohne Schirmung oder sonst was. Das hat bereits in 3 unterschiedlichen Motorrädern funktioniert. Ich glaube nicht, dass es bei dir an der Leitung liegt.

Der Tachosensor funktioniert ja so, dass der Pin selbst HIGH ist und auf Massedurchgang reagiert. Eine induktive Störung bringt das Signal nicht auf Masse, daher sollte das kein Problem sein.

Wenn du eine eigene Software hast, dann check mal, auf was dein Pin reagiert. Auf HIGH zu horchen wäre falsch.

Ich nutze keinen eigenen Hallsensor, sondern das Tachosignal, das die ECU generiert.

Bei dir vermute ich, dass entweder der Pin falsch programmiert ist, oder dass deine aktuelle Verbindung durch Vibration einfach wackelt. Falls das Tachosignal aktuell auf Masse ist und dann die Verbindung wackelt, dann bekommst du deinen beschriebenen Effekt.

Ok, im Mccoiforum wurde mir gesagt, dass die Hondas extrem EMV belastet sind, hast du deins an einer Honda getestet?

Mein Tachosignal wechselt, je nach Radposition von High auf Low auf High usw. Es kann z.b. auch permanent High oder Low sein, je nach radstellung.

Mein Interrupt erkennt Falling. Ich habe ja ebenfalls das Tachosignal abgegriffen was vom ECU kommt und vorne ans Instrument geht. Ich glaube nicht, dass das Vibrationen sind, da ich alles mit Krokodilklemmen befestigt habe, und selbst wenn ich an den Leitungen wackle wenn der Motor aus ist, zählt es nicht hoch. Nur wenn der Motor läuft.

Ich hab das Signal schon mit einem Stromdieb, sowie an anderer stelle mit einer Nadel und Krokodilklemme abgegriffen. Der Effekt bleibt weiterhin bestehen.

Kannst du deinen Codeschnipsel, der das Tachosignal via Interrupt erkennt, hier rein posten?

Hatte den Öler damals in der CBF600 und aktuell in einer MT09 und in einer CB1300. Ist also 2x Honda dabei :wink:

#define PIN_SPEED_SIGNAL D6

void setup() {
  attachInterrupt(digitalPinToInterrupt(PIN_SPEED_SIGNAL), speedSignalTrigger, FALLING);
}

void speedSignalTrigger() {
  distanceCalculator.processTick();
}

Sollte bei dir inhaltlich auch nicht anders aussehen (Achtung mein Code ist für den ESP8266, deine Syntax ist anders).

Was zeigt denn das Multimeter an, wenn du an deinem Tachosignal misst? Mit Motor aus müsste es ja dann sauber zwischen 0 und 5V toggeln (ich glaube Honda hatte da 5V). Stell das Motorrad dann mal so hin, dass die 5V anliegen und mach dann den Motor an. Wenn du dann immer noch diesen Effekt hast, dann kommt es nicht vom Wackeln deiner Leitung (wäre ja dann keine Masse zum hinwackeln vorhanden).
Man kann auch mal das Rad so drehen, dass das Tachosignal LOW ist und das Multimeter dran halten. Da sollte dann auch 0V stehen. Motor an und schauen, was er dann misst. Wenn da was zappelt, sollte das Multi vielleicht zucken.

Check auf jeden Fall mal, ob du auch den richtigen Pin als Trigger zugewiesen hast. Wenn da nämlich nix angeschlossen ist und die Versorgungsspannung schwankt (tut sie ja, sobald die LiMa läuft), dann könnte das vielleicht auch dazu führen, dass der Interrupt kommt.

Danke für den Codeschnipsel.

Ich habe auch eine CBF600. Die PC43 (Die ab BJ 2008).

kannst du mir noch die Funktion in der Interruptfunktion zeigen?

Aber ja, bei mir sieht es mit dem Interrupt genau so aus. Ebenfalls nutze ich Falling.

Schließe ich das Multimeter von der Tacholeitung zu Masse an, drehe das Rad bei Motor aus und Zündung an, Wechselt das Multimeter zwischen 0V und 5V.

Den Tipp mit dem Hinstellen werde ich mal testen.

Ich nutze ja anstatt digitalPinToInterrupt(PIN_SPEED_SIGNAL), setze ich direkt "1" ein (glaube ich jedenfalls) Interrupt 1, an digitalpin 3. (sorry, bin die letzten Tage nur am Laptop, Code ist am PC zuhause wo ich nicht war).

Ist der Motor aus, und Zündung an und wenn ich eine LED zwischen dem Tachosignal und Masse schalte, und das Rad drehe, Leuchtet die LED, geht aus, leuchtet, etc... Also ein klares 5V Signal.

Starte ich den Motor mit LED oder Multimeter angeschlossen. Bleibt die LED in dem jeweiligen zustand und ändert diesen nur, wenn ich am Rad drehe. Also ein eindeutiges Tachosignal. Wenn der Arduino wieder dran hängt, dreht der Impulszähler wieder hoch. Merkwürdig. Meinen Interruptpin hab ich intern auf High gezogen. Also INPUT_PULLUP bei der Pindefinition. Wo ich am Interrupt noch "HIGH" erfasst habe, hatte ich den Pin3 mit 100kOhm auf Masse gezogen. Problem war weiterhin da.

Ebenfalls habe ich eine Diode auf den Arduino zeigend von der Impulsleitung zwischen geschaltet, und einen Tiefpassfilter hatte ich mit 1,5kOhm und 10nF geschaltet. Ebenfalls erfolglos.

Blieb für mich logisch nur noch EMV übrig.

Ich werde als nächstes den Arduino tauschen, nicht dass dieser schon irgendwelche ESD Schäden hat, ebenfalls verwernde ich auch mal einen anderen Interrupt Pin.

Die Funktionen der Schaltung hab ich ja schon alle getestet, indem ich die Leitungen mal abgezogen hab um die Funktion zu testen etc..

Bin da momentan ziemlich ratlos.

Mein Code ist auf GitHub komplett öffentlich zu finden (Link ist im ersten Post). Da findest du dann auch die Methode, die im Interrupt ausgeführt wird. Aber im Endeffekt wird nur hochgezählt und der merkt sich noch die Millis, wann das passiert ist.

Den Pin auf Masse ziehen bringt nix. Im Gegenteil, du willst ja LOW messen und nicht HIGH.

Funktioniert denn dein Interrupt, wenn du den Tachosignalanschluss einfach händisch erdest. Also Kabel dran und dann an Masse halten und wieder weg (ganz ohne Motorrad). So solltest du Interrupts bekommen.
Du kannst dir zum testen auch ein Tachosignal generieren. Einfach einen freien Output Pin auf PWM schalten und als Tachosignal anschließen.

Wie ist deine Diode drin? Ist die Kathode (der schwarze Ring) am Pin oder ist die Kathode auf Seite des Tachosignals?

Wie gesagt, EMV kann eigentlich nicht sein, wenn alles korrekt verdrahtet ist. Der PIN sieht nur Masse. Sämtliche positiven Spannungen sind durch die Diode abgeblockt. Wenn dann könnte höchstens eine negative induzierte Spannung da was ausrichten aber auch daran glaube ich nicht.

Ok danke. Jo, daher sagte ich ja, ich habe dann den pinMode auf INPUT_PULLUP gestellt, und erfasse ja FALLING.

Komplett ohne Motorrad wenn ich den Interrupt auf Masse bzw GND lege, zählt er einen, bzw mit bounce hoch.

Ist bouncing durch vibrationen vielleicht mein problem? Eigentlich sollte das Signal vom Motorrad doch ohne bouncer kommen?

void radimpulseZaehlen()
{
    detachInterrupt(1);                               // Deaktiviert Interrupt an Interruptpin 1 (Digitalpin 3)
    zeit = millis();                                  // Nimmt die Zeit in "zeit" auf
    rpm = 30 * 1000 / (zeit - timeold) * rpmcount;    // Errechnet aus der Zeit und Impulse pro Zeit die rpm
    timeold = millis();                               // Nimmt die Zeit in "timeold" auf
    rpmcount = 0;                                     // Setzt rpmcount auf 0
    
    attachInterrupt(1, rpm_fun, interruptType);                // Aktiviert Interrupt an Interruptpin 1 (Digitalpin 3) mit HIGH Flanke

    Serial.print("RPM: ");
    Serial.println(rpm);

    v = rpm / radumdrehungsimpulse;     // Rechnet Umdrehungen pro Minute durch Impulse pro Radumdrehung
    v = v * abrollumfang;               // Multipliziert mit Abrollumfang
    v = v * 60;                         // Multipliziert mit 60 zu km/h
    
    Serial.print("V: ");
    Serial.print(v);
    Serial.println("km/h");
}

Mein Code zum Impulse erfassen.

Dazu noch die defines

#define abrollumfang 0.01896              // Radumfang 189.6cm -> In km angegeben
#define radumdrehungsimpulse 72           // Pulse pro Radumdrehung
#define interruptType FALLING

Im setup hab ich

  attachInterrupt(1, rpm_fun, interruptType); // Aktiviert Interrupt an Interruptpin 1 (Digitalpin 3) mit HIGH Flanke, führt Funktion "rpm_fun" aus

Der rest ohne die defines jetzt

void setup()
{
  Serial.begin(9600);   // Seriellen Monitor öffnen (Baudrate 9600)

  lcd.begin();          // LCD Starten
  lcd.backlight();      // LCD backlight aktivieren
  lcd.clear();          // LCD Säubern

  pinMode(3, INPUT_PULLUP);

  attachInterrupt(1, rpm_fun, interruptType); // Aktiviert Interrupt an Interruptpin 1 (Digitalpin 3) mit HIGH Flanke, führt Funktion "rpm_fun" aus
}

void loop()
{
  unsigned long currentMillis2 = millis();
  if (currentMillis2 - previousMillis2 >= interval2)
  {
    previousMillis2 = currentMillis2;
    radimpulseZaehlen();              // Funktion rpm berechnen
  }
  oeltemp();                          // Funktion Öltemperatur lesen
  kilometer();                        // Funktion Strecke messen
  lcdprint1();                        // Funktion LCD Ausgabe
}

void rpm_fun()                        // Funktion Interrupt
{
  rpmcount++;                         // Zählt Variable rpmcount um 1 hoch
  radimpulse++;                       // Zählt Variable radimpulse um 1 hoch
}

Mit bounce meinst du sicherlich prellen. Nein ein Hallsensor prellt nicht und auch die Leitung dürfte nicht prellen.

Deine Diode müsste dann wohl auch richtig drin sein, sonst würde er bei GND nicht hochzählen.

Was passiert, wenn du den Arduino am Motorrad hast (Spannungsversorgung) und den Tachoanschluss vom Arduino fest auf Masse bzw. 5V legst und dann den Motor anmachst? Wenn er dann auch Impulse zählt, dann kommt das Problem von der Spannungsversorgung. Wenn dann nix passiert, dann kommt es irgendwie vom Tachosignal.

Um nochmal die Schaltung zu klären: Du hast direkt am Pin den 1nF gegen Masse und dahinter dann die Bat42 mit Kathode in Richtung Motorrad, richtig? Der Pin ist auf HIGH (mit Multimeter messen), wenn nichts angeschlossen ist.

Ich komme vom Tachosignal über die Diode mit Kathode zum Motorrad zeigend auf mein Breadboard, nach der Kathode, also an der Anode gehe ich auf den 1nF Kondensator der auf GND geht, und ebenfalls von der Anode der Diode gehe ich auf digitalPin 3 (Interrupt 1) vom Arduino Mega. Dieser Pin ist mit

  pinMode(3, INPUT_PULLUP);

auf HIGH gezogen, da ich ja FALLING prüfe.

Ich habe meinen Arduino via Powerbank über USB versorgt, nicht über das Motorrad, den GND vom Arduino und die Masse vom Motorrad hab ich zusammengeschaltet.

Klingt korrekt und sollte so funktionieren.
Ob da irgendwelche Störstrahlung ist, solltest du testen können: Kabel so wie bisher führen, aber nicht am Tachosignal, sondern an dort verfügbarer Masse anschließen.
Wenns dann nicht mehr zappelt: Kein Stahlungsproblem.

Wenns dann immer noch zappelt: Kabel nicht mehr am Motor lang legen, sondern direkt an Masse an der Batterie (weit weg von Störquellen). Wenns dann immer noch zappelt: Kein Stahlungsproblem, dann ist da irgendwas anderes faul. Wenns nicht mehr zappelt, dann könnte es Stahlung sein.

So.

Ich habe nun den Aufbau auf einen Arduino Mega geändert, dann hab ich jetzt

digitalPinToInterrupt(3)

anstelle von "1" verwendet.

habe zusätzlich eine weitere Diode für die Masseleitung verwendet, habe die Leitungen woanders hingelegt, da es sich ja noch um Krokoklemmen handelt. (Vom Tacho vorne, über den Tank, zum Handschuhfach hinten). Masse vom Motorrad zu GND Arduino ist lediglich eine 15cm Krokoklemmenleitung.

Gab keine veränderung.

Dann hab ich wie von dir geschrieben anstatt das Tachosignal zu benutzen, bin ich auf Masse (in dem Fall jetzt hab ich einfach die Krokoklemme auf den ABS-Ring an der Felge geklemmt. Oder glaubst du, die Masse vom Kombiinstrument ist anders? Ne oder? Masse am KFZ ist doch gleich Masse!

Dann hab ich den Motor gestartet, wie gehabt, er zählt Impulse hoch.

Defintiv EMV Problem?

Nächster Schritt: Ich hab eine Geschirmte 3x0.75mm² Leitung hier liegen. Werde ich gleich verdrahten, und den Schirm auf Masse vom Motorrad legen, und erneut testen.

Update:

Mit geschirmter Leitung ebenfalls das Problem (Vielleicht weil Arduino und Krokoklemmen nicht geschirmt?).

Zapfe ich das Signal garnicht ab, und gehe direkt vom Minus der Batterie auf den Interruptpin, starte das Motorrad, dann zählt er dennoch Impulse.

Also EMV auch an der Batterie stark genug. Wie sollte es sonst Impulse zählen?

Das einzige was ich noch nicht getestet habe, ist den Arduino in ein Metallgehäuse inklusive aller Kabel zu legen, damit komplett alles geschirmt ist.

Bin echt ratlos. Das kann doch nicht sein.

Was für eine CBF600 hast du damals getestet? PC38 oder PC43?

Weiteres Update:

Eben nochmal alles Verkabelt, ein LCD dran gepackt, Stromversorgung des Arduinos via DCDC Wandler von der Motorrad Batterie.

Nach dem Starten, siehe da, es funktioniert!

Die LCD-Anzeige funktioniert zwar nicht richtig, aber die Geschwindigkeitsanzeige auf dem LCD verändert sich auch je nach Drehzahl des Hinterrades.

Muss die Tachoimpulse anpassen, da es mir bei Tacho ca. 10kmh nur 6,5kmh angezeigt hat (Tachotoleranz?).

Soweit muss es jetzt gehen.

Hoffentlich kommt noch ne antwort. :smiley:

Ich hatte eine PC43.

Interessant, dass es funktioniert, wenn du direkt an der Batterie hängst. Scheinbar funktioniert das mit der gemeinsamen Masse dann doch nicht so ganz sauber.
Freut mich jedenfalls, dass es endlich wieder vorwärts geht (sowas frustet total, wenn man so komische Fehler hat, ich kenne das leider selbst auch zu genüge).

Der Tacho eilt ja sowieso vor. Du musst bei einer höheren Geschwindigkeit schauen. Bei der MT09 hab ich 100 auf dem Display, wenn ich 107 auf dem Tacho habe. Das Display geht aber genau, das bestätigt mir das GPS.
Wenn ich das noch richtig im Kopf hab, dann sind 72 Ticks bei der CBF600 korrekt. Die CB1300 hat 60 Ticks und die MT09 hat 40.

Du kannst natürlich noch Rundungsfehler oder Fehler durch Zeitverschleppung haben. Das ist der Grund, warum ich mir die Millis der Radticks merke. Somit muss ich zur Geschwindigkeitsberechnung nicht ein festes Intervall zum rechnen nehmen, sondern rechne einfach mit den Millis der Radticks als Zeitintervall. Seit ich das so mache, zappelt die Anzeige nicht mehr, wenn man konstante Geschwindigkeit fährt.

Sowieso würde ich nicht den Tacho als Referenz nehmen. Schnapp dir ein Navi und vergleiche damit.

Btw: wenn du magst darfst du einfach Code bei mir klauen. Schau dir einfach meinen DistanceCalculator an (noxmatic/DistanceCalculator.h at master · TelosNox/noxmatic · GitHub). Der berechnet Geschwindigkeit und gefahrene Strecke. Das eigentliche Kettenölungsmodul funktioniert dann direkt mit gefahrenen Streckenintervallen und ist unabhängig davon, wie die Strecke zustande kommt (so kann man z.B. recht einfach von Tachosignal auf GPS wechseln).

Ja, scheinbar.

72 Impulse hab ich ja auch eingestellt, dann passt das sicherlich schon, weil 6,5kmh auf Display zu 10kmh auf Tacho passt ganz gut. Die CBF hat ne enorme abweichung finde ich. Wenn ich 100 fahre, sind es laut Navi/GPS nur ca 95kmh, bei 200 nur 190.

In meiner Funktion, die die Geschwindigkeit ermittelt, werden auch die Intervalle zwischen den Impulsen gemessen. So hat es bisher per Hand auf dem Hauptständer ganz gut funktioniert.

Den Distance Calculator hab ich mir schon angeschaut. Ich rechne die Entfernung aber über die Impulse, da 72 Impulse bei mir ja 0.01896km sind, je mehr Ticks, desto mehr gefahrene km. Inwieweit sich das auswirkt, wenn die long Variable wieder auf 0 Springt, keine ahnung. Muss ich einfach mal testen.

Wenn du die Ölerdistanz über die Ticks machen willst, dann ist es am einfachsten, wenn du dir ausrechnest wieviele Ticks für die gewünschte Distanz nötig sind und ziehst dann einfach nur noch die Ticks ab (direkt im Interrupt), bis du bei 0 bist. Dann ölen und die benötigten Ticks wieder auf den errechneten Wert setzen.
Hier ist meine alte Variante vor der Umstellung auf Distanz:

So hab ich das früher gemacht, aber dann ist man halt an das Ticksystem gebunden (ist in deinem Fall wahrscheinlich wurscht). Ich wollte meine Software halt so schreiben, dass sie modular ist und man das dann einfach erweitern bzw. anpassen kann. Schön wäre, wenn nicht jeder das Rad neu erfindet, sondern ein OpenSource Projekt der Community ensteht, das gemeinsam verbessert und erweitert wird.

Ich verstehe aber auch, dass man Bock hat, es selbst mal zu machen und eigene Ansätze zu probieren.

Am wichtigsten ist, dass man Spaß an der Sache hat.

Genau, das hatte ich vor.

Nun, du hast allerdings recht, vielleicht überlege ich es mir noch. Mal sehen, wichtig ist mir erstmal, dass es funktioniert.

Hab es eben nochmal getestet, bei 10kmh Tacho, hat er mir 62kmh auf dem LCD gezeigt, schien so, als ob zu viele Impulse eingestellt waren.

Vielleicht stimmt bei meiner Geschwindigkeitskalkulation ja was auch nicht.

    zeit = millis();                                  // Nimmt die Zeit in "zeit" auf
    rpm = 30 * 1000 / (zeit - timeold) * rpmcount;    // Errechnet aus der Zeit und Impulse pro Zeit die rpm
    timeold = millis();                               // Nimmt die Zeit in "timeold" auf
    rpmcount = 0;

So rechne ich die Impulse in eine Drehzahl um. "rpmcount" wird via Interrupt hochgezählt.

Am ende resultiert daraus eine Geschwindigkeit. Die errechne ich folgendermaßen:

  v = rpm / radumdrehungsimpulse;     // Rechnet Umdrehungen pro Minute durch Impulse pro Radumdrehung
  v = v * abrollumfang;               // Multipliziert mit Abrollumfang
  v = v * 60;                         // Multipliziert mit 60 zu km/h

Radumdrehungsimpulse sind in dem Fall 72.

Also ich Teile die Drehzahl des Sensors/Rades durch die Impulse die das Rad pro Umdrehung macht, dann multipliziere ich sie mit dem abrollumfang (in km), und rechne dann mit * 60 zu Kilometer pro Stunde um.

Logisch überlegt ist das die Richtige lösung.

Vertue ich mich irgendwo beim "rpm" errechnen?

Warum 30 * 1000?

Deine berechneten rpm sind gar nicht die rpm. Das sind die TpM (Ticks pro Minute). Für RpM müsstest du noch durch die Impulszahl pro Umdrehung teilen.

Mit zeit - timeold hast du das delta in millisekunden.
Wenn du jetzt die gezählten ticks durch diese Zeit teilst, dann hast du die Ticks pro Millisekunde.

  • 1000, dann hast du Ticks pro Sekunde und * 60 wären dann TpM.

Um also wirklich RPM auszurechnen brauchst du:
rpm = rpmcount / (zeit-timeold) * 1000 * 60 / radumdrehungsimpulse;

Geschwindigkeit ist dann RpM * abrollumfang * 60

Einen Haken hat deine Geschichte aber: zeit ist nicht der Zeitpunkt des Ticks, sondern der Zeitpunkt der Berechnung. Das kann deutlich später sein, als der letzte berücksichtigte Tick.

Zweiter Haken: Du rechnest hier mit Ganzzahlen. 30*1000/zeitdelta wird automatisch zur Ganzzahl. Alles hinterm Komma fliegt weg.
Du musst vorher casten.

Faktor 2 als Fehler wäre plausibel (du hast da 30 statt 60 stehen). Allerdings müsste deine angezeigte Geschwindigkeit dann zu niedrig sein. Sie ist aber um Faktor 6 zu hoch.

Deinen Abrollumfang hast du also Kommazahl angegeben.

#define abrollumfang 0.01896

Mach das lieber nicht. Schreib lieber

const float abrollumfang =  1896 /1000  / 1000;

Denn dann passiert es dir nicht, dass du das Komma verschiebst.
0.01896 = 18,96 Meter !!!!
Und jetzt erklärt sich Faktor 6. Das Komma macht Faktor 10 und die 30 machen daraus Faktor 5. Mit Rundungsfehlern und Abweichungen kommen wir dann bei der festgestellten 6 raus. :wink:

Ayay... ein fetter Logikfehler...

Hab den Code mal abgeändert. Testen geht nicht, es fing gerade an zu Regnen, und ich war eben 3 Stunden fahren bei 35°C...

So und die Streckenmessung ist ja radimpulse * abrollumfang / radumdrehungsimpulse, oder?

Also gesammtimpulse * ((1896 / 1000) / 1000) / 72.

Zum ersten Haken: Wie soll ich das Lösen?

Zum zweiten Haken: Also alle Variablen in floats umwandeln, dann müsste es ja genauer sein.

Wieso aber das Zeitproblem? Ich messe doch die Zeit zwischen den Ticks, also je kürzer die Zeit dazwischen, desto schneller wird es doch?

gesamtimpulse / 72 = radumdrehungen.

Strecke = radumdrehungen * radumfang.

Deine Formel müsste also stimmen und die Klammern kannst du weglassen.
Ich würde den Radumfang allerdings beim Start 1x berechnen und dann aus der Variablen wiederverwenden. Jedes mal neu rechnen ist unnötig.

Haken 1:
Dein Tick kommt dann rein, wenn der Interrupt feuert. Deine Streckenberechnung findet aber im Loop statt.

Stell dir vor dein Tick kommt bei 124ms. Der Loop rechnet aktuell noch irgendwas anderes und kommt dann bei 186ms dazu, die Geschwindigkeit zu berechnen. Dann nimmst du 186ms als Zeit und nicht die 124ms, als der Tick tatsächlich kam.

Wenn dann musst du im Interrupt den Zeitpunkt des Ticks speichern (so mache ich das auch).

Haken 2:
Der Wert, auf dessen Basis gerechnet wird, muss ein Float sein.

Beispiel:
int a = 7;
float b = 3;
float c = a / b;

c ist unerwarteter weise 2 und nicht 2,3333.
Das kommt daher, dass a eine Ganzzahl ist und somit bei jeder Operation, die auf a ausgeführt wird wieder eine Ganzzahl rauskommt.
Ändern wird das:

float a = 7;
int b = 3;
float c = a / b;

jetzt kommt für c wie erwartet 2,3333 raus. Weil a jetzt ein float ist und somit das rechenergebnis automatisch auch ein float sein wird.

Es wird immer von links nach rechts und nach den Rechengesetzten gerechnet. Und das dann Schritt für Schritt. Das Zwischenergebnis ist dann von dem Typ, den der erste Operand hatte.

Caste deine gesammtimpulse nach float und lass die Klammer weg. Das sollte schon genügen.