Du kannst deine If()'s ja mal debuggen: schreib einfach in jedes if() ne spezielle Ausgabe und lass dir die auf die Konsole geben. Ggf. zusammen mit nen paar Variablen. Dann siehst du ja, wo er eventuell hängen bleibt.
Druckbare Version
Du kannst deine If()'s ja mal debuggen: schreib einfach in jedes if() ne spezielle Ausgabe und lass dir die auf die Konsole geben. Ggf. zusammen mit nen paar Variablen. Dann siehst du ja, wo er eventuell hängen bleibt.
Hallo inka,
mir fallen mehrere Sachen in Deinen Beispielen auf.
Erstmal konkurieren die "run()" Aufrufe damit die Motoren laufen mit Deinen Aufrufen für die Sensormessungen.
Egal welche Variante der Sensormessungen die Du uns gezeigt hast, beide blockieren den Rest des Systems während der Messung, weil Du auf das Ergebnis wartest. Und nicht nur das, Du hast die Sache noch verschärft, da in den Funktionen "delay(500)" drin steht. Sprich jedes Mal wenn Du die Messfunktion aufrufst vergehen 1/2sec plus der Zeit für die Messung. Deine Stepper könnten also gerade mal einen Step/sec machen.
Sicher nicht was Du willst. Die Messfunktion muss also so geschrieben sein, daß sie nicht blockiert. Die NewPing-Lib kann das s.u.
Die andere Sache, womit der Code klarer werden würde, ist die Verwendung von zwei Schleifen in der Loop-Funktion. Die äußere Schleife sorgt für den Fortschritt Deiner Fahrkommandos und die innere Schleife führt sie aus. In Pseudocode sähe das in etwa so aus (hab's nicht durch den Compiler gejagt!):
wie immer Du die Auswahl der Fahrkommandos organisierst, hast Du so eine klare Trennung zwischen Auswahl und Ausführung!Code:void loop() {
while(1) {
// Kommando auswählen
// Motoren konfigurieren z.B.
geradeaus_unendlich();
do {
// Fortschritt der Motoren
stepper_VL.run();
stepper_HL.run();
stepper_HR.run();
stepper_VR.run();
// Bis die Aufgabe erledigt ist
} while ( ! (stepper_VL.isDone() && stepper_HL.isDone() && stepper_VR.isDone() && stepper_HR.isDone()) );
}
}
Jetzt weiß ich nicht was Dein Roboter alles können soll. Ich nehme hier mal an er soll immer geradeaus fahren und wenn ein Hinderniss erkannt wird nach Rechts drehen. Beim Drehen soll er den Sensor ignorieren. Dann erweitert sich das Bsp. so:
Die NewPing-Lib stellt Dir die Funktion "ping()" zur Verfügung, leider blockiert die das System, kommt also nicht in Frage.Code:void loop() {
bool sensor_benutzen = true;
while(1) {
// Kommando auswählen
// Motoren konfigurieren z.B.
geradeaus_unendlich();
sensor_benutzen = true;
do {
if(sensor_benutzen && hindernis_vorh()) {
motoren_stop();
drehen_rechts(); // Konfiguriert die Motoren um und wird so lange
// ausgeführt bis die innere Schleife abbricht.
sensor_benutzen = false;
}
// Fortschritt der Motoren
stepper_VL.run();
stepper_HL.run();
stepper_HR.run();
stepper_VR.run();
// Bis die Aufgabe erledigt ist
} while ( ! (stepper_VL.isDone() && stepper_HL.isDone() && stepper_VR.isDone() && stepper_HR.isDone()) );
}
}
Statt dessen müssen wir "ping_timer()" und "check_timer()" benutzen.
"hindernis_vorh()" soll uns immer den letzten gültigen Wert liefern und dafür sorgen, daß der Sensor immer wieder neu mißt.
Also gibt uns die Funktion einen bool zurück:
wir müssen uns merken ob der Sensor läuft "sensor_misst" und was das letzte Ergebnis war "erg_vorher", beide sollen nur lokal sichtbar sein. Ausserdem sollen die Werte erhalten bleiben, sprich die Variablen dürfen nicht auf dem Stack liegen sondern müssen ins Datensegment. Dafür gibt's "static".Code:bool hindernis_vorh() {
}
Dann brauchen wir eine Dummy Funktion,weil "ping_timer()" 'nen Funktionspointer als Argument haben will.
Das Ganze sollte dann so aussehen (nicht durch den Compiler gejagt!):
jetzt läßt sich "hindernis_vorh()" immer wieder aufrufen und startet den Sensor immer wieder neu und liefert das letzte Ergebnis zurück.Code:void sonarDummyFunc() { return; }
bool hindernis_vorh() {
static bool sensor_misst = false; // Beim Prg Start läuft der Sensor noch nicht
static bool erg_vorher = false; // Beim Start noch keine Messung vorhanden
if(sensor_misst) {
if(sonar.check_timer()) {
erg_vorher = (sonar.ping_result / US_ROUNDTRIP_CM) < 4; // Oder welche Entfernung auch immer
sensor_misst = false;
}
} else {
sonar.timer_stop();
sonar.ping_timer(sonarDummyFunc);
sensor_misst = true;
}
return erg_vorher;
}
Ein anderes Beispiel findest Du sonst noch https://bitbucket.org/teckel12/ardui...ping/wiki/Home in der Mitte ist ein Beispiel das den Callback-Mechanismus benutzt aber eine globale Variable verwendet,wovon ich kein Freund bin.
Hoffe die Ideen bringen Dich ein bischen weiter.
Gruß
Chris
Hallo inka,
solltest Du momentan diese Variante
im Einsatz haben, landest Du für den Fall das kein Hindernis erkannt wird in einer endlos Rekursion. Dein Program hängt sich schlicht auf und ich vermute das System rebootet immer wieder. Prüfen könntest Du das, wenn Du in die setup-Funktion am Ende mal ein "Serial.println("setup ende")" oder so schreiben würdest. Das sollte dann mehrfach in der Console zwischen den "Ping: xxx cm" erscheinen.Code:void alle_stepper_vorwaerts()
{
hindernis_vorh();
if (hindernis == true)
{
Serial.print("hindernisabfrage in - alle_stepper_vorwärts -");
alle_stepper_rueckwaerts();
}
// !!! Im Fall das hinderniss == false ist führt das zu einer Rekursion ohne Widerkehr !!!
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;
}
Falls Du noch die NewPing lib benutzt gibt es bei "ping()" einen Sonderfall zu berücksichtigen:
Wenn der US-Sensor ins Unendliche zeigt, liefert die Funktion eine Null zurück. In Deiner Funktion:
kann "hindernis" also auch "true" sein. Daher muß eine weitere Abfrage da hinein:Code:void hindernis_vorh(void)
{
if (start_ping == false) ping_distanz();
if (((uS / US_ROUNDTRIP_CM) <= 10))
hindernis = true;
}
meine Funktion funktionert so leider auch nicht. Weil mir "check_timer()" bei einem Blick hinter die Sensorreichweite keine Info darüber gibt, dass ein Time-Out stattgefunden hat. Muss man sich also selbst merken.Code:void hindernis_vorh(void)
{
if (start_ping == false) ping_distanz();
if(uS > 0) {
if (((uS / US_ROUNDTRIP_CM) <= 10))
hindernis = true;
} else {
hindernis = false;
}
}
GrußCode:void sonarDummyFunc() { return; }
bool hindernis_vorh() {
static bool sensor_misst = false; // Beim Prg Start läuft der Sensor noch nicht
static bool erg_vorher = false; // Beim Start noch keine Messung vorhanden
static unsigned long start_zpkt = 0; // Fuer's timeout
if(sensor_misst) {
if(sonar.check_timer()) {
erg_vorher = (sonar.ping_result / US_ROUNDTRIP_CM) <= 10; // Oder welche Entfernung auch immer
sensor_misst = false;
} else if( (start_zpkt - millis()) >= 50 ) { // Falls Distanz hinter Sensorreichweite,
// nach 50ms erneut messen ermöglichen.
erg_vorher = false;
sensor_misst = false;
}
} else {
sonar.timer_stop();
sonar.ping_timer(sonarDummyFunc);
sensor_misst = true;
start_zpkt = millis();
}
return erg_vorher;
}
Chris
hallo botty,
nein habe ich nicht...
habe ich berücksichtigt, danke für den tipp...
- - - Aktualisiert - - -
hi botty,
ich habe jetzt eine einigermassen funktionierende version in der ich ein paar sachen die Du hier erwähnst auch schon drin habe:
- das delay(500) im ping distanz habe ich entfernt, geht auch ohne
- die schleife do - while bei dem run() der stepper habe ich eingefügt, meine aber das wäre doppelt gemoppelt hier, oder?
der roboter:
- prüft erstmal ob vor ihm ein hindernis ist
- fährt entsprechend nach vorne, oder zurück
- nach vorne arbeitet er die (zunächstmal vorgegeben kommandor links, rechts usw) ab
- nach hindernis wird immer nur im voraus geprüft, ausgewichen nach links (warum auch immer)
hier der code (habe auch einen ohne "enum, idx" und was sonst noch zu der elegenteren lösung gehört :-)"
hier stellt sich mir die frage warum ist es ein problem, wenn - hier sogar beide wesentlichen funktionen - ping() und run() der stepper blockierend sind? Der roboter fährt, sogar recht zügig, misst zwischendurch und weicht auch hindernissen aus, wo ist das problem? Kannst Du es mir bitte erklären?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.
uint8_t idx;
uint16_t distanz;
uint16_t uS;
//uint8_t hindernis, start_ping;
enum stepper_e
{ stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX };
CustomStepper stepper[stepper_MAX]
{
CustomStepper(23, 25, 27, 29),
CustomStepper(31, 33, 35, 37),
CustomStepper(47, 49, 51, 53),
CustomStepper(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;
boolean stepper_stop;
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;
stepper_stop = false;
Serial.begin(115200);
Serial.println("setup_ende");
}
void loop()
{
hindernis_vorh();
/****************************************/
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
if (stepper[idx].isDone() && rueckwaerts == false && hindernis == true)
{
Serial.println("start - stepper rückwärts- if-abfrage_1");
alle_stepper_rueckwaerts();
}
else if (stepper[idx].isDone() && 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 (stepper[idx].isDone() && rueckwaerts == true && rotate_li == false)
{
Serial.println("loop - rotiere_links - if-abfrage_2");
rotieren_links();
}
}
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
if (stepper[idx].isDone() && 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 (stepper[idx].isDone() && vorwaerts == true && rotate_re == false)
{
Serial.println("loop - rotiere_rechts - if-abfrage_4");
rotieren_rechts();
}
}
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
if (stepper[idx].isDone() && rotate_re == true && vorwaerts == true)
{
Serial.println("loop - alle_stepper_vorwärts - if-abfrage_5");
alle_stepper_vorwaerts();
}
}
/*****************************************/
do
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
}
} while ( ! (stepper[idx].isDone()));
}
/***********************************************************/
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;
}
void hindernis_vorh(void)
{
if (start_ping == false) ping_distanz();
if (uS > 0)
{
if (((uS / US_ROUNDTRIP_CM) <= 10))
hindernis = true;
} else
{
hindernis = false;
}
}
void alle_stepper_stop()
{
stepper_stop = true;
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(0);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(STOP);
}
}
void alle_stepper_vorwaerts(void)
{
if (start_ping == true) ping_distanz();
//Serial.print(hindernis);
if (hindernis == true)
{
rueckwaerts = true;
Serial.print(hindernis);
Serial.println(" hindernis - true - alle_stepper_rückwärts - if-abfrage_6");
hindernis = false;
//alle_stepper_rueckwaerts();
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
}
else
{
vorwaerts = true;
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CW);
stepper[idx].rotate(1);
}
}
}
void alle_stepper_rueckwaerts(void)
{
rueckwaerts = true;
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
}
void rotieren_links(void)
{
rotate_li = true;
for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CW);
stepper[idx].rotate(1);
}
}
void rotieren_rechts(void)
{
rotate_re = true;
for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CW);
stepper[idx].rotate(1);
}
for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
}
In einem würde ich Dir recht geben: Der roboter fährt nach der messung seine strecke die er vorgegeben bekommen hat noch ab, bleibt also noch der fsetstellung - da vorne ist ein hindernis - nicht sofort stehen. Das kann man aber über die gemessene entfernung lösen, oder?
das muss ich noch lesen...
Grüß Dich inka,
ich fange mal Hinten an.
"ping()" würde "run()" blockieren, nicht umgekehrt. die "run()" Funktionen müssen nachdem die Stepper konfiguriert sind immer wieder aufgerufen werden und das so schnell wie möglich, sonst hakt es.
Sowie Du Dein Programm aufgebaut hast, gibt's zwei kritische Dinge zu beachten:
Nachdem Du "gepingt" hast, fährst Du los. Wenn jetzt plötzlich etwas vor dem Roboter auftaucht - Eure Katze, Deine Füße oder die Schienbeine Deiner Liebsten - bekommt das das System nicht mit, sondern fährt einfach weiter - schlimmstenfalls "Aua" ;) .
Das andere Problem hast Du schon richtig erkannt, die gemessene Distanz vom Sensor muss größer sein als der Fahrweg.
Du legst im Moment bei gerade Fahren immer eine Umdrehung zwischen den "pings" zurück. Dein Grenzwert zum potentiellen Hinderniss sind aktuell 10cm. Das ist zu wenig, denn ich schätze Dein Raddurchmesser wird größer als 10cm/pi sein, oder?
Rechne mal nach Raddurchmesser * pi - dann muss "hindernis_vorh()" so aussehen:
eine weitere Möglichkeit wäre statt "rotate(1)" "rotateDegrees(180)" oder mit anderen Werten kleinere Schritte zu machen. Das könnte dann zum Stottern führen. Momentan, vermute ich, bewegt die Trägheit den Robbi während des "pings" weiter, so das man das mit bloßem Auge nicht wahr nimmt. Einfach mal kleinere Werte mit "rotateDegrees()" ausprobieren.Code:{
if (start_ping == false) ping_distanz();
if(uS != NO_ECHO)
{
/* richtige Werte einsetzen */
if (((uS / US_ROUNDTRIP_CM) <= (Raddurchmesser * M_PI))
hindernis = true;
} else {
hindernis = false;
}
}
Zum Thema "do{...}while()" und "doppelt gemoppelt":
Deine "loop()" sah auszugsweise so aus:
Du testes zwangsweise am Anfang immer ab, ob die Stepper schon das letzte Kommando ausgeführt haben oder nicht.Code:void loop() {
if (stepper[idx].isDone() && rueckwaerts == false && hindernis == true)
{
Serial.println("start - stepper rückwärts- if-abfrage_1");
alle_stepper_rueckwaerts();
}
else if (stepper[idx].isDone() && vorwaerts == false && hindernis == false)
{
Serial.println("start - stepper vorwärts- else-abfrage_1");
alle_stepper_vorwaerts();
}
// andere if's
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
}
}
Dadurch mischt Du inhaltlich "Sind die Stepper fertig?" mit "Wie wähle ich das nächste Kommando aus?".
Führst Du jetzt die innere Schleife ein egal ob "while(){}" oder "do{...}while()":
dann ist nach der inneren Schleife und vor dem nächsten "loop()" Ablauf absolut sicher, dass die Stepper ihre angewiesene Arbeit getan haben.Code:void loop() {
// Kommando Auswahl treffen
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();
}
// andere if's
// Stepper ausführen lassen
// Es muessen alle Stepper gleichzeitig getestet werden, sonst ist's falsch!
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();
}
}
}
Dadurch reduzieren sich Deine "if()" Ausdrücke, die sich nur noch mit der Auswahl beschäftigen und sind meiner Meinung nach einfacher lesbar.
Das Konzept der CustomStepper-Lib basiert darauf 1) die Stepper zu konfigurieren was sie tun sollen "rotate()", "setDirection()" etc. und dann 2) sie solange mit "run()" in Schwung zu halten, bis "isDone()" wahr wird. Genau das spiegelt sich in letzterem Aufbau wieder.
Ich hoffe ich hab's verständlich erklärt?
Gruß
Chris
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();
}
}
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()...
OK, bei "hindernis_vorh();"hab ich übersehen, dass das der Aufruf einer Funktion ist und das Nachfolgende weiterer Code.
Trotzdem:
Dann müssten es angesichts der for-Parameter dennoch vier Schleifendurchläufe und vier serielle Meldungen werden, oder ??
We das? Es wird doch viermal aufgerufen, oder? Das ist ja mein Zweifel, ob an dieser Stelle der Programmfluss anders als gewünscht verläuft.
Ich gestehe, dass ich nicht heimisch bin in diesem Thread und deinen Arbeiten. Ich hab halt mal versucht, den gelieferten Programmausschnitt auf Auffälligkeiten hin zu studieren.
Wenn ich hier neben der Spur sein sollte, darfst du gerne deine Zeit sparen und meine Beiträge ignorieren.
jetzt hast Du mich etwas verunsichert (ist nicht schwierig :-))...
hier in diesem
springt er hierhin:Code: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(); <-----hier
}
else if (vorwaerts == false && hindernis == false)
{
Serial.println("start - stepper vorwärts- else-abfrage_1");
alle_stepper_vorwaerts();
}
}
und dann wieder, nach dem er diese funktion abgearbeitet hat, zurück, ignoriert die else-if abfrage und geht weiter. Und muss die schleife noch 3x durchlaufen?Code:void alle_stepper_rueckwaerts(void)
{
rueckwaerts = true;
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
}
void rotieren_links(void)
{
rotate_li = true;
for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CCW);
stepper[idx].rotate(1);
}
for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].setRPM(12);
stepper[idx].setSPR(4075.7728395);
stepper[idx].setDirection(CW);
stepper[idx].rotate(1);
}
}
Die serialprint meldung kommt wirklich nur einmal! ich muss es noch ohne die schleife mit den "idx" testen...