hervorragend erklärt, kurz, prägnant - dank dafür...
hervorragend erklärt, kurz, prägnant - dank dafür...
gruß inka
ich bin jetzt noch einmal zurück zu der "normalen" steuerung der Stepper zurück, der code sieht nun so aus:
habe nicht alle funktionen hier reinkopiert, nur die für vorwärts:Code:#include <CustomStepper.h> #include <NewPing.h> #define TRIGGER_PIN 8 // Arduino pin tied to trigger pin on the ultrasonic sensor. //12 #define ECHO_PIN 7 // Arduino pin tied to echo pin on the ultrasonic sensor. //11 #define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. uint16_t distanz; uint16_t uS; //uint8_t hindernis, start_ping; CustomStepper stepper_HL(23, 25, 27, 29); CustomStepper stepper_VL(31, 33, 35, 37); CustomStepper stepper_HR(47, 49, 51, 53); CustomStepper stepper_VR(46, 48, 50, 52); boolean rotate_li; boolean rotate_deg_li; boolean rotate_re; boolean rotate_deg_re; boolean vorwaerts; boolean rueckwaerts; boolean start_ping; boolean hindernis; void setup() { rotate_li = false; rotate_deg_li = false; rotate_re = false; rotate_deg_re = false; vorwaerts = false; rueckwaerts = false; start_ping = false; hindernis = false; Serial.begin(115200); } void loop() { hindernis_vorh(); /****************************************/ if (stepper_VL.isDone() && rueckwaerts == false && hindernis == true) { alle_stepper_rueckwaerts(); //alle_stepper_stop(); } else if (stepper_VL.isDone() && rueckwaerts == false && hindernis == false) alle_stepper_vorwaerts(); /*************************************/ if (stepper_VL.isDone() && rueckwaerts == true && rotate_li == false) { rotieren_links(); } /**************************************/ if (stepper_VL.isDone() && rotate_li == true && vorwaerts == true) { alle_stepper_vorwaerts(); } /**********************************/ if (stepper_VL.isDone() && vorwaerts == true && rotate_re == false) { rotieren_rechts(); } /********************************/ if (stepper_VL.isDone() && rotate_re == true && vorwaerts == true) { alle_stepper_vorwaerts(); } /*****************************/ stepper_VL.run(); stepper_HL.run(); stepper_HR.run(); stepper_VR.run(); }
ping distanz:Code:void alle_stepper_vorwaerts() { vorwaerts = true; stepper_VL.setRPM(12); stepper_HL.setRPM(12); stepper_HR.setRPM(12); stepper_VR.setRPM(12); stepper_VL.setSPR(4075.7728395); stepper_HL.setSPR(4075.7728395); stepper_HR.setSPR(4075.7728395); stepper_VR.setSPR(4075.7728395); stepper_VL.setDirection(CW); stepper_VL.rotate(1); stepper_HL.setDirection(CW); stepper_HL.rotate(1); stepper_HR.setDirection(CW); stepper_HR.rotate(1); stepper_VR.setDirection(CW); stepper_VR.rotate(1); //vorwaerts = true; }
und der hindernis erkennung:Code:void ping_distanz(void) { delay(500);// Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. uS = sonar.ping(); // Send ping, get ping time in microseconds (uS). Serial.print("Ping: "); Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range) Serial.println(" cm"); start_ping = true; }
an und für sich funktioniert die hinderniserkennung, am start fährt der robby an, oder eben nicht (bei hindernis vorne)Code:void hindernis_vorh(void) { if (start_ping == false) ping_distanz(); if (((uS / US_ROUNDTRIP_CM) <= 10)) hindernis = true; }
wo es noch klemmt ist das mit den blockierenden funktionen für die stepper. Die reagieren also während der fahrt nicht auf hindernisse und das stört natürlich
mir ist es bis jetzt nicht gelungen das irgendwie zu lösen - hab ich da keine chance in diese blockierenden funktionen einzugreifen? Oder reicht es, wenn die ping funktion vor dem aufruf der stepperfunktion erfolgt? Irgendwie klappte es aber auch nicht...
Eine idee?
gruß inka
Du wirst aus dem Motorprogramm raus das Sonar auch abfragen müssen, oder?
Bau dir mal irgendeine Meldung in die entsprechenden Unterprogramme ein,die du auf die Konsole ausgeben lässt. Dann siehst du, ob die betreffenden Routinen überhaupt aufgerufen werden.
Grüssle, Sly
..dem Inschenör ist nix zu schwör..
ja sicher, hatte ich schon, habs aber bei meiner vorhergehenden frage nicht so explizit erwähnt...
Das hier ist nur eine alternative von vielen:
- beim start MIT hindernis davor fährt er sofort nach hinten los, ausgabe im terminal:Code:void alle_stepper_vorwaerts() { hindernis_vorh(); if (hindernis == true) { Serial.print("hindernisabfrage in - alle_stepper_vorwärts -"); alle_stepper_rueckwaerts(); } else alle_stepper_vorwaerts(); vorwaerts = true; stepper_VL.setRPM(12); stepper_HL.setRPM(12); stepper_HR.setRPM(12); stepper_VR.setRPM(12); stepper_VL.setSPR(4075.7728395); stepper_HL.setSPR(4075.7728395); stepper_HR.setSPR(4075.7728395); stepper_VR.setSPR(4075.7728395); stepper_VL.setDirection(CW); stepper_VL.rotate(1); stepper_HL.setDirection(CW); stepper_HL.rotate(1); stepper_HR.setDirection(CW); stepper_HR.rotate(1); stepper_VR.setDirection(CW); stepper_VR.rotate(1); //vorwaerts = true; } void alle_stepper_rueckwaerts() { Serial.print("fahre rückwärts nach hindernisabfrage in - alle_stepper_vorwärts -"); rueckwaerts = true; stepper_VL.setRPM(12); stepper_HL.setRPM(12); stepper_HR.setRPM(12); stepper_VR.setRPM(12); stepper_VL.setSPR(4075.7728395); stepper_HL.setSPR(4075.7728395); stepper_HR.setSPR(4075.7728395); stepper_VR.setSPR(4075.7728395); stepper_VL.setDirection(CCW); stepper_VL.rotate(1); stepper_HL.setDirection(CCW); stepper_HL.rotate(1); stepper_HR.setDirection(CCW); stepper_HR.rotate(1); stepper_VR.setDirection(CCW); stepper_VR.rotate(1); //rueckwaerts = true; }
- beim start OHNE ein hindernis davor bleibt er stehen, fährt also nicht nach vorne los, ausgabe im terminal:Code:Ping: 4 cm fahre rückwärts nach hindernisabfrage in - alle_stepper_vorwärts -
das ist die ausgabe von "ping_distanz", kommt ungefähr alle 8 sekunden...Code:Ping: 80 cm Ping: 79 cm Ping: 79 cm Ping: 79 cm
- wenn sich ihm in dieser phase ein hindernis von vorne nähert (handfläche) fährt er nach hinten los. Dann kommt im terminal:
ich schliesse daraus nur, dass er die freie strecke vor sich zwar erkennt, irgendwas hindert ihn aber daran die fahrbefehle in "alle_stepper_vorwaerts" auch auszuführen, er wartet nur (in etwas so lange, wie auch die fahrt dauern würde) und pingt...Code:Ping: 3 cm fahre rückwärts nach hindernisabfrage in - alle_stepper_vorwärts -
Timingprobleme?
gruß inka
Gut möglich.
Versuch mal, das Sonar zu Fuss zu programmieren, ohne die NewPing-Bibliothek.
Das Problem hat man bei Arduino recht oft, dass mehrere Bibliotheken sich da in die Quere kommen, weil irgendjemand Timer oder Interrupts einfach benutzt ohne zu fragen, und schlimmer: ohne es zu dokumentieren.
Du hast nicht allzu viele US-Sensoren dran, wenn du da nen halbwegs knapp bemessenes Timeout setzt, dann sollte sich die Verzögerung in Grenzen halten, du brauchst also die NewPing nicht unbedingt.
Grüssle, Sly
..dem Inschenör ist nix zu schwör..
der code mit NewPing war der erste, der bei mir auf anhieb funktionierte und auch die richtigen ergebnisse lieferte, da wollte ich natürlich dabei bleiben. Habe den code nun geändert
von:in:Code:void ping_distanz(void) { delay(500);// Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. uS = sonar.ping(); // Send ping, get ping time in microseconds (uS). Serial.print("Ping: "); Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range) Serial.println(" cm"); start_ping = true; }die daten bei der pindefinition und im setup natürlich angepasst. Die art des aufrufs der "ping_distanz" funktion erfolgt auf die gleiche art wie vorher....Code:void ping_distanz(void) { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = duration / 58, 1; //58.2 /52,3 delay(500); if (distance >= maximumRange || distance <= minimumRange) { Serial.println("-1"); } else { Serial.println(distance); } start_ping = true; }
Der neue code funktioniert nun wie der alte, im wahrsten sinne des wortes, das verhalten ist identisch...
noch eine idee?
gruß inka
Noch ne Idee: schreib mal in deinen Vergleichen TRUE statt true und FALSE statt false.
Das ist eigentlich eher üblich bei Arduino- und wird in den Beispielen immer so gemacht. K.A. obs nötig ist, probieren schadet nicht.
Da er scheinbar ja das erste "if" im Hauptprogramm abarbeitet, wärs denkbar....
Auch möglich: er verhaspelt sich in den If()'s irgendwo.
Wenn man mehrere if()-Entscheidungen hinter einander schreibt, werden die auch der Reihe nach abgearbeitet.
Wenn also if(1) zutrifft, wird sie abgearbeitet. Tritt dabei der Zustand auf, der bei if(2) TRUE geben wird, wird anschliessend die abgearbeitet, und so weiter. So kann man Endlosschleifen basteln, die schwer zu finden sind.
Da eben hilft es, in jedem if() einfach mal ne Ausgabe zu machen "ich bin hierund hier jetzt".
Sowas umgehe ich dann mit switch/case: dort wird nach jedem break alles von vorne begonnen!
Grüssle, Sly
..dem Inschenör ist nix zu schwör..
ein gutes neues jahr 2016 allen,
hallo botty,
Deinen erklärungen konnte ich folgen, danke...
irgendwie funktioniert bei mir die erkennung ob die Stepper mit der vorgesehen einen drehung fertig sind aber nicht und ich finde keinen unterschied zu Deinen codebeispielen in meinem loop:
hier noch die ausgabe im terminal, wie man sehen kann werden zwar die if abfragen mit "rotiere links" und "rotiere rechts" erreicht, die befehle selbst aber nicht ausgeführt, daraus würde ich schliessen, dass die Stepper eben noch nicht fertig sind?Code:void loop() { hindernis_vorh(); /****************************************/ for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (rueckwaerts == false && hindernis == true) { Serial.println("start - Stepper rückwärts- if-abfrage_1"); alle_stepper_rueckwaerts(); } else if (vorwaerts == false && hindernis == false) { Serial.println("start - Stepper vorwärts- else-abfrage_1"); alle_stepper_vorwaerts(); } } /*************************************/ for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (rueckwaerts == false && rotate_li == false) { Serial.println("loop - rotiere_links - if-abfrage_2"); rotieren_links(); } } for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (rotate_li == true && vorwaerts == false) { Serial.println("loop - alle_stepper_vorwärts - if-abfrage_3"); alle_stepper_vorwaerts(); } } for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (vorwaerts == true && rotate_re == false) { Serial.println("loop - rotiere_rechts - if-abfrage_4"); rotieren_rechts(); } } for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (rotate_re == true && vorwaerts == true) { Serial.println("loop - alle_stepper_vorwärts - if-abfrage_5"); alle_stepper_vorwaerts(); } } /*****************************************/ while ( ! (stepper[stepper_VL].isDone() && stepper[stepper_HL].isDone() && stepper[stepper_VR].isDone() && stepper[stepper_HR].isDone() ) ) { for (idx = stepper_VL; idx < stepper_MAX; idx++) { stepper[idx].run(); // delay(1); } } }
ergänze ich einer dieser if abfragen mit der afrage ob z.b. der "stepper_VL" fertig ist, wird der printbefehl auch übersprungen, die abfrage 2 also gar nicht ausgeführt...Code:setup_ende Ping: 83 cm start - Stepper vorwärts- else-abfrage_1 Ping: 71 cm loop - rotiere_links - if-abfrage_2 loop - rotiere_rechts - if-abfrage_4 loop - alle_stepper_vorwärts - if-abfrage_5 Ping: 82 cm loop - alle_stepper_vorwärts - if-abfrage_5 Ping: 82 cm
Code:for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (stepper[stepper_VL].isDone()) if (rueckwaerts == false && rotate_li == false) { Serial.println("loop - rotiere_links - if-abfrage_2"); rotieren_links(); } }
gruß inka
Ich versuche mich grad mal wieder am lesen von C-Code. Dabei tauchen Fragen auf, die eventuell den Weg zum Fehler weisen ...:
Warum wird der Funktionsaufruf "alle_stepper_vorwaerts();"in der Funktion hindernis_vorh() in eine for-Schleife über alle vorhandenen Stepper verpackt? Ist der Namensanteil "alle_..." irreführend? Ist im Augenblick nur ein Stepper dem Programm bekannt? Falls es mehrere sind - warum erscheint die serielle Ausgabe "start - Stepper vorwärts- else-abfrage_1" trotz Motor-unabhängiger boolescher Aussage nur ein einziges mal auf dem Terminal?
es sind vier stepper. "alle" im funktionsnamen deshalb, weil ja evtl. auch nur zwei laufen sollen...
es sind hier aufrufe zweier verschiedener funktionen:
1) hindernis_vorh() - prüft ob hindernis vorne (funktion selbst ist im codebeispiel nicht zu sehen - ist ausserhalb von loop())
2) in dieser schleife
wird eine andere funktion aufgerufen - alle_stepper_rueckwaerts() - wenn hindernis vorneCode:for (idx = stepper_VL; idx < stepper_MAX; idx++) { if (rueckwaerts == false && hindernis == true) { Serial.println("start - Stepper rückwärts- if-abfrage_1"); alle_stepper_rueckwaerts(); } else if (vorwaerts == false && hindernis == false) { Serial.println("start - Stepper vorwärts- else-abfrage_1"); alle_stepper_vorwaerts(); } }
oder alle_stepper_vorwaerts() - wenn kein hindernis
serial.print soll nur einmal melden wo man gerade ist...
und die funktionen "alle_stepper***" sind natürlich auch ausserhalb von loop()...
gruß inka
Lesezeichen