Projekt Motorradkettenöler - laufender Motor löst Interrupt aus

Hallo! Mein aktuelles Projekt ist ein automatisches Kettenölsystem für mein Motorrad, doch ich bin gestern beim Einbau auf ein Problem gestoßen, bei dem ich nicht weiter weiß. Aber der Reihe nach:

Funktionsweise: Ein Magnet am Hinterrad schließt pro Umdrehung einmal einen Reedkontakt. Das Schließen des Kontaktes wird von einem Arduino Nano per Interrupt registriert, die Schaltung ist identisch zu der im Beispiel DigitalReadSerial (5V vor dem Schalter, Pin mit 10kOhm mit GND verbunden). Anhand des Umfangs des Rades und der Anzahl der registrierten Pulse wird die gefahrene Strecke berechnet und dann in einem eingestellten Intervall ein Tropfen Öl auf das Kettenrad gepumpt. Die Spannung kommt direkt von der Batterie (natürlich abgesichert), und die ganze Sache wird mit einem Relais am Rücklicht (=zusammen mit der Zündung) angeschaltet.

Soweit die Theorie. Bei nicht laufendem Motor funktioniert alles tadellos.

Nun das Problem: Bei laufendem Motor wird vom Interrupt jede Umdrehung des Motors registriert (im Leerlauf ca. 1500 1/min). Ich dachte zuerst, das (ungeschirmte) Kabel vom Reedkontakt zum Arduino würde, da es an einer Stelle neben den Zündkabeln verläuft, von diesen beeinflusst. Versorge ich den Arduino allerdings nur per USB mit Strom (statt von der Batterie), tritt das Problem nicht auf.

Meine zweite Idee: die Ladespannung der Batterie ist vielleicht nur B2-gleichgerichtet, somit entsteht pro Umdrehung eine Spannungsspitze, die evtl den Arduino beeinflusst. Leider hab ich gerade kein Oszilloskop zur Hand, sonst hätte ich mir das auch mal genauer anschauen können. Würde ein korrekt dimensionierter RC-Tiefpass hier vielleicht helfen?

Hier der auf das wesentliche gekürzte Code dazu:

Spielereien wie die Ausgabe der Daten per Bluetooth und die Speicherung der gefahrenen Kilometer hab ich hier der Übersichtlichkeit halber weggelassen.

int tachopin = 2;
int pumppin = 5;

int umfang = 200;       // Radumfang in cm
int oelabst = 5;           // Abstand zwischen Ölvorgängen in km
int pumpzeit = 45;


volatile int pulszaehler = 0;
volatile unsigned long last_micros = 0;



void pumpen ()
{                                                                 
    digitalWrite(pumppin, HIGH);                      
    delay(pumpzeit); 
    digitalWrite(pumppin, LOW);                       
}


void puls()
{
  
  if( (micros()-last_micros) >= 33)
  {
    pulszaehler++;         
    Serial.println(pulszaehler);
    last_micros = micros();
  }

}



void setup() 
{
  pinMode(pumppin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(tachopin), puls, RISING);
  Serial.begin(9600);
}


void loop()
{ 

  if ( pulszaehler >=  ((oelabst*100000)/umfang) )
  {
    pumpen();
    pulszaehler = 0;    
  }

}

Ich hoffe auf ein paar Ideen oder im besten Fall auf fundiertes Wissen, was mir hilft mein Problem zu lösen ;)

Gruß David

Arduino nicht an der Batteriespannung direkt betreiben! Das Netz ist unsauber.

http://www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.23

Das Thema interessiert mich brennend, da ich bals ein ähnliches Problem haben könnte- ich möchte für mein Motorrad einen Lima- Regler mit einem Arduino bauen und überlege auch schon die Betriebspannung via RC- Glied und Z- Diode zu glätten… in der Hoffnung es reicht

aaaaah! jetzt mir wird schon einiges klar, vielen dank für den Link!

Ich lese mich mal rein und berichte dann wenn ich was passendes gebastelt hab hier.

Ja, der Link ist verdammt gut- bin auch schon die ganze Zeit am lesen... :)

Hallo,

nimm einen ordentlichen KFZ Zigarettenstecker USB Adapter. Bsp von hama und deine Spannungprobleme sind gelöst. Kannste ja zerlegen.

Nur mit dem Reedkontakt habe ich Mitleid. Du meinst sicherlich die Dinger im Glaskörper? Die werden das nicht lange mitmachen. Erstens durch die Erschütterungen beim fahren und die ständigen Betätigungen. Nimm einen Hallsensor an dem der Magnet vorbeirauscht. Kontaktlos ohne Mechanik. Hält ewig.

Die werden das nicht lange mitmachen.

Gegenindiz: Alle Yamaha (XJ) Tachos, welche seit 1982 bis fast 2000 produziert wurden haben ein solches Ding eingebaut. Ok, in DE Land ist die automatische Blinkerrückstellung verboten, aber die Glasdinger tuns trotzdem noch. Seit weit über 30 Jahren und in tausender Stückzahlen.

(wobei ich natürlich nichts gegen ein anderes Sensorprinzip habe...)

@Doc_Arduino Super Idee! Hab gerade auch schon so ein Teil in einer Kabelkiste gefunden! Ich mach mich sofort ans basteln :)

Der Kontakt ist sehr einfach zugänglich, sollte er irgendwann kaputtgehen ist er schnell ersetzt.

Der KFZ12V - USB Adapter hat leider keine Besserung gebracht. Es war der Elektronik nach zu urteilen auch kein ganz billiger...

Ich besorge mir jetzt ein Oszi und schaue das alles mal genauer an.

Grenze doch mal das Problem ein indem du einen einfachen Arduino mit ganz einfachem Sketch, wie einer blinkenden LED oder ähnlichem laufen läßt, und schaue mal ob der Arduino generell mit der Umgebung zurecht kommt.

Vielleicht gibt es ja doch etwas an deiner Verdrahtung oder im Sketch was das ganze stört...

Du könntest meiner Meinung nach die Spannung etwas säubern indem du in der Stromversorgung eine Diode und einen Widerstand von 10- 20 Ohm einbaust, dann einen Spannungsregler mit einem ausreichenden Kondensator davor und danach. Das ganze idealerweise direkt an die Batterie, da diese ja auch ein paar Spitzen dämpft... Damit solltest du eine recht saubere Stromversorgung bekommen.

Moin zusammen,

ich hab ja auch nen Nano im Motorrad laufen als RGB thermometer für wasser und öl. Bei mir ohne probleme, zumindest konnte ich keine feststellen. ich hab diesen DC-DC Wandler vorgeschaltet.

http://www.banggood.com/LM2596-DC-DC-Verstellbar-Step-Down-Schaltregler-Power-Supply-Module-p-88252.html?currency=EUR&createTmp=1&utm_source=google&utm_medium=shopping&utm_content=kevin&utm_campaign=elec-de-xiemeijuan&gclid=Cj0KEQjw5ti3BRD89aDFnb3SxPcBEiQAssnp0hfGOdNp-FieineE7CrAK_yxmACvI8y2wV9iGEE49v0aAvsD8P8HAQ

hängt eingangsseitig an geschaltetem plus und ausgangsseitig mit eingestellten 7 Volt an Vin des nanos. läuft tadellos, und ich hab genug leitungen an dem hängen und es kommen noch welche dazu. der nano ist auf einem terminalboard gesteckt, damit habe ich dann gscheite schraubanschlüsse. alles zusammen in einem kleinen plastikgehäuse.

http://www.robotshop.com/media/files/images/xbig/en/gravitech-terminal-adapter-for-arduino-nano-1-B.jpg

evtl. hilft das ein wenig.

Hallo,

naja, kann gut gehen, wie lange weis niemand. Das Modul mit dem LM2596 ist als normaler DC-DC Wandler aufgebaut. Der hat keinerlei Schutzfunktionen gegen Störungen bzw. Spannungsspitzen die im Bordnetz auftreten können, nicht müssen. So verseucht wie früher sind die Bordnetze heute sicherlich nicht mehr. Vorbeugen sollte man dennoch. Ich würde zumindestens nochwas davorschalten.

www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.23 http://www.elektroniknet.de/automotive/sonstiges/artikel/87359/ http://www.mikrocontroller.net/articles/Kfz_Spannungsspitzenkiller_/_Transientenschutz

Hallo,

das Problem konnte durch eine Diode im Signalkabel (vom Arduino wegzeigend) gelöst werden.

Danach lief allerdings die Pumpe nicht mehr, ich denke aber nicht, dass das zusammenhängt. Hab das auch alles einzeln getestet, ich hab wohl aus Unachtsamkeit irgendwas zerstört.

Das ganze liegt jetzt erstmal für kurze Zeit auf Eis. Wenns weitergeht melde ich mich nochmal.

Die Diode sollte in der Plusleitung hängen, mit Ring zum Arduino (Vin)... dazu ein dicker Kondensator...

Schau dir mal den Schaltplan vom Rehoiler an (rehtronik.de/IQ72.pdf). Genau so nehm ich an meinem Arduino Heizöler das Signal ab. Funktioniert sowohl mit Hallsensor als auch mit Tachosignal. Dürfte mit Reed ebenso funktionieren.

Zu deinem Code:

  • Das delay sollte weg
  • Den Interrupt habe ich auf FALLING (weiß nicht, ob es wichtig ist, aber so funktionierts jedenfalls mit Rehoiler Schaltung)
  • In der Interruptmethode nur hochzählen. Was soll da der Millis Vergleich? Entprellen sollte nicht nötig sein, das macht der Kondensator schon.
void ChainOiler::processTick() {
	_remainingOilTicks--;
	_speedTicks++;
	if (_remainingOilTicks < 1) {
		_remainingOilTicks += _requiredOilTicks;
		_speedPump = true;
	}
	_lastTickMillis = millis();
}

Das ist mein Code im Interrupt als Beispiel: Du musst aber bedenken, dass ich auch die Geschwindigkeit berechne und nicht direkt öle, sonder nur ölen markiere und nur bei passender Geschwindigkeit öle. _speedTicks und _lastTickMillis brauchst du nicht, wenn du keine Geschwindigkeit berechnen willst. _speedPump wird im loop ausgewertet und schaltet dann abhängig von der Geschwindigkeit und Strecke die Pumpe ein.

  • Wenn du deine Ticks zum ölen resettest, dann nicht auf 0 setzen, sondern die ZielTickzahl abziehen. Damit geht garantiert nix verloren, falls Abziehen und Interrupt zugleich laufen sollten.
  • Nicht jedes mal ausrechnen wieviele Ticks für deine Wegstrecke nötig sein sollten (das ist redundant und verbraut unnötig Rechenzeit. 1x Rechnen und speichern und davon abziehen. Wenn das auf 0 ist, dann wieder auf den Wert setzen (_remainingOilTicks und _requiredOilTicks in meinem code Beispiel).

Fürs Pumpen ohne delay hier ein Beispiel:

void ChainOiler::processPump() {
	static unsigned long pumpOnUntilMillis = 0;
	static unsigned long pumpOffUntilMillis = 0;

	unsigned long currentMillis = millis();

	if (_pumpActive && pumpOnUntilMillis < currentMillis) {
		deactivatePumpPin();
		pumpOffUntilMillis = currentMillis + PUMP_OFF_INTERVAL_MILLIS;
	} else if (!_pumpActive && _startPump && pumpOffUntilMillis < currentMillis) {
		if (_stopPump) {
			_startPump = false;
		}
		pumpOnUntilMillis = currentMillis + PUMP_ON_INTERVAL_MILLIS;
		activatePumpPin();
	}
}

void ChainOiler::deactivatePumpPin() {
	_pumpActive = false;
	digitalWrite(_pinPump, LOW);
}

void ChainOiler::activatePumpPin() {
	_pumpActive = true;
	digitalWrite(_pinPump, HIGH);
}

void ChainOiler::pumpOnce() {
	_startPump = true;
	_stopPump = true;
}

void ChainOiler::pumpOn() {
	_startPump = true;
	_stopPump = false;
}

void ChainOiler::pumpOff() {
	_startPump = false;
	_stopPump = true;
}

pumpOn() aktiviert Dauerpumpen (zum Entlüften). pumpOff() schaltet ab. pumpOnce() sorgt dafür, dass genau 1x gepumpt wird (das wird beim eigentlichen ölen benutzt). processPump() wird im loop gerufen.

Ich hoffe es hilft mehr, als es verwirrt.

Das hilft sehr! Danke!

Ich überarbeite meinen Code und sehe zu, dass ich im Laufe der Woche mal wieder in die Uni komme, um Bauteile zu besorgen ;)

Btw. falls es dir nicht so sehr ums selber entwickeln, sondern einfach ums Ergebnis geht, kannst du auch gerne meinen kompletten Source haben. Dann musst du ein paar Sachen ändern und hast nen fertigen Code für einen Kettenöler mit Settings, die sich seriell einstellen lassen (Arduino App dazu existiert auch). Natürlich kannst du aber auch gerne noch die Griffheizung und das Display mit einbinden, wenn du magst.

Allerdings gibts halt keinen gezeichneten Schaltplan und das Projekt ist in Eclipse erstellt (lässt sich also nicht einfach mit der normalen Arduino IDE öffnen und kompilieren). Für jemanden, der prinzipiell weiß, was er macht, ist es aber ein Kinderspiel, das alles zum laufen zu bringen.

Nur für Anfänger, die weder programmieren können, noch von elektronischen Bauteilen ne Ahnung haben, ist es leider nicht geeignet (ich wollt das Projekt ursprünglich mal so weit bringen und quasi open source machen zum nachbauen für jedermann, hab dann aber keinen Weg gefunden, wie ich einfach das HEX bereitstellen kann und jeder kann es dann einfach auf den Arduino uploaden - das entsprechende Programm zum Uploaden fehlt mir). Im aktuellen Zustand muss leider jeder erstmal die IDE mit Eclipse aufsetzen, damit er kompilieren und uploaden kann.

Doc_Arduino: Hallo,

naja, kann gut gehen, wie lange weis niemand. Das Modul mit dem LM2596 ist als normaler DC-DC Wandler aufgebaut. Der hat keinerlei Schutzfunktionen gegen Störungen bzw. Spannungsspitzen die im Bordnetz auftreten können, nicht müssen. So verseucht wie früher sind die Bordnetze heute sicherlich nicht mehr. Vorbeugen sollte man dennoch. Ich würde zumindestens nochwas davorschalten.

www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.23 http://www.elektroniknet.de/automotive/sonstiges/artikel/87359/ http://www.mikrocontroller.net/articles/Kfz_Spannungsspitzenkiller_/_Transientenschutz

naja, da diese teile nun in diversen mopeten verbaut sind, glaube ich da nicht an einen zufall. die laufen nun seit rund einem jahr ohne probs.

@TelosNox Das Angebot nehme ich dankend an! Das zum laufen zu bekommen traue ich mir durchaus zu.

http://forum.arduino.cc/index.php?topic=326073.0

Dann schau mal da, ich hab den Link zu den Sourcen mit angehängt. Ist eine kleine readme mit drin.