Selbstbau Simple Ketten Oiler für Motorrad

Hallo Com,

Ich bin ganz neu hier im Forum und auch in Arduino bin ich quasi Newbie :wink:
ich beschäfftige mich mit dem Ding seit gut 4 Wochen und habe mir vor gut 2 Wochen ein Starterkit gekauft.

Habe mit kleinen Spaß Projekten angefangen wie per Schalter die pin13 led leuchten lassen usw.

Vorgestern hat mich ein Freund auf die Idee gebracht für unsere Motorräder einen Kettenoiler zu bauen.
Da ich total Lust auf Arduino habe, dachte ich mir ich gucke mal wieweit ich komme....

Imprinzip möchte ich einmal das ein Taster eine Pumpe betreibt, damit ich den schlauch mit öl füllen kann.
Das klappt sogar schon soweit lach

Das zweite ist, ein reedkontakt soll impuls auf ein relais geben und die pumpe schalten
da ich kein reedsensor habe (ist bestellt) habe ich mir aus dem starterkit einfach den bewegungsmelder genommen um zu testen.
Das ganze geht auch schon so halb sprich der bewegungsmelder gibt impuls und meine test led leuchtet.

Nun ist es aber so, dass er nicht bei jedem kontakt pumpen soll, sondern zB nur jede Minute für ca. 2 Sekunden.
(ist nur ein Beispiel) das muss ich später testen am motorrad.
ich habe es mit delays versucht, das geht zwar aber ist iwie nicht richtig wie ich finde :slight_smile:

Da benötige ich nun eure Hilfe...
Wie kann ich sowas realalisieren ?

Hier mein bisheriger Sketch (bitte nicht gleich los lachen :wink: bin wie gesagt blutiger Anfänger)

int LEDboard=13;
int taster=7;
int tasterstatus=0;
const int reedpin = 2; // Reedkontakt Eingangspin
const int pumpe = 9; // Zum Pumpenrelais derzeit noch eine LED auf PIN 9
int reedkontaktzustand = 0; // Variable zum lesen des Reedstatus status

void setup()
{
pinMode(LEDboard, OUTPUT);
pinMode(taster, INPUT);
// der pumpen/LED ausgang:
pinMode(pumpe, OUTPUT);
// der Reedkontakt eingang:
pinMode(reedpin, INPUT);
}

void loop()
{
oiltaster();
reedkontakt();
}

//////////////////////////////////////OILTASTER//////////////////////////
void oiltaster()
{
tasterstatus=digitalRead(taster);
if (tasterstatus == HIGH)
{
digitalWrite(LEDboard, HIGH);
delay (500);
digitalWrite(LEDboard, LOW);
}
else
{
digitalWrite(LEDboard, LOW);
}
}
//////////////////////////////////////OILTASTER-ENDE/////////////////////

//////////////////////////////////////REED-KONTAKT/////////////////////
void reedkontakt()
{
// lese den status vom reedkontakt
reedkontaktzustand = digitalRead(reedpin);
if (reedkontaktzustand == LOW) {
// Pumpe oder LED aus
delay(900);
digitalWrite(pumpe, LOW);
}
else {
// Pumpe oder LED an
delay (4500);
digitalWrite(pumpe, HIGH);
}
}

//////////////////////////////////////REED-KONTAKT-ENDE/////////////////////

PhyniX:
... bin wie gesagt blutiger Anfänger

Dann ist schonmal gut, dass Du ein paar superdeutliche Kommentare im Code untergebracht hast.

Ich habe Deinen Code mal Auto-Formatiert (Strg-T), ein bisschen gekürzt (überflüssige Zeilenumbrüche raus, Kommentare umgestellt ...), ein paar 'int's in 'const byte' geändert und in Code-Tags eingeschlossen:

const byte LEDPin = 13;
const byte tasterPin = 7;
const byte reedPin = 2; // Reedkontakt Eingangspin
const int pumpenPin = 9; // Zum Pumpenrelais derzeit noch eine LED auf PIN 9

void setup()
{
  pinMode(LEDPin, OUTPUT);
  pinMode(tasterPin, INPUT);
  pinMode(pumpenPin, OUTPUT); // der pumpenPin/LED ausgang:
  pinMode(reedPin, INPUT); // der Reedkontakt eingang:
}

void loop()
{
  oiltaster();
  reedkontakt();
}

////////////////////////////////OILTASTER//////////////////////////
void oiltaster()
{
  if (digitalRead(tasterPin) == LOW)
  {
    digitalWrite(LEDPin, HIGH);
    delay (500);
    digitalWrite(LEDPin, LOW);
  }
  else
  {
    digitalWrite(LEDPin, LOW);
  }
}
////////////////////////////////OILTASTER-ENDE/////////////////////

//////////////////////////////////REED-KONTAKT/////////////////////
void reedkontakt()
{
  if (digitalRead(reedPin) == LOW) {  // Pumpe oder LED aus
    delay(900);
    digitalWrite(pumpenPin, LOW);
  }
  else {                              // Pumpe oder LED an
    delay (4500);
    digitalWrite(pumpenPin, HIGH);
  }
}
/////////////////////////////REED-KONTAKT-ENDE/////////////////////

Und zu Deiner Frage, wie Du das realisieren kannst, was Du möchtest: Arbeite nicht mit delay(), sondern mit millis() und programmiere eine „finite state machine“ (einen endlichen Automaten). Evtl. hilft Dir, was ich mir hier (und die Folgeseite) dazu habe einfallen lassen.

Gruß

Gregor

Erstmal vielen Dank für das umstellen des Codes sieht jetzt iwie auch sauberer aus :slight_smile:
Ja das mit dem Kommentaren, solle man sich gleich angewöhnen haben die Totorialschreiber immer rot unterstrichen lach

Danke für deine Antwort, ich werde das mal versuchen sieht aber iwie schwer aus lach

Wenn das nicht so Spaß machen würde.

PhyniX:
... sieht aber iwie schwer aus lach

Es sieht wirklich nur schwer aus, ist im Grunde aber ziemlich einfach. Teile das, was Du machen möchtest, in Schritte auf, bei denen Du sagen kannst, wann welche Aktion durchgeführt werden soll. Das kann zwar ein ziemliches Gehampel mit millis()-Zeiten geben, aber es lässt sich sehr gut verstehen, bearbeiten und debuggen.

PhyniX:
Wenn das nicht so Spaß machen würde.

Wem sagst Du das ...

Gruß

Gregor

PS: Alles ist gut, was man gerne tut (Fanta 4)

Hallo vielen Dank für die schöne Anleitung.
Diese hat mit bissel probieren wunderbar geklappt.
Theoretisch ist der sketch jetzt schon fertig,aber ich habe noch eine idee :wink:

Ich möchte per Schalter oder Taster
Einen Regenmodus hinzufügen
Die Funktion ist schon fertig aber die Funktionumschaltung per Taster, da habe ich iwie keine idee das einfach hinzubekommen.

Hast Du evtl. noch ein klasse idee für mich ?

Gruss

PhyniX:
Ich möchte …
Hast Du evtl. noch ein klasse idee für mich ?

Poste den funktionierenden Code (in „Code-Tags“ - </>-Knopf im Editor) und formuliere das, was Du möchtest so, dass ich es verstehe. Dann gucke ich mir das an und schreibe etwas Sinnvolles dazu.

Gruß

Gregor

Nachtrag:
Klar zu formulieren, was man erreichen möchte, ist üblicherweise ein Riesenschritt in Richtung der Lösung. Mich würde nicht wundern, wenn Du den entsprechenden Code dann selbst schreiben könntest.
Ach ja: Und wenn alles so funktioniert, wie Du möchtest, gibst Du mir einen Karma-Punkt :slight_smile:

Servus, wenn du magst, kannst du dir den Sketch im Anhang durchschauen.
Ich hab mich letztes Jahr mit dem Thema beschäftigt :wink:

Implementiert
Ist z.B.
Kommunikation via Jason während der Laufzeit
Schlechtwetter,
Speichern der Distanz beim Abschalten der Zündung,
die Möglichkeiten alle Parameter für die Pumpe einzustellen,
Entlüften,
Ermitteln der Anzahl der Pumpvorgänge bis der Behälter leer ist, und Ausgabe einer Warnung.
Konfiguration der Anzahl der Pumpstöße beim Ölvorgang
Kommunikation via .BT-Modul über die serielle Schnittstelle,
usw.

Kettenoeler_V4.07_mit_Jason_EEPROMx_Bounce_BT.zip (6.66 KB)

Hast Du evtl. noch ein klasse idee für mich ?

Ja!
Manuelle Ölpumpe (oder vergleichbares)
Plus ein paar Tricks, damit das Öl gleichmäßg läuft.

Vorteil:
Die Automatiköler machen einen Pumpenstoß, dank Murphy, meistens auf den letzten 5 Metern vor der Garage.
Damit ist die Bildung einer Ölpfütze quasi garantiert.

Erstmal danke für die Tipp und den Code.
Doch erstmal möchte ich bei meinem Test Oiler bleiben :slight_smile: (auch zu lernzwecken.)

ich bin jetzt schon soweit das es quasi funktioniert nur ist die logik meines erachtens iwie noch nicht das wahre lach

ich möchte halt, dass der oiler beim ersten kontakt ca eine minute wartet und dann das signal zur pumpe abgibt.

Das geht auch, nur ist zb eine standzeit an der ampel nicht berücksichtigt.
Denn erzählt 1 minute runter und führt aus.
Aber da bin ich einfach noch zu dolle leihe damit ich das iwie besser lösen kann zumindest habe ich das gefühl

ich denke ich es schlauer wenn man kontakte zählt und dann einsignal gibt.

so zumbeispiel : reedkontakt = 1000 impule = pumpe für 1 sekunte an = reset und von vorne das ganze

dann mir da jemand nen code beispiel nennen ?

anbei mein code:

/ Variablen
int schaltmodus = 1;              // Variable für die verschiedenen Schaltmodis (Start auf Modus 1 normal Modus)
int tasterStatus = LOW;           // Variable zu speichern des Tasterstatus
const int tasterPin = 11;         // Taster an Pin 2 angeschlossen
int taster = 7;                   // Oiltaster auf PIN 7
int tasterstatus = 0;
const int reedpin = 5;            // Reedkontakt Eingangspin
const int pumpe = 9;              // Zum Pumpenrelais derzeit noch eine LED auf PIN 9
int reedkontaktzustand = HIGH;    // Variable zum lesen des Reedstatus status
unsigned long Zeit;               // Variable Speicher für Systemzeit.
long pumpeAus = 75000;              // Zeit wie lange die NORMALE-Pumpe aus ist 1 25 min
long rainpumpeAUS = 60000;          // Zeit wie lange die REGEN-Pumpe aus ist
long rainpumpeEIN = 1000;           // Zeit wie lange die REGEN-Pumpe pumpt 1sek
long pumpeEin = 1000;              // Zeit wie lange die NORMALE-Pumpe pumpt
int programmLED1 = 2;
int programmLED2 = 3;            // Programm Status LEDs
int programmLED3 = 4;



void setup()
{
  pinMode(tasterPin, INPUT);      // Setzt den TasterPin als Eingang
  
  pinMode(taster, INPUT);         // Oeltaster
  // der pumpen/LED ausgang:
  pinMode(pumpe, OUTPUT);         // Pumpen Ausgang
  // der Reedkontakt eingang:
  pinMode(reedpin, INPUT);        // reedkontakt EINGANG

  pinMode(programmLED1, OUTPUT);
  pinMode(programmLED2, OUTPUT);   // Programm LEDs Ausgaenge
  pinMode(programmLED3, OUTPUT);


}


void loop()
{
  // Abfrage ob der Taster gedrückt ist
  tasterStatus = digitalRead(tasterPin);

  // Wenn Taster gedrückt ist...
  if (tasterStatus == HIGH)
  {
    schaltmodus++;     // Schaltmodus +1 (immer einen hoeher schalten
    delay(300);       // 300ms warten

  }

  //+++++++++++++++ SCHALTPROGRAMME +++++++++++++++++

  // Modus 0 = Alles AUS
  if (schaltmodus == 0)
  {
    digitalWrite(programmLED1, 0);                // Programmstatus LED an
    digitalWrite(programmLED2, 0);
    digitalWrite(programmLED3, 0);
    digitalWrite(pumpe, LOW);
  }

  // Modus 1 = Normalmodus (schoenwetter)
  else if (schaltmodus == 1)
  {

    digitalWrite(programmLED1, 0);               // Programmstatus LED an
    digitalWrite(programmLED2, 0);
    digitalWrite(programmLED3, 255);
    // lese den status vom reedkontakt
    reedkontaktzustand = digitalRead(reedpin);
    if (reedkontaktzustand == HIGH)
    {
      if (millis() - Zeit > pumpeAus) { // Zeit wielange die Pumpe aus bleibt

        digitalWrite(pumpe, HIGH);
        Zeit = millis();

      }
    }
    else {
      if (millis() - Zeit > pumpeEin) { // Zeit wie lange die Pumpe pumpt
        digitalWrite(pumpe, LOW);
        //reedkontaktzustand = LOW;

      }
    }
  }

  // Modus 2 = Regenmodus
  else if (schaltmodus == 2)
  {
    digitalWrite(programmLED1, 0);                // Programmstatus LED an
    digitalWrite(programmLED2, 255);
    digitalWrite(programmLED3, 0);

    // lese den status vom reedkontakt
    reedkontaktzustand = digitalRead(reedpin);
    if (reedkontaktzustand == HIGH) {

      if (millis() - Zeit > rainpumpeAUS) { // Zeit wielange die REGEN-Pumpe aus bleibt

        digitalWrite(pumpe, HIGH);
        Zeit = millis();
        //reedkontaktzustand = HIGH;
        //digitalWrite (pumpe, LOW);
      }

    }
    else {

      if (millis() - Zeit > rainpumpeEIN) { // Zeit wie lange die REGEN-Pumpe pumpt
        digitalWrite(pumpe, LOW);


      }
    }
  }


  // Modus 3 = Pumpe per Taster schalten
  else if (schaltmodus == 3)
  {
    digitalWrite(programmLED1, 255);                // Programmstatus LED an
    digitalWrite(programmLED2, 0);
    digitalWrite(programmLED3, 0);
    digitalWrite(pumpe, LOW);
    tasterstatus = digitalRead(taster); // Oiltasterstutus auslesen
    if (tasterstatus == HIGH)
    {

      digitalWrite(pumpe, HIGH);          // Pumpe einschalten
      delay (150);                        // 150ms warten
      digitalWrite(pumpe, LOW);           // Pumpe Ausschalten
    }

    else
    {
      digitalWrite(pumpe, LOW);          // wenn nicht gedrueckt ausschalten

    }
  }


  // Anzahl der Schaltmodis auf 3 begrenzen. (0 bis 4)
  else
  {
    schaltmodus = 0;
  }
}

Du musst erkennen ob das Motorrad fährt oder steht. Eine Minute zu warten macht dir mehr Probleme als es dir bringt.

Hallo, danke für die antwort.

Das hatte ich in meinem lösungsversuch ja schon angedeutet. Nur die umsetung bekomme ich nicht hin leider

Lösung soll sein:
Wenn reedsensor 1000 x einen input bekommt soll für 1 sek die pumpe aktiviert werden. Und dann von vorne anfangen.

Aber ich habe kein ahnung wie ich das anfangen soll.

Deshalb die frage nach einem codebeispiel

PhyniX:
... Aber ich habe kein ahnung wie ich das anfangen soll.

Meiner Meinung nach solltest Du damit anfangen, dass Du Deinen Code „hübscher“ machst – d. h. sinnvoll einrücken, Leerzeilen löschen, auf max. 80 Zeichen Breite bringen ...

Damit machst Du es nicht nur denjenigen leichter, die Dir helfen möchten, sondern hilfst Dir vor Allem selbst, Fehler oder Ungereimtheiten im Programm zu vermeiden bzw. zu erkennen.

Gruß

Gregor

OK danke Gregor für deine Antwort.
Aber der Code funktioniert wie er soll
es geht um das Beispiel was ich in Worten beschrieben habe.

Mir ist eben noch ein Einfall gekommen lach
leider möchte der nicht so wie ich lach
denn er löst warum auch immer bei jeden reedkontaktimpuls aus statt erst bei dem 30sten wie ich wollte :frowning:

reedkontaktzustand = digitalRead(reedpin);
    if (reedkontaktzustand == HIGH)     //reedkontakt an
    {
      zaehler++;                                  //impulse 1+
     if (zaehler == 30){                       // wenn zähler bei 30 impulsen dann pumpe
     
      digitalWrite(pumpe, HIGH);          // pumpe an
        }
      }
    
   else {
      digitalWrite(pumpe, LOW);

Wenn Du Deinen Code sinnvoll einrückst, merkst Du wahrscheinlich, wo der Fehler ist. Ich tippe auf einen Klammerfehler, wollte den schlecht formatierten Code aber nicht analysieren.

Gruß Tommy

PhyniX:
denn er löst warum auch immer bei jeden reedkontaktimpuls aus statt erst bei dem 30sten wie ich wollte :frowning:

Mit reedkontaktzustand == HIGH fragst Du einen Zustand ab, Du möchtest aber die Veränderung zählen. Dazu benötigst Du die Signalflanke !reedkontaktzustandalt&&reedkontaktzustandakt.

Hast Du den Kontakt entprellt? Sonst zählt der µC auch das Prellen.

Strg+t formatiert in der IDE. Für Tommy:

reedkontaktzustand = digitalRead(reedpin);
if (reedkontaktzustand == HIGH)     //reedkontakt an
{
  zaehler++;                                  //impulse 1+
  if (zaehler == 30) {                      // wenn zähler bei 30 impulsen dann pumpe
    digitalWrite(pumpe, HIGH);          // pumpe an
  }
} else {
  digitalWrite(pumpe, LOW);
}

agmue:
Strg+t formatiert in der IDE. Für Tommy:

Ich weiß, wie man einen Code formatiert.
Es nervt nur manches Mal, wie schrottig die Codezeilen hier rein gestellt werden.
Irgendwie drückt das für mich eine Einstellung des Anfragenden aus.

Gruß Tommy

@ agmue vielen Dank, das war der hinweis den ich beauchte :relaxed:
@ Tommy nicht immer das negative im Menschen suchen.
Denn hier schreiben auch Anfänger die nicht unbedingt wissen wie man sowas vernünpfig formatiert.

Ps. Werde nach der arbeit mal schauen ob es klappt

Tommy56:
Ich weiß, wie man einen Code formatiert.

Kleines Mißverständnis: Der erste Satz sollte PhyniX helfen, eine Sketch lesefreundlich zu formatieren, der zweite Dich motivieren, weiter helfend mitzuwirken. Bitte lies es mit einem Lächeln :slight_smile:

Tommy56:
Es nervt nur manches Mal, wie schrottig die Codezeilen hier rein gestellt werden.
Irgendwie drückt das für mich eine Einstellung des Anfragenden aus.

Ich denke, ich weiß, was Du meinst. Dass ich auf „hübschen“ Code stehe, dürfte bekannt sein :slight_smile:

Andererseits ist das Schreiben „hübschen“ Codes für einen Anfänger (und solche schlagen hier ja üblicherweise auf) nicht das Ziel erster (und der ersten paar) Sketche. Wie sehr hübscher Code hilft, den Überblick zu behalten (oder zu bekommen) und Fehler zu finden/zu vermeiden, wird erst klar, wenn man Probleme hat, die man wegen der „Hässlichkeit“ des Codes nicht findet.

Naja, auch ein Computerprogramm „sagte“ mal: Die Leute gehen mir manchmal auf die Nerven. (PARRY, s. Poesiemaschinen - Maschinenpoesie).

Gruß

Gregor

agmue:
Kleines Mißverständnis: Der erste Satz sollte PhyniX helfen, eine Sketch lesefreundlich zu formatieren, der zweite Dich motivieren, weiter helfend mitzuwirken. Bitte lies es mit einem Lächeln :slight_smile:

Keine Sorge, so schnell hat mich nichts um.

Gruß Tommy