Go Down

Topic: Projektvorstellung: Kettenölung und Griffheizung die 2. (Read 10210 times) previous topic - next topic

TelosNox

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.

meister_q

So.

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

Code: [Select]

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.

meister_q

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. :D


TelosNox

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 (https://github.com/TelosNox/noxmatic/blob/master/Arduino/sketches/noxmatic/DistanceCalculator.h). 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).

meister_q

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.

TelosNox

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:
https://github.com/TelosNox/noxmatic/blob/2483f2dfb8fabab545b03dea85e88796f8203e4d/Arduino/sketches/noxmatic/ChainOiler.h

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.

meister_q

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.

Code: [Select]

    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:

Code: [Select]

  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?

TelosNox

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.
Code: [Select]
#define abrollumfang 0.01896
Mach das lieber nicht. Schreib lieber
Code: [Select]
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.  ;)

meister_q

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?

TelosNox

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.

Serenifly

Quote
c ist unerwarteter weise 2 und nicht 2,3333.
Nein. Es reicht wenn eine der Zahlen Float ist. Es ist egal welche. Solche Probleme hast du erst wenn du mehr als zwei Operanden hast und von links nach rechts gerechnet wird.


Das ist übrigens auch falsch:
Code: [Select]

const float abrollumfang =  1896 /1000  / 1000;

Korrekt:
Code: [Select]

const float abrollumfang =  1896.0 /1000  / 1000;

Hier wäre es z.B. falsch nur am Ende 1000.0 zu schreiben, weil 1896 / 1000 im noch als Integer berechnet werden würde

meister_q

Ganz einfach:

Ich hab die #defines weg gemacht, hab alles gegen floats ausgetauscht, und alle ersten definitionen der floats mit .0 belegt.

Somit sollten jetzt ja alle Rechnungen nur noch mit floats erfolgen.

Ebenso hab ich

const float abrollumfang =  1896.0 / 1000.0  / 1000.0;

gemacht.

TelosNox

Danke für die Korrektur. Ich hatte das Verhalten immer bei mehreren Operanden festgestellt, daher dachte ich,
dass der erste Operand schon Gleitkomma sein muss. Dann war bei mir wohl die Gleitkommazahl immer hinten.

Ich persönlich vermeide Gleitkommazahlen sowieso, sofern es möglich ist. Den Radumfang hab ich bei mir z.B. in mm gespeichert und ich rechne auch immer wenn möglich in Ganzzahlen. Als Geschwindigkeit will ich am Ende doch eh ne Ganzzahl haben. Warum also nicht auch mit Ganzzahlen rechnen? Man muss nur drauf achten, dass man zuerst die Multiplikationen macht und hinterher erst 1x dividiert (Dividend vorher auch ausmultiplizieren).

Ob das von der Performance her besser ist, als mit Gleitkomma weiß ich nicht, aber die Genauigkeit ist auf jeden Fall höher. Man muss halt drauf achten, dass man mit long arbeitet, sonst kommt es zu überläufen.

Serenifly

Alles float zu machen geht natürlich, aber es hilft bei sowas wirklich zu verstehen was abläuft und wie Datentypen miteinander interagieren.

meister_q

Aber da ja eh sogut wie nichts anderes auf dem Arduino läuft, ist es ja performancetechnisch egal ob alles float ist.

Der Mega den ich gerade benutze, ist mit den paar Funktionen total unterfordert.

Ich teste das ganze morgen (oder demnächst, hab am Wochenende keine zeit)... oder mit viel lust und laune heute abend noch. Dann berichte ich weiter!

Go Up