PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit der Accelstepper.h



jok3r
24.03.2014, 17:51
Ich suche schon ewig nach einem Fehler, in einem Programmabschnitt. Ich habe 4 Joysticks die mit denen ich 4 Schrittmotoren ansteuern kann, jetzt war es bisher so das die Schrittgeschwindigkeit extrem langsam war . Jetzt hab ich zu Versuchszwecke mal über diese Kette eine while(1) schleife gesetzt und siehe da alles funktioniert so wie es soll.

Problem ist das ich jetzt nicht mehr aus der schleife komme(ist ja logisch) und auch keine Bedingung dafür finde, das Verständnis zu den Erklärungen der Funktionen auf http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#a748665c3962e66fbc0e9373eb1 4c69c1 liegt auch nur bei 50%.

Kann mir mal wer erklären wieso es mit der while schleife zügig funktioniert und ohne nicht ? :(

void Joystick()
{


while(1)

{
int analog_in0 = (512 - analogRead(ANALOG_IN0));
int analog_in1 = (512 - analogRead(ANALOG_IN1));
int analog_in2 = (512 - analogRead(ANALOG_IN2));
int analog_in3 = (512 - analogRead(ANALOG_IN3));


int AN0, AN01;
int AN1, AN11;
int AN2, AN21;
int AN3, AN31;


//.......Stepper1..........//
if (analog_in0 >= 35 )
{
AN0 = exp(analog_in0 / 67);
stepper0.setSpeed(AN0) ;
stepper0.runSpeed();
}
else if (analog_in0 <= -35)
{
AN01 = exp(-analog_in0 / 67);
stepper0.setSpeed(-AN01) ;
stepper0.runSpeed();
}

//........Stepper2...........//
else if (analog_in1 >= 35 )
{
AN1 = exp(analog_in1 / 67 );
stepper1.setSpeed(AN1) ;
stepper1.runSpeed();
}
else if (analog_in1 <= -35)
{
AN11 = exp(-analog_in1 / 67 );
stepper1.setSpeed(-AN11) ;
stepper1.runSpeed();
}

//..........Stepper3..........//
else if (analog_in2 >= 35)
{
AN2 = exp (analog_in2 / 67);
stepper2.setSpeed(AN2) ;
stepper2.runSpeed();
}
else if (analog_in2 <= -35)
{
AN21 = exp (-analog_in2 / 67);
stepper2.setSpeed(-AN21) ;
stepper2.runSpeed();
}

//............Stepper4...........//
else if (analog_in3 >= 35 )
{
AN3 = exp (analog_in3 / 67);
stepper3.setSpeed(AN3) ;
stepper3.runSpeed();
}
else if (analog_in3 <= -35)
{
AN31 = exp (-analog_in3 / 67 );
stepper3.setSpeed(-AN31) ;
stepper3.runSpeed();
}

}
}


Gruß

Sisor
24.03.2014, 19:59
Aus der AccelStepper.h :

/// Poll the motor and step it if a step is due, implmenting a constant
/// speed as set by the most recent call to setSpeed().
/// \return true if the motor was stepped.
boolean runSpeed();

Auf deutsch: runSpeed() macht genau einen Step. Und nur dann, wenn eine bestimmte Dauer, die aus dem mit setSpeed() bekommenen Geschwindigkeitswert berechnet wird, überschritten wird.

Ergo: Du solltest die Funktion möglichst oft ausführen. Daher wäre es ratsam die Teachen_menue()-Funktion nur einmal auszuführen und um den Eintrag delay(500) zu erleichtern.

P.S.:Wenn du

... //........Stepper2...........//
else if (analog_in1 >= 35 )...
bzw. Stepper3, Stepper4 durch

...//........Stepper2...........//
if (analog_in1 >= 35 )...
ersetzt, hast du gleichberechtigte Joysticks. Z.Z. ist Joystick 1 sozusagen Master, d.h. wird er betätigt, wird auf die anderen nicht reagiert.

jok3r
24.03.2014, 20:29
Hab das Problem mit einer for Schleife gelöst :), alle 1000 Durchgänge wird Teaching_menue() aufgerufen.
Gibts noch elegantere Möglichkeiten ?
Und danke schon mal bzw wieder.
Die delay() im Teaching_menue hätte mir auch auffallen müssen.


Gruß

Sisor
24.03.2014, 21:19
Klar, du könntest eine 2.Funktion (z.B.void displayUpdate()) bauen, die nicht alles löscht und neu aufbaut, sondern nur die tatsächlichen Änderungen schreibt.

jok3r
24.03.2014, 21:29
Lieber nicht :D

jok3r
25.03.2014, 18:10
void Joystick(int x)
{

int analog_in0 = (512 - analogRead(ANALOG_IN0));
int analog_in1 = (512 - analogRead(ANALOG_IN1));
int analog_in2 = (512 - analogRead(ANALOG_IN2));
int analog_in3 = (512 - analogRead(ANALOG_IN3));


int AN0, AN01;
int AN1, AN11;
int AN2, AN21;
int AN3, AN31;


//.......Stepper1..........//
if (analog_in0 >= 35 )
{
AN0 = exp(analog_in0 / 67);
stepper0.setSpeed(AN0) ;
stepper0.runSpeed();
}
else if (analog_in0 <= -35)
{
AN01 = exp(-analog_in0 / 67);
stepper0.setSpeed(-AN01) ;
stepper0.runSpeed();
}

//........Stepper2...........//
if (analog_in1 >= 35 )
{
AN1 = exp(analog_in1 / 67 );
stepper1.setSpeed(AN1) ;
stepper1.runSpeed();
}
else if (analog_in1 <= -35)
{
AN11 = exp(-analog_in1 / 67 );
stepper1.setSpeed(-AN11) ;
stepper1.runSpeed();
}

//..........Stepper3..........//
if (analog_in2 >= 35)
{
AN2 = exp (analog_in2 / 67);
stepper2.setSpeed(AN2) ;
stepper2.runSpeed();
}
else if (analog_in2 <= -35)
{
AN21 = exp (-analog_in2 / 67);
stepper2.setSpeed(-AN21) ;
stepper2.runSpeed();
}

//............Stepper4...........//
if (analog_in3 >= 35 )
{
AN3 = exp (analog_in3 / 67);
stepper3.setSpeed(AN3) ;
stepper3.runSpeed();
}
else if (analog_in3 <= -35)
{
AN31 = exp (-analog_in3 / 67 );
stepper3.setSpeed(-AN31) ;
stepper3.runSpeed();
}


if (analog_in0 < -20 || analog_in0 > 20 || analog_in1 < -20 || analog_in1 > 20 ||analog_in2 < -20 || analog_in2 > 20 ||analog_in3 < -20 || analog_in3 > 20 )
{
return 1;
}


}

Stimmt das so ? Oben sollte jetzt beim bewegen eines Joysticks eine 1 in Joystick(int x) stehen bzw für x ?
Wobei void steht ja für keinen Wert .... normal schreibt man ja int main(void) oder int main (int x) .... wie sieht das beim Arduino aus ?
logisch wäre int Joystick(int x) oder ?

Sisor
25.03.2014, 19:24
Was vor dem Bezeichner (hier: Joystick) steht beschreibt den Rückgabedatentyp der Funktion. Void gibt keinen Wert zurück, double einen double etc. In den Klammern stehen die Eingangsdatentypen. Diese werden ihr zum Ausführungsbeginn mit übergeben. Es kann gar kein, ein oder mehrere Wert(e) verschiedener Datentypen übergeben werden.

jok3r
25.03.2014, 20:50
also dann zb "int Joystick(int x) " ?

Sisor
25.03.2014, 21:51
Wenn du dem Kompiler sagst, dass ein int zurückgegeben wird, musst du auch dafür sorgen, dass dies IN JEDEM FALL passiert.

...
if (analog_in0 < -20 || analog_in0 > 20 || analog_in1 < -20 || analog_in1 > 20 ||analog_in2 < -20 || analog_in2 > 20 ||analog_in3 < -20 || analog_in3 > 20 )
{
return 1;
}
else return 0;
Und du solltest darüber nachdenken, ob das int x in der Funktion gebraucht wird. Falls nicht, wäre int joystick() die richtige Wahl. Es ist im übrigen Programmierer-Konvention Funktionsbezeichner klein zu schreiben. Kein Muss, aber guter Stil.

jok3r
25.03.2014, 22:34
Ich hab das damals von C++ noch so in Erinnerung gehabt das ich immer (int x ) schreiben muss , weil sonst kann ich mit den rückgabewerten nichts anfangen (vergleichen ect.) ?

Sisor
26.03.2014, 06:37
jok3r

Ich hab das damals von C++ noch so in Erinnerung gehabt das ich immer (int x ) schreiben muss , weil sonst kann ich mit den rückgabewerten nichts anfangen (vergleichen ect.) ?

Das mag für Funktionen wie z.B.

int addiere (int a, int b)
{
return a+b;
} gelten.
Deine Funktion joystick() holt sich aber mit analogRead() Werte 'direkt' von der Hardware.

jok3r
26.03.2014, 16:04
Wieso wie macht das dann einen Unterschied ? Ich hab erfreuliche Ergebnisse, alles funktioniert soweit hin sehr gut .

Teaching Modus, Positionen Speed Delay Tool werden in einem Array[][] gespeichert .
Automatik Modus,alle Werte werden richtig zugeordnet und werden in eine For schleife abgefahren .
Jetzt wäre mir noch sehr wichtig das Delay ab dem Zeitpunkt beginnt zu laufen wenn alle Schrittmotoren stehen.
Daher habe ich eine If abfrage am schluss
int Stepper_routine()
{

stepper0.moveTo(Position[Pos_Display][0]);
stepper1.moveTo(Position[Pos_Display][1]);
stepper2.moveTo(Position[Pos_Display][2]);
stepper3.moveTo(Position[Pos_Display][3]);

stepper0.setSpeed(Position[Pos_Display][7]*100);
stepper1.setSpeed(Position[Pos_Display][7]*100);
stepper2.setSpeed(Position[Pos_Display][7]*100);
stepper3.setSpeed(Position[Pos_Display][7]*100);

stepper0.runSpeed();
stepper1.runSpeed();
stepper2.runSpeed();
stepper3.runSpeed();

if ( stepper0.runSpeed = 0 | stepper1.runSpeed = 0 | stepper2.runSpeed = 0 | stepper3.runSpeed = 0){
return 1;
}else {
return 0;
}

}

Die soll mir einen Wert liefern der im Betrieb die While schleife schließt -->
void Automatik()
{

static int PosWork = 0;



if (digitalRead(Taster1) == HIGH)
{

for (Pos_Display = 1; Pos_Display <= 5; Pos_Display++)
{

while (PosWork)
{


PosWork = Stepper_routine();




lcd.setCursor(5, 3); // Display Ausgabe
lcd.print(Position[Pos_Display][5]) ;
lcd.setCursor(14, 3);
lcd.print(Position[Pos_Display][4]);
lcd.setCursor(6, 2) ;
lcd.print(Position[Pos_Display][7]);
lcd.setCursor(16, 2);
lcd.print(Position[Pos_Display][6]);

delay(Position[Pos_Display][6] * 1000);
}


}


}


}



Leider läuft er jetzt nicht an , ich muss irgendwie davor in die schleife kommen ... nach 2 stunden bin ich nicht auf dem Fehler gekommen -.- . Gruß Dominik

Sisor
26.03.2014, 17:14
Ich werde den Code nicht genau analysieren, aber auf den ersten Blick fällt auf:

... wenn alle Schrittmotoren stehen.

if ( stepper0.runSpeed = 0 | stepper1.runSpeed = 0 | stepper2.runSpeed = 0 | stepper3.runSpeed = 0)...
Müsste aber:

if ( stepper0.runSpeed == 0 && stepper1.runSpeed == 0 && stepper2.runSpeed == 0 && stepper3.runSpeed == 0)...



stepper0.setSpeed(Position[Pos_Display][7]*100);
stepper1.setSpeed(Position[Pos_Display][7]*100);
stepper2.setSpeed(Position[Pos_Display][7]*100);
stepper3.setSpeed(Position[Pos_Display][7]*100);
Sicher, dass alle Stepper die gleiche Geschwindigkeit haben sollen?


lcd.setCursor(16, 2);
lcd.print(Position[Pos_Display][6]);
delay(Position[Pos_Display][6] * 1000);
Das würde ich mir auch noch einmal überlegen.

jok3r
26.03.2014, 18:35
Ja vorerst sollten sie die gleich Geschwindigkeit bekommen. Oh sry ja das wurde schon geändert es soll nicht Pos_Display sondern Delay_Display heißen.


zu
if ( stepper0.runSpeed == 0 && stepper1.runSpeed == 0 && stepper2.runSpeed == 0 && stepper3.runSpeed == 0)...

Die idee ist wenn einer der Schrittmotoren noch aktiv ist , dann soll die While schleife eine 1 erhalten ein verlassen sollte erst möglich sein wenn die Motoren stehen. Gruß

- - - Aktualisiert - - -

Laut Accel Stepper liefert Stepper0.runSpeed() --> eine 1 wenn er in Bewegung ist . Ich hab mir dabei gedacht das ich diese ein einfach abfragen kann in dem ich die Funktion mit etwas vergleiche .Sie liefert eine Boolean

Sisor
26.03.2014, 18:52
Die Aussage

wenn einer der Schrittmotoren noch aktiv ist , dann soll die While schleife eine 1 erhalten
als C-Code:


if (stepper0.runSpeed || stepper1.runSpeed || stepper2.runSpeed || stepper3.runSpeed) return 1;
else return 0;

oder umgedrehte Logik, identisches Ergebnis:

if (stepper0.runSpeed == 0 && stepper1.runSpeed == 0 && stepper2.runSpeed == 0 && stepper3.runSpeed == 0) return 0;
else return 1;

jok3r
27.03.2014, 21:40
ja stimmt schon hast recht ... es muss auch noch eine do while schleife werden , sonst komme ich nie rein . Gruß