Jump to content

Recommended Posts

Geschrieben

Hallo Tinkerfreunde!

 

Entweder bin ich zu doof oder ich bekomme es einfach nicht hin. Leider habe ich auch noch keinen Eintrag dazu gefunden.

 

Ich möchte einen Kreuztisch mit 2 Achsen (X und Y) aufbauen. Dafür habe ich einen Master und 2x den StepperBrick.

 

Meine Problem ist, ich bekomme es nicht hin es so zu programmieren (C#) das ich beide Stepper separat ansteuern kann. Irgendwas mache ich falsch bzw. hab keine Ahnung wie ich es richtig machen soll.

 

StepperBrick 1 hängt an Position 1 und

StepperBrick 2 hängt an Position 2 im Stack (Pos. 0 ist der Master)

 

Kann mir jemand weiterhelfen?

 

Würde mich über jeden Beitrag freuen!

 

Danke

 

Artur

Geschrieben

Das sind zu wenige Informationen. Als Einstieg würde ich erstmal die Beispiele zum Stepper aus der API/Doku ausprobieren, später erst die eigene Anwendung, anschl. poste hier deinen Source-Code.

 

Und prüfe ob jeder Stepper-Brick einzeln (und mal mit Master) funktioniert um Hardware Versagen einer oder mehr Teile auszuschließen. Dann den kompletten Stack Aufbau beschreiben einschl. Stromversorgung etc..

 

Es wurde hier im Forum schon eine mehrachsige CNC Fräse vorgestellt:

http://www.tinkerunity.org/forum/index.php/topic,863.0.html

Geschrieben

Also die StepperBricks funktionieren einzeln wunderbar.. Achsen verfahren.

 

Der Aufbau ist nicht das Problem! Stromversorgung auch nicht.

 

Ich habe nach dem Robusten Ansatz programmiert mit der [EnumerateCB]-Funktion.

 

Die Schwierigkeiten sind aufgetreten als ich dann auf einmal 2xStepperbricks am Master habe. Die Zuordnung kann dann ja nur über die Abfrage der Position im Stack stattfinden.. dies habe aber noch nicht im Griff .. ich denke da liegt auch das Problem!

 

=(

 

 

Geschrieben

Dein konkretes Problem hast Du aber immernoch nicht genauer beschrieben.

 

Wenn Du den Enumerate verwendest, dann bekommst Du darüber doch die Position im Stack (0,1,2) und UID und den Typ (Master, Stepper) etc.. Damit kannst Du doch alles zuordnen was Du brauchst und mit der richtigen UID den einen oder anderen Stepper steuern. Und Dein Problem ist ... ?

Geschrieben

Wenn dein Source-Code geheim bleiben soll ;) können wir dir nicht helfen.

Die Schwierigkeiten sind aufgetreten als ich dann auf einmal 2xStepperbricks am Master habe. Die Zuordnung kann dann ja nur über die Abfrage der Position im Stack stattfinden.. dies habe aber noch nicht im Griff .. ich denke da liegt auch das Problem!

Ich verstehe nur Bahnhof. Kannst du das folgende Beispiel ausführen, Parameter wie Uid, port etc. deiner Umgebung angepasst ?

http://www.tinkerforge.com/de/doc/Software/Bricks/Stepper_Brick_CSharp.html#callback

Warum sollte es ein Problem sein, da noch eine 2.Stepper Instanz zu erzeugen ?

Geschrieben

Also mein Sourcecode ist nicht geheim..

namespace CrazyStuff
{
    public partial class Form1 : Form
    {

        private static string HOST = "localhost";
        private static int PORT = 4223;

        private static IPConnection ipcon = null;

        private static BrickStepper X_Achse = null;
        private static BrickStepper Y_Achse = null;

        private delegate void SetuidTextBoxCallback(string value);
        private delegate void SetconnectedUIDTextBoxCallback(string value);
        private delegate void SetpositionTextBoxCallback(string value);
        private delegate void SetdeviceidentifierTextBoxCallback(string value);

        private delegate void GetStackVoltageLabelCallback(string value);
        private delegate void GetRemainingStepsLabelCallback(string value);
        private delegate void GetActualPositionLabelCallback(string value);
        private delegate void GetCurrentConsumptionLabelCallback(string value);

        public Form1()
        {
            InitializeComponent();

            // Create IP Connection
            ipcon = new IPConnection();

            // Register IP Connection callbacks
            ipcon.EnumerateCallback += EnumerateCB;
            ipcon.Connected += ConnectedCB;

            // Connect to brickd, will trigger cb_connected
            ipcon.Connect(HOST, PORT);
            ipcon.Enumerate();

        }

        // Callback handles device connections and configures possibly lost
        // configuration of lcd and temperature callbacks, backlight etc.
        private void EnumerateCB(IPConnection sender, string UID, string connectedUID,
                                char position, short[] hardwareVersion,
                                short[] firmwareVersion, int deviceIdentifier,
                                short enumerationType)
        {
            if (enumerationType == IPConnection.ENUMERATION_TYPE_CONNECTED ||
               enumerationType == IPConnection.ENUMERATION_TYPE_AVAILABLE)
            {
                SetdeviceidentifierTextBox(Convert.ToString(deviceIdentifier));
                SetpositionTextBox(Convert.ToString(position));
                SetconnectedUIDTextBox(Convert.ToString(connectedUID));
                SetuidTextBox(Convert.ToString(UID));

                if (deviceIdentifier == BrickStepper.DEVICE_IDENTIFIER)
                {
                    if (position == 1)
                    {
                        X_Achse = new BrickStepper(UID, ipcon);
                        X_Achse.AllData += AllDataX;
                    }
                    else if (position == 2)
                    {
                        Y_Achse = new BrickStepper(UID, ipcon);
                        //Y_Achse.AllData += AllDataY; noch nicht programmiert
                    }
                }
                
            }
        }

        private void AllDataX(BrickStepper sender, int currentVelocity, int currentPosition, int remainingSteps, int stackVoltage, int externalVoltage, int currentConsumption)
        {
            GetStackVoltageLabel(Convert.ToString(externalVoltage / 1000) + "V");
            GetRemainingStepsLabel(Convert.ToString(remainingSteps));
            GetActualPositionLabel(Convert.ToString(currentPosition));
            GetCurrentConsumptionLabel(Convert.ToString(currentConsumption) + "mA");
        }

        //############################################################################################################ Callback handles reconnection of IP Connection
        private void ConnectedCB(IPConnection sender, short connectReason)
        {
            // Enumerate devices again. If we reconnected, the Bricks/Bricklets
            // may have been offline and the configuration may be lost.
            // In this case we don't care for the reason of the connection
            ipcon.Enumerate();
        }



        //#############################################################################################
        private void SetdeviceidentifierTextBox(string value)
        {
            // Invoke nötig?
            if (deviceIdentifier.InvokeRequired)
            {
                // Invoke nötig
                deviceIdentifier.Invoke((MethodInvoker)delegate { deviceIdentifier.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                deviceIdentifier.Text = value;
            }
        }

        //#############################################################################################
        private void SetpositionTextBox(string value)
        {
            // Invoke nötig?
            if (position.InvokeRequired)
            {
                // Invoke nötig
                position.Invoke((MethodInvoker)delegate { position.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                position.Text = value;
            }
        }
        //#############################################################################################
        private void SetconnectedUIDTextBox(string value)
        {
            // Invoke nötig?
            if (connected_uid.InvokeRequired)
            {
                // Invoke nötig
                connected_uid.Invoke((MethodInvoker)delegate { connected_uid.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                connected_uid.Text = value;
            }
        }
        //#############################################################################################
        private void SetuidTextBox(string value)
        {
            // Invoke nötig?
            if (uid.InvokeRequired)
            {
                // Invoke nötig
                uid.Invoke((MethodInvoker)delegate { uid.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                uid.Text = value;
            }
        }

        //#############################################################################################
        private void GetCurrentConsumptionLabel(string value)
        {
            // Invoke nötig?
            if (lbl_current_consumption.InvokeRequired)
            {
                // Invoke nötig
                lbl_current_consumption.Invoke((MethodInvoker)delegate { lbl_current_consumption.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                lbl_current_consumption.Text = value;
            }
        }

        //#############################################################################################
        private void GetActualPositionLabel(string value)
        {
            // Invoke nötig?
            if (lbl_akt_position.InvokeRequired)
            {
                // Invoke nötig
                lbl_akt_position.Invoke((MethodInvoker)delegate { lbl_akt_position.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                lbl_akt_position.Text = value;
            }
        }

        //#############################################################################################
        private void GetRemainingStepsLabel(string value)
        {
            // Invoke nötig?
            if (lbl_rem_steps.InvokeRequired)
            {
                // Invoke nötig
                lbl_rem_steps.Invoke((MethodInvoker)delegate { lbl_rem_steps.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                lbl_rem_steps.Text = value;
            }
        }
        //#############################################################################################
        private void GetStackVoltageLabel(string value)
        {
            // Invoke nötig?
            if (lbl_ext_voltage.InvokeRequired)
            {
                // Invoke nötig
                lbl_ext_voltage.Invoke((MethodInvoker)delegate { lbl_ext_voltage.Text = value; });
            }
            else
            {
                // Kein Invoke nötig - Vorgang sicher durchführbar
                lbl_ext_voltage.Text = value;
            }
        }
    }
}

 

Also wenn ich das Programm starte dann wird in meiner Windows Form in den Invoked-Textboxen angezeigt:

 

Connected_UID

UID

Position

deviceIdentifier

 

Mein Problem ist einfach (denke ich) das ich die Position nicht korrekt abfrage und dann den Stepper nicht richtig zuweise.

 

Danke schonmal für eure Mühe.

 

 

 

Geschrieben

Ist dieser Teil überhaupt richtig so?

 

        // Callback handles device connections and configures possibly lost
        // configuration of lcd and temperature callbacks, backlight etc.
        private void EnumerateCB(IPConnection sender, string UID, string connectedUID,
                                char position, short[] hardwareVersion,
                                short[] firmwareVersion, int deviceIdentifier,
                                short enumerationType)
        {
            if (enumerationType == IPConnection.ENUMERATION_TYPE_CONNECTED ||
               enumerationType == IPConnection.ENUMERATION_TYPE_AVAILABLE)
            {
                if (deviceIdentifier == BrickStepper.DEVICE_IDENTIFIER)
                {
                    if (position == 1)
                    {
                        X_Achse = new BrickStepper(UID, ipcon);
                        X_Achse.AllData += AllDataX;
                    }
                    else if (position == 2)
                    {
                        Y_Achse = new BrickStepper(UID, ipcon);
                        Y_Achse.AllData += AllDataY; 
                    }
                } 
            }
        }

 

 

Geschrieben

Nicht über Position fragen, sondern der Enum Callback gibt dir auch die Uid zurück, nur diese beschreibt eindeutig ob es um den Stepper Brick für X- oder Y-Achse geht.

Schau mal was dir der BrickV zurückgibt, so prüfe ich immer ob die Uid "c3po" Stepper 1 oder "r2d2" Stepper 2 ist usw.

Geschrieben

Das mit '1' und '2' hab ich probiert .. hab irgendwie nicht funktioniert..

 

habs nur so gemacht.. und siehe da Alldata wird für beide Achsen alle 500ms angezeigt..

 

                    if (deviceIdentifier == BrickStepper.DEVICE_IDENTIFIER)
                    {
                        if (UID == "69imVq")
                        {
                            X_Achse = new BrickStepper(UID, ipcon);
                            X_Achse.AllData += AllDataX;
                            X_Achse.SetAllDataPeriod(500);
                        }

                        else if (UID == "6dLjnF")
                        {
                            Y_Achse = new BrickStepper(UID, ipcon);
                            Y_Achse.AllData += AllDataY;
                            Y_Achse.SetAllDataPeriod(500);
                        }
                    }

Geschrieben

Dann lass es so, wenn es jetzt klappt. Über die Uid ist der generelle Weg, da jedes Bauteil seine eigene Identifikation Nr hat, unabh. welche Pos. es im Stack einnimmt. Und das interessiert i.d.R. nicht. ich prüfe immer über die Uid und device Type.

Geschrieben

Den Ansatz, das in diesem Fall über die Position im Stack zu machen finde ich eigentlich gut. Die Brick Reihenfolge im Stack kann man leicht erkennen (leichter als die Bricklet Ports) und wenn man den Stack zerlegt, um z.B. neue Firmware draufzuspielen, muss man nicht drauf achten, ob man danach den richtigen Stepper an Anschluss X oder Y hat.

 

Mich wundert nur, dass die Abfrage nicht funktioniert hat, sollte eigentlich gehen.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...