Jump to content

AuronX

Members
  • Gesamte Inhalte

    887
  • Benutzer seit

  • Letzter Besuch

Posts erstellt von AuronX

  1. Also insgesamt scheint die Bastelarbeit dabei eher in der Konstruktion und weniger in der Elektronik zu liegen.

    Der im Video gezeigte käme ja fast völlig ohne Elektronik aus.

     

    Welches Brick:

    Die Motoren kannst du entweder über das DC-Brick ansteuern oder über ein Servo-Brick mit angeschlossenem ESC (also ein Fahrtenregler aus dem Modellbau). Das Servo-Brick kann bis zu 7 Teilnehmer (Servos und ESCs) bedienen. Der im Video gezeigte würde meiner Ansicht nach zwei Motoren brauchen.

    Zum Schwenken würde ich es mit Servos versuchen (machen Schrittmotoren sinn?).

     

    An Tinkerforge-Equipment müsste dir dann im Besten Fall ein Servo-Brick reichen, der Rest wäre Modellbau-Zeug (Servos, Motoren, ESC).

     

    Die Steuerung in dem Umfang wie im Video zu sehen sollte sehr einfach sein (ist ja quasi nur Motoren anschalten).

    Sobald du dann natürlich irgendwelche Programme abspielen willst kann es so komplex werden wie es deine Phantasie zulässt, aber grundsätzlich auch alles nicht sooo wild.

     

    Zumindest aus meiner Perspektive sollte die Konstruktion deutlich schwerer sein als die Programmierung. Allerdings hat das auch mit meinen zwei linken Händen zu tun :D

     

    LG

    Jan

  2. Dann empfehle ich dir (das schon unterstützte) Python.

     

    Python bietet viele gute Eigenschaften für Anfänger:

    - kein Zwang zur Objekt-orientierung (aber dennoch die möglichkeit wenn man will)

    - ich würde behaupten ähnlich einfach wie BASIC

    - kann verdammt mächtig sein (also auch dann noch nützlich wenn man schon was gelernt hat)

    - dadurch, dass whitespace teil der syntax ist lernt jeder anfänger seinen code zu formatieren

     

    Noch schnell zum Hello World:

    print("Hello World")

  3. Bei einem setDegree (0, -3510, 18000) läuft der Motor weiter. Stoppe ich ihn und setz den Wert so, läuft er aber nicht los.

    Also ein ähnliches Phänomen kenne ich von Gehäuselüftern (die ja auch nur per PWM gesteuert werden), da ist das Problem, dass das Anlaufen schwerer ist als das "laufen lassen", denn der Rotor ist ja dann schon in Schwung und kann seine Trägheit nutzen. Deswegen ist es tatsächlich möglich nach dem Anlaufen des Motors die Drehzahl wieder zu reduzieren. Ist natürlich tricky, weil wenn du jetzt mit dem Finger den Rotor stoppst (bei Lüftern geht das ohne Verletzung ^^) läuft er wieder nicht an.

     

    Man kann normalerweise auch den ESC auf die vorgegebene Pulsweite eichen.

    Bei guten ESCs geht das definitiv, aber ich besitze auch welche die das nicht können ^^

  4. Habe nur kurz in die Klasse geschaut wo du die Servos ansteuerst. Es sieht so aus als würden deine Motoren aus sein, wenn die Servos voll links eingeschlagen sind. Dafür rufst du setPosition mit -9000 auf.

    In der Doku steht, dass du diesen Bereich aber frei wählen kannst, dann wären die Zahlen auch intuitiver. Zum Beispiel:

    setPosition(0) <-- Motor steht

    setPosition(18000) <-- maximale Drehzahl (hier kannst du auch was anderes nehmen ^^)

     

    Hab grad geschaut, die FUnktion dazu heißt setDegree()

     

     

  5. Hallo,

    als ich in einem anderen Thread gerade erklärt habe wie die Receive-Loop in C# funktioniert ist mir was aufgefallen:

     

    Es wird ja einfach in einen Puffer mit 8kiB geschrieben, allerdings wird nciht überprüft, ob auch genug gelesen wurde. Denn Read garantiert nur für 1 Byte, mehr nicht. Die Implementierung sieht dann zum Glück schonmal so aus, dass ganze TCP-Pakete auf einmal verfügbar sind.

     

    Was ist heir das Problem?

    1. Ihr seid darauf angewiesen, dass die Gegenseite erst dann flushed (das Paket losschickt) wenn die Nachricht komplett ist. Der brickd tut das, ihr könnt auch bei WLAN & Co. darauf achten, das so zu tun, allerdings müsste sowas dann mti in die TCP-Doku

    2. Eure Pakete haben ein Größenlimit: ich bin mir nicht ganz sicher, aber entweder bei 4 kB oder spätestens 8 kB ist Schluss, dann wird jede Nachricht auf mehrere Pakete verteilt. Das heißt im Moment kann keine Nachricht durchkommen die größer ist, weil dann die Bindings daran sterben würden.

     

    Möglicherweise sind diese Überlegungen für euch egal, weil ihr sagt:

    1. Wir implementieren alles selber und achten darauf, dass alles in einem Paket versendet wird

    2. Wir brauchen keine Nachrichten die größer sind als ein TCP-Paket

     

    Kann durchaus sein, sollte aber bewusst entschieden werden ^^

     

    Lösung? (wenn Lösung nötig)

    1. Falls Paketlänge vorher bekannt, solange weiterlesen bis der Puffer ausreichend voll ist (scheint hier nicht zu gehen)

    2. In der weiteren Bearbeitung keinen Byte-Buffer weiterreichen sondern den Stream, dann kann der Code der die Daten braucht sie vom Stream nehmen (das kann dann problematisch sein, wenn man zuerst Daten braucht die weiter "hinten" stehen)

     

    LG

    Jan

     

    P.S.: Wenn der Java-Code genauso aussieht, dann ist dort das gleiche Problem... bei den anderen Standardbibliotheken kenne ich mich weniger aus, aber ich glaube das ist die übliche read-implementierung

  6. Also ganz langsam und von vorn... So sieht im wesentlichen die Hauptschleife des Receive-Thread aus:

    while(RecvLoopFlag) 
    {
    byte[] data = new byte[8192];
    int length = socketStream.Read(data, 0, data.Length);
    
    //mache irgendwas mit den gelesenen Daten
    }

     

    Das passiert in einem eigenen Thread.

    Ich "debugge" jetzt mal:

    while(RecvLoopFlag) 

    RecvLoopFlag ist true, also gehe ich in den Schleifenrumpf

    byte[] data = new byte[8192];

    ich lege ein byte-array namens data an

    int length = socketStream.Read(data, 0, data.Length);

    Hier wirds spannend: Ich lese vom Stream, dabei ist spezifiziert, dass die Methode Read erst dann zurückkehrt (also erst dann gehts weiter), wenn mindestens ein Byte auf dem Stream lesbar ist.

    Das heißt solange niemand etwas auf den Stream schreibt wird hier kein Code mehr ausgeführt, der Thread schläft. Sobald jemand auf den Socket schreibt bekommt dein Betriebssystem das mit, dieses weckt den Thread, sagt ihm, dass der IO auf den er wartet angekommen ist und der Thread macht genau dort weiter wo er aufgehört hat. Das heißt jetzt kehrt die Methode Read zurück, data ist befüllt und die Menge der gelesenen Bytes wurde zurückgegeben.

     

    Ich hoffe jetzt war das einigermaßen klar... ansonsten sollten wir das villt mal ausskypen, weil villt ist der Knoten ja an einer ganz anderen Stelle ^^

     

    Achso zum Lesen:

    http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx

     

    LG

    Jan

     

    P.S.: Mir ist dabei grad was aufgefallen... gibt nen neuen Thread ^^

  7. Am Ende ist halt ausgeschlossen, dass der Receive-Thread an einer anderen Stelle blockiert als beim Lesen vom Socket. (Memo an mich/TF: was passiert wenn die BlockingQueue voll ist? Geht das?)

     

    Woanders blockieren tut die Anwendung immer dann wenn mana uf die Antwort des Stacks wartet, solche Methoden können aber nur in dem Code vorkommen den der Library-User schreibt. Dieser Code wird nur von dessen eigenen Threads ausgeführt und eben vom Callback-Thread. Das ist ja am Ende der Thread der die "Auslieferung" der Callbacks durchführt.

  8. Dein LCD-Device sollte halt von dort aus erreichbar sein. Beispielsweise geht das, indem du das LCD-Device als Instanz-variable vorhälst:

     

    class MyCoolForm
    {
      private Device MyLCD;
      ...
      public void MyCoolForm_Load(someArgumentsIDontRemember)
      {
         ...
         MyLCD = new BrickletLCD20x4("aCooLU1D");
         ...
      }
      ...
      void PressedCB(byte button)
      {
        MyLCD.DoWhatEverYouWant();
      }
    }

     

    Hoffe das Beispiel hat geholfen die Idee klarzumachen ^^

     

    P.S.: Ich habe auf GitHub bereits vorgeschlagen Callbacks per C#-Event umzusetzen (wirst du kennengelernt haben wenn du mit WinForms arbeitest). Dabei gibt es auch immer ein sender-object. Hier hättest du direkt die möglichkeit dieses zu nutzen, da das in dem Fall das LCD wäre.

  9. Verstehe ich dich richtig, dass im gezeigten Code die erste Verbindung hergestellt wird und der Code dann den zweiten if-Zweig ansteuert?

     

    Falls es zu compile-fehlern kommt: ich denke, dass deine defines ganz oben möglicherweise NICHT auskommentiert sind. Zumindest dachte ich bisher, dass der präprozessor sich nciht für kommentare interessiert... das würde bedeuten, dass UID_lcd und UID_tir durch deine UIDs ersetzt würden, das würde wiederum hier krachen:

    	char* UID_tir = argv[1];
    char* UID_al = argv[2];
    char* UID_lcd = argv[3];

     

    Allerdings bin ich kein C++-Fan, dementsprechend kann ich mich auch irren ^^

×
×
  • Neu erstellen...