Hallo, zur Zeit versuche ich mich an einem Roboter, welcher mit einem Ultraschallsensor ausgestattet ist und einfach nur Objekten ausweichen soll. Sowohl das Ansteuern meiner beiden Gleichstrommotoren mit einer H-Brücke als auch die Messung der Entfernung klappt problemlos. Allerdings schaffe ich es nun nicht, die Distanz zu messen und gleichzeitig die Motoren zu steuern. Ich möchte, dass der Roboter seine Richtung ändert, wenn in 50 cm Entfernung ein Objekt erkannt wird. Aber egal wie ich es versuche, irgendwie kommen die Delays sich immer gegenseitig in die Quere. Wie kann ich beispielsweise einen Motor für fünf Sekunden laufen lassen und gleichzeitig jede Sekunde die Entfernung messen?
Arduino schrieb: > Aber egal wie ich es versuche, irgendwie kommen die Delays welche Delays? Du musst dir eines immer verinnerlichen: Delays sind selten die Lösung, aber oft das Problem. Etwas weniger freundlich ausgedrückt: In dem Moment, in dem ein Programm bei dir Delays benutzt, hast du den falschen Programmansatz. > sich immer > gegenseitig in die Quere. Wie kann ich beispielsweise einen Motor für > fünf Sekunden laufen lassen und gleichzeitig jede Sekunde die Entfernung > messen? Wenn man 5 mal 1 Sekunde wartet, hat man in Summe auch 5 Sekunden gewartet. Der Unterschied: Bei 5 mal 1 Sekunde warten, kann ich immer wieder schnell mal was dazwischen schieben. Wenn ich hingegen 5 Sekunden am Stück warte, kann ich in der Zwischenzeit nichts tun. Aber eigentlich ist es der falsche Ansatz. Zeitsteuerungen laufen (bis auf ganz kurze Zeiten) praktisch immer über den Einsatz eines oder mehrerer Timer. Ich verstehe, dass man als Anfänger nicht gleich alles auf einmal kann. Aber irgendwann muss man dann auch die Simpel-Anfänger Schiene verlassen und sich ansehen, wie man solche Dinge richtig macht. Denn der Delay Ansatz ist ausser für ganz einfache Sachen nicht tragfähig genug.
Arduino schrieb: > Wie kann ich beispielsweise einen Motor für > fünf Sekunden laufen lassen und gleichzeitig jede Sekunde die Entfernung > messen? Indem du jede Sekunde die Entfernung misst und nachguckst, ob schon 5 Sekunden rum sind. Arduino schrieb: > irgendwie kommen die Delays sich immer > gegenseitig in die Quere. Nimm einen Timer!
Arduino schrieb: > Wie kann ich beispielsweise einen Motor für > fünf Sekunden laufen lassen und gleichzeitig jede Sekunde die Entfernung > messen? Da gibt es mehrere Möglichkeiten: Zustandsautomat oder Timer. Einfacher wird es sicherlich, wenn man den Sensor in einer WHILE-Schleife abfragt und den Roboter so lange fahren lässt bis der Sensor ausschlägt.
Leander B. schrieb: > Einfacher wird es sicherlich, wenn man den Sensor in einer > WHILE-Schleife abfragt und den Roboter so lange fahren lässt bis der > Sensor ausschlägt. Erstmal danke an alle für die fixe Hilfe. :) https://www.arduino.cc/en/Tutorial/MultipleBlinks So in etwa?
Arduino schrieb: > https://www.arduino.cc/en/Tutorial/MultipleBlinks > > So in etwa? Benutzt du einen Due?
Arduino schrieb: > Aber egal wie ich es versuche, irgendwie kommen die Delays sich immer > gegenseitig in die Quere. Wie du schon gemerkt hast, sind Delays eigentlich der falsche Ansatz. Besser wäre ein fester Zeittakt und eine Statussteuerung, z.B. bei jedem Takt den Abstand messen, Motor bei Bedarf anschalten und fünf Takte später wieder ausschalten. > Wie kann ich beispielsweise einen Motor für fünf Sekunden laufen lassen > und gleichzeitig jede Sekunde die Entfernung messen? Solange nicht mehr als das passieren soll, wird es wohl auch mit deinen geliebten Delays funktionieren, wenn du - Motor anschaltest - 5 mal { Messen und eine Sekunde wartest} - Motor ausschaltest
Leander B. schrieb: > Benutzt du einen Due? Ops, nein. Ich benutze einen Uno. Gibt es so etwas auch für den Uno?
Arduino schrieb: > https://www.arduino.cc/en/Tutorial/MultipleBlinks > > So in etwa?
1 | This is a cooperative scheduler in that the CPU switches from one task to another. |
Auch da wirst du mit deinen Delays nicht glücklich werden. Du kannst es drehen und wenden wie du willst. Du wirst nicht umhin kommen, die richtige Technik zu lernen. Zumal das am Arduino gar nicht so schwer ist. https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay Und welche Büchse der Pandorra du dir mit Multitasking aufmachst, kannst du mit deinem jetzigen Kentnisstand noch gar nicht abschätzen. Auch wenn immer wieder das Gegenteil behauptet wird: Auch ein Arduino ist kein Wunderwuzzi, der einem das Lernen der richtigen Techniken abnimmt. Bis zu einem gewissen Grad kann man sich durchwurschteln. Aber früher oder später ist dann das Ende der Fahnenstange erreicht. Meistens früher.
Karl H. schrieb: > Du kannst es drehen und wenden wie du willst. Du wirst nicht umhin > kommen, die richtige Technik zu lernen. Ich versuche ja auch gar nicht drumherum zu kommen. Ich bin halt jetzt an einem Punkt, an dem es mit Delays nicht mehr geht und dann muss ich mir eben was neues angucken. Ich wusste halt nur noch nicht genau, was ich nun brauche. Könnte ich es auch so machen wie hier? http://www.duino-robotics.com/james.html Mit dieser Void funktion?
Arduino schrieb: > Könnte ich es auch so machen wie hier? Wer oder was hindert dich daran, das auszuprobieren und den Code zu studieren wie er funktioniert? Gewöhn dich daran. Wenn du bei der Programmierung bleibst, dann wirst du noch viiiiiiel fremden Code studieren um rauszufinden, wie er funktioniert. Manches davon wird guter Code sein, manches schlechter Code. Und du wirst lernen das eine vom anderen zu unterscheiden.
Das Prinzip ist einfach. Du baust Dir eine TimerIRQ. die z.B. alle 10ms aufgerufen wird. Innerhalb dieser IRQ baust Du dir verschiedene flags die z.B. bei 100ms, 1Sek. 10Sek. oder was auch immer gesetzt werden. In der main() schaust Du ob das flag gesetzt ist das Dich interessiert. Z.B. das flag für 1sek. ist abgelaufen. Du führst also den Programmteil aus der jede Sekunde laufen soll und setzt danach das flag zurück. In Deinem Fall würde so jede Sekunde die Entfernung gemessen und der Motor solange laufen bis Du 5 mal durch diesen Programmteil gelaufen bist. Für meinen STM8 sieht das z.B. so aus:
1 | void T4_IRQ(void) |
2 | {
|
3 | static u8 count_10ms = 10; |
4 | static u8 count_100ms =10; |
5 | static u8 count_1s=10; |
6 | |
7 | TIM4_ClearITPendingBit(TIM4_IT_UPDATE); |
8 | SYSTIC_1ms = true; |
9 | if (count_10ms) --count_10ms; |
10 | else { |
11 | count_10ms = 10; |
12 | SYSTIC_10ms = true; |
13 | if (count_100ms) --count_100ms; |
14 | else{ |
15 | count_100ms = 10; |
16 | SYSTIC_100ms = true; |
17 | if (count_1s) --count_1s; |
18 | else{ |
19 | count_1s = 10; |
20 | SYSTIC_1s = true; |
21 | }
|
22 | }
|
23 | }
|
24 | }
|
Von Adafruit gibt es ein sehr schönes Tutorial für ein sehr einfach gehaltenes kooperatives Multitasking: https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.