Go Down

Topic: Problem mit for Schleife (Read 427 times) previous topic - next topic

pyrogekko

Jun 23, 2018, 06:42 pm Last Edit: Jun 23, 2018, 06:49 pm by pyrogekko
Hallo,

bin neu hier und würde mich freuen, wenn Ihr mir helfen könntet.

Ich bin Sportschütze und unsere Duell Anlage hat sich in Rauch aufgelöst.
Das Problem versuche ich nun mit einer Arduino Steuerung zu lösen.
Soweit läuft mein Programm auch sauber durch, nur möchte ich das ganze nun erweitern, dass nach 5 maligem "Scheiben drehen" das Programm anhält und ich den nächsten durchgang per Taster starten kann.
Leider läuft das Programm immer weiter und endet nicht nach 5 Durchgängen.
Ich weiss nicht, wo der Fehler liegt :(

Hier mein Quelltext:

Code: [Select]

void setup()
{
 pinMode( 10 , OUTPUT);            // Motor Relais an Pin 10
 digitalWrite(10 , LOW);           // Motor aus
 
}

void loop()
{
 for (int i=1; i<=5; i++)             //Wiederholung
   {
   digitalWrite(10 , HIGH);          // Motor an
   if (digitalRead(2)==HIGH)         // Abfrage Endschalter A
   {
     digitalWrite(10 , LOW);         // Motor aus
     delay( 5000 );                  // Zeit warten
     digitalWrite(10 , HIGH);        // Motor an
     delay( 205 );                   // Zeit warten bis Endschalter verlassen
   }
   digitalWrite(10 , HIGH);          // Motor an
   if (digitalRead(4)==HIGH)         // Abfrage Endschalter B
   {
     digitalWrite(10 , LOW);         // Motor aus
     delay( 3000 );                  // Zeit warten
     digitalWrite(10 , HIGH);        // Motor an
     delay( 205 );                   // Zeit warten bis Endschalter verlassen
   }
   }
   digitalWrite(10 , LOW);
}


Ich bin nicht der Arduino Profi, also bitte nicht steinigen, wenn etwas verkehrt ist.
Bin für jede Hilfe dankbar.
In dem Quelltext ist der Start Taster noch nicht drin, da ich erstmal das wiederholungsproblem lösen wollte.

Tommy56

Setze Deinen Sketch bitte in Codetags (</>-Button oben links im Forumseditor), damit er für alle gut lesbar ist.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

pyrogekko

Danke für den Hinweis.

Gruß pyrogekko

Thorsten4171

Du rufst in der Loop die for Schleife immer wieder auf .Wenn die abgearbeitet ist geht es wieder von vorne los.

Tommy56

Du brauchst keine for-Schleife. Du hast doch loop als Schleife.
Zähle eine globale Variable bei jedem Durchlauf deiner Aktion hoch, solange sie unter der Grenze (5) ist.

Also etwa so:
Code: [Select]

byte zaehler = 0;
...

// im Loop
if (zaehler < 5) {
  zaehler++;
  // mache Deine Aktion
}



Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

pyrogekko

Du rufst in der Loop die for Schleife immer wieder auf .Wenn die abgearbeitet ist geht es wieder von vorne los.
Danke für deinen Post.Gibt es eine Möglichkeit das zu unterbinden?

Du brauchst keine for-Schleife. Du hast doch loop als Schleife.
Zähle eine globale Variable bei jedem Durchlauf deiner Aktion hoch, solange sie unter der Grenze (5) ist.

Also etwa so:
Code: [Select]

byte zaehler = 0;
...

// im Loop
if (zaehler < 5) {
  zaehler++;
  // mache Deine Aktion
}



Gruß Tommy
Danke Tommy.
Ich hab mir das eben kurz angeschaut, aber muss noch sehr viel lesen dazu, wie und wo ich das einbaue.
Habe noch nie Zähler benutzt.

Tommy56

Das i in Deiner for-Schleife ist auch ein Zähler. Also hast Du schon welche benutzt ;) wohl ohne es zu merken.
In der IT fängt man überwiegend / fast generell bei 0 an zu zählen.

Etwas Lernen ist immer angesagt, wenn man nicht bei Copy & Paste stehen bleiben will. Schau Dir die Beispiele in der IDE an, baue sie nach und verstehe ihre Wirkungsweise. Dann bist Du auf dem richtigen Weg.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

gregorss

... muss noch sehr viel lesen ...
Tu das. Lernen gehört zu den besten Dingen, die man mit seinem Hirn anstellen kann :-)

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

Thorsten4171

Indem du die for Schleife in eine if Abfrage steckst.


Code: [Select]
if (Variable==true){
    for(int i=0; i<=4; i++){
      //tue was
    }
    Variable=false;
  }

Aber mach es lieber gleich wie Tommy gesagt hat.Eine for schleife ist blockierend.

amithlon

#9
Jun 24, 2018, 09:24 am Last Edit: Jun 24, 2018, 09:25 am by amithlon
Hallo,

Hallo,

alle bisherigen Hinweise sind völlig ok, ich vermisse aber einen auf das konkrete Projekt bezeogenen Hinweis:
die Durchlaufzeit Deiner for-Schleife ist "ewig" bezogen auf die Geschwindigkeit eines µC.
Ein neuer Duchlauf von loop kommt also ohnehin nur nach etlicher Zeit, wenn die Scheibe komplett gedreht wurde, zustande.

Einfach vor der for Schleife die Tasterabfrage einfügen:

Code: [Select]


#define Taster 5      // Pinnummer des Tasters
...
setup()
{
  pinMode(Taster, INPUT_PULLUP)         //Taster gegen GND anschließen
...
}

loop()
{
  while (1)
  {
    if (digitalRead(Taster) == LOW)   // Taster gedrückt
    {
      delay(50);
      if (digitalRead(Taster) == LOW)   // Taster immernoch gedrückt, gegen Störimpulse und Prellen
      {
         break;                                  // wihile verlaseen und for laufen lassen
       }
    }     
  }
  // hier Deine for-Schleife
}


Ich finde, man kann durchaus auch zweckbezogene Lösungen nutzen, andere Möglichkeiten lernen sollte man trotzdem.

Ein Einsteiger wird am Anfang kaum überblicken, was er alles für zukünftige vielleicht mal gewünschte Erweiterungen so beachten muß.
Das ist ohnehin ein ewiges dazulernen, ein Hinweis auf den blockierenden Ablauf ist ja durchaus ok, nur dann müßte er alles neu bauen...
Wenn das Teil so erstmal ein halbes Jahr seinen Zweck erfüllt, hat er genug Zeit, neue Ideen zu testen.

Gruß aus Berlin
Michael

pyrogekko

Hallo,

erstmal großen Dank für die vielen Vorschläge und Hilfestellungen.

Bisher habe ich nur andere Sketche umgeschrieben und nie was eigenes erstellt.
Da ich nun eine eigene Steuerung benötige, werde ich mich natürlich mehr damit beschäftigen.
Ich will ja auch wissen, wie und warum das funktioniert.Copy & Paste kann ja jeder.

Da wir nächten Monat Rundenwettkämpfe haben und die Anlage erstmal generell laufen muss, habe ich euren Vorschlag mit dem Schalter vor der for Schleife genommen.
Nun startet das ganze einfach und läuft halt durch, bis ich den Kippschalter wieder umlege.
Ist vielleicht nicht ideal, erfüllt aber erstmal seinen Zweck und gibt mir etwas Zeit, mich mehr mit der Materie zu beschäftigen.

Das einzige was ich nicht verstehe ist, warum die for Schleife nicht nach 5 mal anhält und einfach weiter macht...
Da muss ich mich wohl etwas mehr reinlesen in die Materie.

Danke nochmals an alle.

Hier mein jetziger Sketch:

Code: [Select]

void setup()
{
  pinMode( 10 , OUTPUT);              // Motor Relais an Pin 10
  digitalWrite(10 , LOW);             // Motor aus
 
}

void loop()
{
  if (digitalRead(8)==HIGH)           // Kippschalter
  {
     
  for (int i=1; i<=5; i++)            // Wiederholung
    {
    digitalWrite(10 , HIGH);          // Motor an
    if (digitalRead(2)==HIGH)         // Abfrage Endschalter A
    {
      digitalWrite(10 , LOW);         // Motor aus
      delay( 5000 );                  // Zeit warten
      digitalWrite(10 , HIGH);        // Motor an
      delay( 205 );                   // Zeit warten bis Endschalter verlassen
    }
    digitalWrite(10 , HIGH);          // Motor an
    if (digitalRead(4)==HIGH)         // Abfrage Endschalter B
    {
      digitalWrite(10 , LOW);         // Motor aus
      delay( 3000 );                  // Zeit warten
      digitalWrite(10 , HIGH);        // Motor an
      delay( 205 );                   // Zeit warten bis Endschalter verlassen
    }
    }
  }
  digitalWrite(10 , LOW);             // Motor aus
}


Gruß Waldi

Tommy56

Das einzige was ich nicht verstehe ist, warum die for Schleife nicht nach 5 mal anhält und einfach weiter macht...
Da muss ich mich wohl etwas mehr reinlesen in die Materie.
Das wurde Dir weiter oben auch schon gesagt: Die for-Schleife fängt immer wieder neu an, solange der Taster gedrückt ist.
Du musst Dir merken, dass es schon gelaufen ist, wenn Du es mit der Schleife machen willst.
Code: [Select]

boolean gelaufen = false;

...
  if (!gelaufen && digitalRead(8)==HIGH)           // Kippschalter
  {
     gelaufen = true;
     for...
  }
  if ( digitalRead(8)==LOW) {
    gelaufen = false;
                         
  }
...



Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

amithlon

#12
Jun 24, 2018, 04:41 pm Last Edit: Jun 24, 2018, 04:44 pm by amithlon
Hallo,

ok nun ist aus dem Taster plötzlich ein Kippschalter geworden...
Dann wirst Du auf die Lösung von Tomm56 zurückgreifen müssen.

Heißt praktisch für Dich ja:
Schalter auf ein
Schleife läuft einmal durch und wartet dann bis Du den Schalter wieder ausschaltest.
Dann mußt Du für den nächsten Durchlauf den Schalter wieder einschalten.
Wäre für mich von der Handhabung etwas unlogisch.

Ich vermisse auch das pinMode(schalterpibx,INPUT_PULLUP);
Eingang ist beim AVR der Pin ja nach Reset,
du verläßt Dich hier aber daruf, daß die IDE den PullUp einschaltet oder hast Du einen externen Widerstand dran?

Gruß aus Berlin
Michael



pyrogekko

@Tommy:
Stimmt, hab ich total übersehen.War irgendwie eben zu sehr auf den Schalter fixiert.
Danke für deinen Lösungsansatz.Werde das mal einbinden.Ergibt bei genauem hinsehen Sinn.
Ich muss lernen, wie eine Maschine zu denken...


@Michael:
Habe deinen sketch bei mir eingebaut, aber irgendwie lief das nicht so, wie es sollte.
Das Relais Board hat nur geblinkt und die Endschalter wurden ignoriert bzw nach betätigen dieser ging das relais dauerhaft aus.
Aus diesem Grund habe ich einen Kippschalter genommen, der den loop startet.
Wenn ich diesen umlege läuft der loop bis ins unendliche durch und wenn ich umschalte, wird das relais ausgeschaltet, damit der Motor nicht weiter dreht.
Ist quick and dirty irgendwie,aber läuft erstmal.
Muss man jetzt also nach 5 Durchgängen manuell ausschalten, bis die andere Lösung läuft.

Die Endschalter, sowie die Kippschalter sind über 10k Widerstände an Masse Angeschlossen.
Anfangs hatte ich es ohne Widerstände, aber da kam nur blödsinn bei raus.
Externe Widerstände waren für mich einfacher, als im IDE welche ein zu schalten.

Gruß Waldi


gregorss

Hier mein jetziger Sketch:
Code: [Select]

...
    }
    }
...

Solche Zeilen sind meiner Meinung nach ganz übel. Man muss sich erst im restlichen Code orientieren, um zu wissen, welche „Klammer-zu" zu welcher „Klammer-auf" gehört.

Wenn Du Programmier-Anfänger bist, solltest Du Dir unbedingt angewöhnen, die Verschiedenen „Klammer-Ebenen" durch verschiedene Einrückungen deutlich zu machen. Für eine erste „Quick-and-Dirty-Formatierung" eines Sketches kannst Du die Auto-Formatierung des Editors nutzen („Automatische Formatierung" im Werkzeuge-Menü bzw. Strg-T).

Besser ist aber auf jeden Fall, wenn Du solche Sachen selbst machst. Bei der Fehlersuche ist das Gold wert.

Viel Spaß beim Spaßhaben!

Gregor
Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

Go Up