Go Down

Topic: [Projekt] xyz Portal für ein Strömungs-Messsystem (Read 819 times) previous topic - next topic

100-200-00

Hallo,

In meinem Projekt habe ich die Aufgabe die Steuerung für ein xyz Portal zu programmieren. Hierzu werden 3 Stepper Motoren eingesetzt, je ein Motor pro Achse.

Da es sich hier nicht um eine CNC Maschine handelt, spielen große Beschleunigungen & Geschwindigkeiten keine große Rolle. Das Portal soll eine Punktewolke (Quader) abrastern, dh. Punkt anfahren, messen/warten, nächsten Punkt anfahren etc...

Da ich bisher noch nie ernsthaft programmiert habe, bin ich daher auf Hilfe angewiesen :)

Für das Projekt gibt es bereits einen fertigen, funktionierenden Sourcecode, dieser ist allerdings nicht "schön" und soll daher neu geschrieben werden.

Als Libraries möchte ich die AccelStepper.h (+ MultiStepper.h) verwenden (im alten Sourcecode bereits verwendet).

So, nun zum ersten Problem:

Ich habe eine Funktion geschrieben, die eine Koordinate ansteuern soll. Das Problem ist, dass nach erreichen der Position der Befehl
Code: [Select]
x_Stepper.moveTo(x) (gleiches gilt analog für y und z) nicht mehr ausgeführt werden soll. Sobald die Motoren sich nicht mehr bewegen
Code: [Select]
x_Stepper.distanceToGo() == 0, werden die Variablen auf die neue Position gesetzt:
Code: [Select]
actual_x = x;
actual_y = y;
actual_z = z;

Leider sind die Werte aber nach erneutem Aufruf der while Schleife immer noch auf dem alten Stand(0,0,0) gesetzt. Wieso? Anbei der bisherige Code:
 

Code: [Select]

#include "AccelStepper.h"

AccelStepper x_Stepper(1, 10, 7);
AccelStepper y_Stepper(1, 9, 6);
AccelStepper z_Stepper(1, 8, 5);

//global variables

// Set stepper speeds and acceleration
int x_speed = 10;
int y_speed = 10;
int z_speed = 10;
int x_acc = 10;
int y_acc = 10;
int z_acc = 10;

// Actual stepper positions
int actual_x ;
int actual_y ;
int actual_z ;

// Target for stepper positions
int target_x ;
int target_y ;
int target_z ;

// debug variable; set to false for faster movement
boolean debug = true;
int debug_delay = 500; //delay for each debug message in ms

//declaration of functions: do i really need this declaration?
boolean positioning(int x, int y, int z);
void debugging(int i);
void test_function1();


void setup() {
Serial.begin(9600);
// Accelstepper settings
x_Stepper.setMaxSpeed(x_speed);
x_Stepper.setAcceleration(x_acc);
y_Stepper.setMaxSpeed(y_speed);
y_Stepper.setAcceleration(y_acc);
z_Stepper.setMaxSpeed(z_speed);
z_Stepper.setAcceleration(z_acc);
pinMode(13, INPUT);
pinMode(12, INPUT);
pinMode(11, INPUT);
// Stepper enable pins
x_Stepper.setEnablePin(13);
y_Stepper.setEnablePin(12);
z_Stepper.setEnablePin(11);

}

void loop() {
test_function1();
}

//functions


boolean positioning(int x, int y, int z) {
/*
This function will position the system to the committed/target coordinates x, y, z.
The coordinates have to be submitted in STEPS.
If the coordinates are reached, the function will return true.
*/
debugging(100);
while (actual_x != x && actual_y != y && actual_z != z) { // Checks, if the system is already at the target coordinates
debugging(101);
/*
If the target coordinates are not reached, each coordinate is tested separately.
If the Stepper is not at the target coordinate AND is not moving,
he gets the command to move his ass
*/

if (actual_x != x && x_Stepper.isRunning() == false) //coordinate x
{
x_Stepper.moveTo(x);
debugging(102);
}

if (actual_y != y && y_Stepper.isRunning() == false) //coordinate y
{
y_Stepper.moveTo(y);
debugging(103);
}

if (actual_z != z && z_Stepper.isRunning() == false) //coordinate z
{
z_Stepper.moveTo(z);
debugging(104);
}

if (x_Stepper.distanceToGo() == 0 && y_Stepper.distanceToGo() == 0 && z_Stepper.distanceToGo() == 0) {
/*
If the distance between each stepper and his coordinate is 0,
we assume that the target has been reached. Therefore, the actual
coordinates are set to the target coordinates.
*/
actual_x = x;
actual_y = y;
actual_z = z;
debugging(105);
return true;
}
x_Stepper.run();
y_Stepper.run();
z_Stepper.run();
}
}

void debugging(int i){
/*
This function will give a debug message (if debug is true), depending of the given codenumber i.
The debug codes go from 100-999. A debug message always begins with "DEB: "
*/
if (debug) {
if (debug_delay > 0)
{
delay(debug_delay);
}

switch(i){
default:    Serial.println("DEB: unknown command");
break;
case     0: Serial.println("DEB: enter void loop");
break;
case   100: Serial.println("DEB: enter function: positioning");
break;
case   101: Serial.println("DEB: enter while (positioning)");
break;
case   102: Serial.println("DEB: send coordinate to x_Stepper");
break;
case   103: Serial.println("DEB: send coordinate to y_Stepper");
break;
case   104: Serial.println("DEB: send coordinate to z_Stepper");
break;
case   105: Serial.println("DEB: reached target position");
break;
}
}
}


void test_function1(){
debugging(0);
actual_x = 0;
actual_y = 0;
actual_z = 0;
positioning(30, 40, 50);
Serial.println("position reached");
delay(1000);

}







mkl0815

Du rufst die Funktion test_function1() innerhalb der Funktion loop() auf. Diese Funktion hat, daher auch der Name, die Aufgabe solange der Arduino läuft immer wieder durchlaufen zu werden.
Damit wird auch immer wieder die Funktion test_function1() aufgerufen und diese setzt die Werte für
   actual_x = 0;
   actual_y = 0;
   actual_z = 0;
immer wieder auf 0 gesetzt. Lass diese Initialisierung mal in der Funktnio weg und setze die bei der Deklaration der Variablen am Anfang des Programms oder von mir aus in der setup() Funktion, die wird nämlich nur einmal beim Start ausgeführt.

Mario.

100-200-00

Hach, manchmal sieht man den Wald vor lauter Bäumen nicht :D Danke

100-200-00

Hallo,
bei der Implementierung der Messfunktion komme ich nicht weiter. Ich möchte mit der Bibliothek
"Statistics.h" Messwerte auswerten (Mittelwert und Standardabweichung).

Für die Erfassung der Messdaten habe ich eine Funktion geschrieben, die einen float Wert zurück gibt. Leider weis ich nicht, wie ich den Befehl für den Mittelwert im Zusammenhang mit return schreiben soll:
Code: [Select]
return (myStats.average(),4); // Liefert jedesmal 4.00
return myStats.average(), 4; // Liefert ebenfalls jedesmal 4.00
return (myStats.average()); // Liefert den Messwert auf 2 Nachkommastellen, gewünscht sind allerdings 4 Nachkommastellen


In der Beschreibung der Bibliothek wird als Beispiel der Mittelwert über den Befehl
Code: [Select]
Serial.print(myStats.average(), 4); aufgerufen, ich möchte dies allerdings über return machen.

Serenifly

#4
Dec 05, 2016, 04:30 pm Last Edit: Dec 05, 2016, 04:34 pm by Serenifly
Quote
Liefert jedesmal 4.00
Natürlich tut es das. Der Komma Operator führt das links aus und gibt das ganz rechts zurück.

Wie kommst du auf die Idee dass return genauso funktioniert wie Serial.print()?  :o Das eine ist ein elementares Schlüsselwort der Sprache. Das andere ist eine Arduino Methode die einen Float nimmt und ihn als ASCII Zeichen druckt.

Quote
aufgerufen, ich möchte dies allerdings über return machen.
Das ist totaler Unsinn. Du gibst einfach einen normalen Float zurück. Wie du den dann am Ende bei der Ausgabe darstellst ist überhaupt nicht die Aufgabe dieser Funktion. Das kann in der aufrufenden Funktion erledigt werden.

z.B. so in der Art:
Code: [Select]

void loop()
{
   Serial.println(func(), 4);
}

float func()
{
   return mystats.average();
}


Go Up