2 for-Schleifen in einander

Hallo zusammen!

Ich bin noch recht neu in der Arduino / C Welt und stehe grade irgendwie auf dem Schlauch...

Ich möchte zwei Servos mit mit je einer for-Schleife langsam drehen lassen. Die sollen allerdings "gleichzeitig" laufen. Die millis() Variante hab ich schon gesehen, aber ich wollte es anders lösen..
Am Ende soll das ganze ein vierbeiniger Laufroboter werden.

Vom Prinzip her soll Servo 1 einen Schritt um k++ machen. Danach ist Servo 2 dran. Das soll sich wiederholen bis der angestrebte Wert erreicht ist.
Die zweite Schleife soll in die erste integriert werden.

Hier wäre mein Code:

  for (int k = 140; k < 180; k++) {
    L12.write(k);
    delay(10);
    for (int m = 150; m < 180; m++) {
      L13.write(m);
      delay(10);
      break;
    }
  }

-In dieser Konstellation fährt Servo L12 komplett durch und L13 macht nichts.
-Wenn ich das break; weglasse fährt L12 um einen Schritt und dann L13 bis 180. Dann L12 wieder um einen Schritt und L13 fährt in die Anfangsposition 150 dann wieder nach 180 und so weiter bis L12 die Position 180 erreicht.
-Wenn ich die {} vom L13 weglasse passiert genau das selbe wie im zweiten Fall..

Ich hoffe ich konnte mein Problem verständlich erklären und vielleicht hat jemand einen Lösungsvorschlag

Philter:
Die millis() Variante hab ich schon gesehen, aber ich wollte es anders lösen..

Ohne millis() wird es nicht gehen.
Es sei denn, Du benutzt eine Lib, die das langsame Drehen bereits beherrscht, z.B. meine :wink: . Die ist von den Aufrufen weitgehend kompatibel zur Standard-Lib, aber man kann auch die Geschwindigkeit einstellen.

So wird das auch nichts. Du blockierst Dich mit Deinen Schleifen selbst.
Du hast doch schon eine große Schleife --> loop().

Für die Zeitsteuerung benutzt Du millis(), kein delay(). Schau Dir dazu in der IDE das Beispiel BlinkWithoutDelay an und verstehe es.
Dann kannst Du auch mehrere Sachen (fast) gleichzeitig, also nebeneinander machen.

Gruß Tommy

Die zweite Schleife soll in die erste integriert werden.

Warum beharrst du darauf, obwohl du schon einsehen musstest, dass das nicht funktioniert?

Zu was brauchst Du das break; in der FOR Scleife? Damit Du sofort aus der FOR -Schleifer raus kommst ohne daß sie ganz abgearbeitet wird?

Die Bemerkungen über millis(), delay() und Servoansteuerung sind berechtigt aber nicht Gegenstand der Fehlfunktion. Wenn Du ein zeilenweises abscannen eines rechteckigen Feldes brauchst, ohne daß etwas anderes gemacht wird, dann funktioniert das.

Grüße Uwe

Wow erstmal danke für die vielen schnellen Antworten!

combie:
Warum beharrst du darauf, obwohl du schon einsehen musstest, dass das nicht funktioniert?

So wie ich es bisher umgesetzt habe funktioniert es wohl nicht. Muss ja nicht heißen, dass es so gar nicht geht :wink: Ich denke mal ich hab irgendwo einen Denkfehler.

uwefed:
Zu was brauchst Du das break; in der FOR Scleife? Damit Du sofort aus der FOR -Schleifer raus kommst ohne daß sie ganz abgearbeitet wird?

Die Bemerkungen über millis(), delay() und Servoansteuerung sind berechtigt aber nicht Gegenstand der Fehlfunktion. Wenn Du ein zeilenweises abscannen eines rechteckigen Feldes brauchst, ohne daß etwas anderes gemacht wird, dann funktioniert das.

Grüße Uwe

Der break; sollte die zweite FOR-Schleife nach dem einmalen ausführen von m++ unterbrechen, damit die erste FOR-Schleife wieder von vorne beginnt.

vielleicht sollte noch erwähnt werden, dasss ich die Standard ServoLib aus der IDE benutze.

Vielleicht erklär ich nochmal wie es eigentlich ablaufen sollte:

Servo L12 fährt einen Schritt (k++)
Servo L13 fährt einen Schritt (m++)
Servo L12 fährt einen Schritt (k++)
usw... bis L12 die Endposition 180 erreicht hat.

uwefed:
Die Bemerkungen über millis(), delay() und Servoansteuerung sind berechtigt aber nicht Gegenstand der Fehlfunktion. Wenn Du ein zeilenweises abscannen eines rechteckigen Feldes brauchst, ohne daß etwas anderes gemacht wird, dann funktioniert das.

Grüße Uwe

Könntest du das etwas erläutern? Ich versteh nicht ganz was du meinst..

Auch viele Grüße zurück, Philipp

Der break; sollte die zweite FOR-Schleife nach dem einmalen ausführen von m++ unterbrechen, damit die erste FOR-Schleife wieder von vorne beginnt

Dann verlierst du aber m.
Musst dessen Definition also vor den Schleifen machen!

int m = 150;
for (int k = 140; k < 180; k++) {
    L12.write(k);
    delay(10);
    for (; m < 180; m++) {
      L13.write(m);
      delay(10);
      break;
    }
  }

Das ist allerdings eine recht kranke Nummer!

Hallo

Eine for Schleife heißt nun mal Schleife weil sie anfängt und beendet wird wenn sie fertig ist. For start to end mit step . Mal abgesehen von dem Break was eigentlich eine Krücke ist.
Schreib einfach deine beiden Fahrbefehle erst mal in einer in eine Schleife hintereinander und danach den delay Dann sollte es schon Mal fast so funktionieren wie du es willst. Servos fahren gleichzeitig und langsam von a nach b .

Dann solltest du im nächsten Schritt die Schleife durch eine If Abfrage ersetzen um von a nach b zu fahren. Dazu benötigst du dann eine variable die mit jedem Umlauf erhöht / verringert wird .
Abhängig von Anfang und Ende legt du dann die Richtung fest . Plus oder minus . Dann kannst mit zwei If konstrukten hintereinander unterschiedliche Anfangs und Endpunkte für jeden Servo festlegen. Dann packst du die einzelnen If Konstrukte in einzelne Funktionen für jeden Servo zusammen . Usw usw

So kannst du dann Schritt für Schritt aufeinander aufbauen um das richtig zu lernen .

Am Ende aber kommst du um das ersetzen des delay durch millis() nicht herum .

du kannst auch eine fertige Lib nehmen und damit arbeiten das führt am schnellsten zum Erfolg, aber du lernst am wenigsten .

Wenn du dann den steinigen Weg gegangen bist und alles begriffen hast kannst du die ja immer noch nehmen .

Heinz

... oder versuche die Lib, Die Dir von MicroBahner ans Herz gelegt wurde ...

Damit hast Du nicht nur Deine smoothe Servo-Bewegung, Du kannst den Arduino auch noch anderes Zeug nebenbei machen lassen.
So wie bisher hat der Arduino 'alle Hände voll zu tun' - nur, damit die zwei Servos halbwegs zusammen laufen.
Davon ab - wenn die Servos eh zusammen laufen ... warum nicht zusammen laufen lassen??
Also in EINER Schleife (wenn's schon eine Schleife sein muß ... millis() möchte dringend mit Dir reden, glaub mir)

MfG

glaub mir

Unser Philter wird entweder seine Einstellung ändern, oder sich ein anderes Hobby suchen.
Glaube mir!
:o :o :o :o

Ok, ich werde mich also doch mehr mit den millis beschäftigen müssen...
Ich glaube die werden mir noch einige Kopfschmerzen bereiten :wink:

Die Mobatools lib werde ich mir auf jedenfall mal angucken, aber mein Schwerpunkt wird wohl auf den millis liegen.

Danke für die ganzen Kommentare :slight_smile:

Ich glaube die werden mir noch einige Kopfschmerzen bereiten :wink:

Nur, wenn du dich innerlich dagegen sperrst.

Tipp:

Der Kopf ist rund,
damit das Denken die Richtung ändern kann.

Hallo,

Philter:
Ich denke mal ich hab irgendwo einen Denkfehler.

Servo L12 fährt einen Schritt (k++)
Servo L13 fährt einen Schritt (m++)
Servo L12 fährt einen Schritt (k++)
usw... bis L12 die Endposition 180 erreicht hat.

Ja ich glaube auch das Du nen Denkfehler hast. Sind die Servos mechanisch verbunden? zb: Pan Tilt Modul? Ich gehe jetzt mal davon aus, was bedeutet ein Servo fährt horizontal der andere vertikal.

Deine Doppelschleife 'sollte' dann folgendes machen:
Fährt nach links, dann vertiakl von unten nach oben.
Dann gehts einen Schritt richtung rechts weiter und der zweite Servo fährt wieder von unten nach oben.
Also Servo1 macht einen Schritt, Servo2 macht 180 Schritte, Servo1 macht einen weiteren Schritt usw.

Kann es sein das Du es so haben willst:
Bei einem Pan/Tilt Modul zB: in die rechte obere ecke fahren oder Servo1 macht einen Schritt, Servo2 macht einen Schritt dann wieder Servo1. Den so schaut es nach einer gleichzeitigen Bewegung aus.
Wenn ja, brauchst Du 2 Schleifen die nicht ineinander verschachtelt sind.

Vielleicht sagst Du uns Schrittweise was die Servos machen sollen?

Grüße,
Donny

Philter:
Ok, ich werde mich also doch mehr mit den millis beschäftigen müssen...
Ich glaube die werden mir noch einige Kopfschmerzen bereiten :wink:

Bevor's kronisch wird das Kopfweh, frag uns lieber um Hilfe.
Grüße Uwe

dony:
Servo1 macht einen Schritt, Servo2 macht einen Schritt dann wieder Servo1. Den so schaut es nach einer gleichzeitigen Bewegung aus.
Wenn ja, brauchst Du 2 Schleifen die nicht ineinander verschachtelt sind.

Vielleicht sagst Du uns Schrittweise was die Servos machen sollen?

Grüße,
Donny

Hallo Donny,
Was ein Pan/Tilt Modul ist weis ich nicht, aber ich benutze nur einen Mega und darauf einen selbstgemachen Shield.

Genau so sollte es werden.
Servo 1 startet bei 150
Servo 2 startet bei 140
Servo 1 -> 141
Servo 2 -> 151
Servo 1 -> 142
Servo 2 -> 152
usw bis 180

Die Servos sind so angeordnet: /°.

/ und \ sind die Beinteile. ° und . sind die Bewegungspunkte der Servos. Das /\ soll sich in ein || zusammenklappen. Hoffe es ist verständlich^^

combie:
Dann verlierst du aber m.
Musst dessen Definition also vor den Schleifen machen!

Das hatte leider nichts geändert..

hm, wenn der eine bei 140 anfängt und bis 180 gehen soll und
der andere erst bei 150 anfängt und bei 180 aufhört, sind die steps schonmal unterschiedlich.

Wären Sie gleich, wärs einfach:

for (int k = 140; k < 180; k++) {
    L12.write(k);
    L13.write(k);
    delay(10);
 }

oder soll es aufhören, wenn der erste den Wert 180 hat, dann ist aber der zweite erst bei 170!

for (int k = 150; k < 180; k++) {
    L12.write(k);
    L13.write(k-10);
    delay(10);
 }

Wenn Sie unterschiedlich schnell laufen sollen wirds halt ein bisschen mehr Rechnerei aber auch nicht viel anders.

Hi

Besagtes Pan/Tilt-Servo ist ein Plastik-Konstrukt, Welches zwei Servos aufnehmen kann - 1x Drehen, 1x Kippen.

WENN Du diese beiden Servos IMMER gleichzeitig und IMMER gleichsinnig ansteuern willst - packe Beide in die gleiche - von mir aus auch Schleife.
Da ein Servo aber einen größeren Verfahrweg hat - befürchte ich - wird Das dann auch nicht funktionieren.
(von dem Blockieren und dem ganzen Bäh-Kram ganz abgesehen).

Aber wie Es scheint, willst Du Das so - ohne millis und den ganzen anderen Kram, Der Dir schon seit gefühlten Wochen als Hilfestellung angeboten wird.

Nun denn - wird Dein Ding eben nicht laufen lernen, meinen Segen hast Du.

MfG

Philter:
Hallo Donny,
Was ein Pan/Tilt Modul ist weis ich nicht ...
Hoffe es ist verständlich^^ ...

Hallo,

Naja jetzt wurde ja bereits alles gesagt... So schaut ein Pan/Tilt Modul zB. aus.

Und wie bereits gesagt wurde musst Du in einem Schleifendurchgang beide Servos nacheinander drehen.

Grüße,
Donny

Wenn Sie unterschiedlich schnell laufen sollen

... dann ist die Frage nicht mit einer oder zwei for Schleifen zu beantworten, wenn diese die Geschwindigkeit per delay realisieren.

Hallo,

wenn sich das Trapez gleichmäßig zusammenklappen und öffnen soll, mit verschiedenen Servobewegungswinkel
140 ... 180
150 ... 180
dann muss zwangweise eine höhere Winkelauflösung her mit Fließkomma.
Sonst hast du immer Rundungsfehler, weil ein Servo sonst eher auf 180° steht wie das andere.
Fließkommawinkel gibt die Standardservo Lib allerdings nicht her.
Bsp. Servo 1 fährt mit 40 Unterteilungen von 140 auf 180, stellt sich immer genau 1° weiter.
Das 2. Servo bewegt sich aber nur von 150 zu 180. Es muss sich demzufolge mit 40 Unterteilungen immer nur um 0,75° weiterstellen. Sodass beide Servos zeitgleich starten und zeitgleich auf Ziel stehen. Das bekommt man nur mit Steuerung der direkten Pulsweite hin.

Warum sind die Winkelbereiche überhaupt unterschiedlich? Steht das Trapez bzw. die Beine nicht schief? Das nur am Rande gefragt.