Jump to content

borg

Administrators
  • Gesamte Inhalte

    3.629
  • Benutzer seit

  • Letzter Besuch

  • Tagessiege

    63

Alle erstellten Inhalte von borg

  1. Problem: Wie in diesem Thread zu sehen, bekommt ein Programm welches ausschließlich Callback verwendet und über WLAN betrieben wird ein Verbindungsabbruch von der Gegenseite nicht mit. Dies liegt grundsätzlich erst einmal an der Funktionsweise von Sockets, der "Read Socket" blockiert und bekommt einfach keine neuen Nachrichten mehr und auf den "Write Socket" wird nicht geschrieben. Dadurch kann eine Verbindung nicht automatisch neu aufgebaut werden, da keinerlei Hinweis auf eine Verbindungstrennung vorhanden ist. Ein Workaround habe ich im obigen Thread schon gepostet, Wenn wir regelmäßig den "Write Socket" nutzen (z.B. durch Aufruf eines Getters), bekommen wir mit wenn die Gegenseite wieder da ist und es wird automatisch eine neue Verbindung aufgebaut. Jetzt könnte man diese "Ping Funktionalität" fest in die Bindings einbauen, allerdings stellt mich dies als Lösung nicht zufrieden. Es ist weiterhin so, dass eine Disconnect erst dann aufgerufen wird, wenn die Gegenseite wieder da ist. Nicht aber wenn die Verbindung das erste mal abbricht. Problemerklärung: Um zu zeigen, dass dies eine Prinzipielle Eigenschaft von Sockets ist, hier ein Beispielaufbau: PC1 (simuliert WIFI Extension indem ein Socket geöffnet wird und eingehende Daten ausgegeben werden): # WIFI Extension simulation import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 1234)) s.listen(1) conn, addr = s.accept() while 1: data = conn.recv(1024) print data conn.close() PC2 (simuliert Client der mit WIFI Extension spricht): # Client import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('192.168.178.153', 1234)) while True: s.sendall('Hello, world') time.sleep(1) s.close() Wenn ich dieses Programm auf beiden Rechnern starte, gibt PC1 jede Sekunde einmal "Hello World" aus. Wenn ich jetzt das Ethernet Kabel trenne (oder äquivalent die WLAN Verbindung unterbreche), passiert auf beiden seiten _nichts_, Der Server bekommt keine Nachrichten mehr und der Client gibt keine Fehler. Wenn ich jetzt das Programm auf PC2 neustarte und dann das Ethernet Kabel wieder einstecke, bekomme ich dies auf PC1 mit (da "sendall" einen Fehler schmeißt, da die Gegenseite die Socket Verbindung noch nicht kennt). Erst jetzt bekomme ich mit, dass die Gegenseite nicht mehr erreichbar war und kann eine neue Verbindung aufbauen. Exakt das gleiche passiert mit der WIFI Extension, dadurch bekommen wir den Verbindungsabbruch erst mit, wenn die WIFI Extension wieder in Reichweite ist oder sich neugestartet hat o.ä. Lösungsvorschlag: Eine mögliche Lösung wäre folgendes: Alle Bindings schicken in regelmäßigen Abständen (alle 2-5 Sekunden?) ein Ping raus. Wenn dies mehr als 3 mal hintereinander passiert, gehen wir davon aus dass die Verbindung getrennt wurde, schmeißen einen DISCONNECTED Callback und versuchen eine neue Verbindung aufzubauen. Vorteil: Eine Verbindungstrennung wird frühzeitig erkannt, nicht erst wenn eine Verbindung wieder aufgebaut werden kann. Der neue Verbindungsaufbau passiert zur gleichen Zeit wie zuvor auch, es gibt dadurch keine Vorteil bzgl. der "Neuverbindungsgeschwindigkeit". Was meint ihr? Ist das den Aufwand Wert? Wird es da zuviele "False Positives" geben (3x Timeout obwohl Verbindung nicht unterbrochen war)?
  2. Firmwares: Master Brick 2.0.2 Fixes für stabilere WIFI Extension: Command/Data Modus entfernt, nur eine Stelle für Empfangen/Senden Ermöglich viel besseres Error Handling, Logging und Debugging [*]Brickd speichert Nachrichten nur wenn "Return Expected" = 1 [*]Analysiere alle Command-Responses mit lesbarer Antwort [*]Analysiere <ESC>O, <ESC>F, <ESC>A Optionen ausgiebiger [*]Entferne Nachrichten von Brickd wenn socket getrennt [*]WIFI Initialisierung jetzt Asynchron Ermöglicht ein Kommunizieren mit Master Brick während Initialisierung [*]5 Minuten Timeout für "Hang-Up-Detection" (statt 3) [*]Empfangene Daten werden ausgewertet während Commands geschickt werden [*]Benutze andere ATS Konfigurationen [*]Analysiere Startup/Reset Nachrichten [*]Neue Data-State-Machine [*]API für langen WPA Schlüssel hinzugefügt (bis zu 64 Buchstaben) Download Firmwares: Master Brick
  3. Firmwares: Master Brick 2.0.2 Fixes for a more stable WIFI Extension: Remove command/data mode, use only one place for receiving/sending Allows for much better error handling, debugging and logging [*]Only save messages in brickd if return expected [*]Parse all command responses with human readable response [*]Parse <ESC>O, <ESC>F, <ESC>A options more thoroughly [*]Remove messages from brickd if socket disconnected [*]Make WIFI initialization asynchronous Allows to communicate with Master Brick while WIFI is connecting [*]Use 5 minute timeout before we assume a hang up (instead of 3) [*]Evaluate received data while sending command [*]Use different ATS configuration [*]Parse startup/reset message [*]Refactor data state machine [*]Add API for long WPA key (up to 64 chars) Download Firmwares: Master Brick
  4. Das funktioniert, ich habs gerade getestet. Du musst die IPcon nicht selbst neu aufbauen. Es ist über WLAN in der Tat so, dass der Socket einen Disconnect nicht mitbekommt wenn nur Callbacks verwendet werden. Dagegen können wir allerdings nichts machen, WLAN verhält sich da anders als USB. Das ist allerdings kein großes Problem, dann du kannst einfach alle paar Sekunden einen Getter aufrufen (und die Timeout Exception natürlich fangen). Dann bekommst du ein Disconnect sobald die WIFI Extension wieder da ist. Hier mein Code mit dem ich getestet hab (Aufbau: Master <-> WIFI <-> IMU): #!/usr/bin/env python # -*- coding: utf-8 -*- HOST = "192.168.178.108" PORT = 4223 UID = "631cHu" # Change to your UID import time import traceback from tinkerforge.ip_connection import IPConnection from tinkerforge.brick_imu import IMU imu = None def quaternion_cb(x, y, z, w): print("x: " + str(x) + "\ny: " + str(y) + "\nz: " + str(z) + "\nw: " + str(w) + "\n") def cb_enumerate(uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): print "cb_enumerate", uid, enumeration_type if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \ enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE: if device_identifier == IMU.DEVICE_IDENTIFIER: global imu imu = IMU(UID, ipcon) imu.set_quaternion_period(1000) imu.register_callback(imu.CALLBACK_QUATERNION, quaternion_cb) def cb_connected(connected_reason): print "cb_connected", connected_reason ipcon.enumerate() if __name__ == "__main__": ipcon = IPConnection() ipcon.connect(HOST, PORT) ipcon.enumerate() ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, cb_enumerate) ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, cb_connected) while True: time.sleep(1) if imu != None: try: imu.get_imu_temperature() except: pass Wenn ich hier jetzt den Stack neustarte läuft das Programm automatisch weiter, sobald das WLAN Modul sich wieder mit dem AP verbunden hat. Die Ausgabe sieht dann wie folgt aus: Wir sollten das Rugged Example diesbezüglich anpassen. Alternativ sollten wir den Bindings vielleicht doch eine automatische "Ping Funktionalität" hinzufügen, die man aktivieren kann, die genau dieses Verhalten automatisch erzeugt. Dies wurde auch hier im Forum schon öfter vorgeschlagen. Mhhhhhhh
  5. Das Problem sind hier die Sockets. Der Connection State wird geändert wenn sich der Zustand des Sockets ändert. Zum einen kann dies Lange dauern (länger als Minuten) und zum anderen kann es sein, dass man dies gar nicht mitbekommt wenn nur Callbacks verwendet werden. Da können wir aber auch nichts gegen machen, befürchte ich. Du könntest versuchen zusätzlich einmal pro Sekunde einen getter Aufzurufen, um damit Timeouts zu provozieren und darüber mitzubekommen, dass die Gegenseite nicht mehr da ist. Spätestens wenn der Brick wieder da ist wird die Verbindung allerdings neu aufgebaut, das sollte funktionieren! Das ist korrekt. Es gibt nur eine Callback Periode und ein Callback Thershold etc. Einstellungen sind nicht pro Verbindung, das wäre technisch auch gar nicht möglich. Wenn mehrere Verbindungen über Brickd hergestellt werden (über USB), bekommen die Bricks da gar nichts von mit. Für die Bricks selbst gibt es immer nur einen Teilnehmer.
  6. So, es gibt jetzt die erste beta von Master Brick Firmware 2.0.2: http://download.tinkerforge.com/_stuff/brick_master_firmware_2_0_2_beta1.bin Das ist definitiv noch nicht die finale Version 2.0.2, es fehlen noch ein paar Kleinigkeiten die ich heute nicht mehr geschafft hab. Desweiteren hab ich bisher nur mit WPA und noch nicht ausführlich im AdHoc/AP Modus getestet. Hab ziemlich viel umgerissen, hauptsächlich um bessere Fehlerbehandlung und besseres Debugging/Logging zu erlauben: https://github.com/Tinkerforge/master-brick/commit/510e9350b2c7769222bbbd839254809baafafe2c Wer Lust und Zeit hat: Bitte testen ob die Firmware einen Unterschied bringt .
  7. Im Stack flashen geht.
  8. Sorry, wird noch ein wenig dauern . Die anderen Probleme die ich gerade am versuche zu fixen lassen sich leider nicht so gut reproduzieren, dadurch dauert es so lange.
  9. Komisch. D.h. es läuft einfach weiter nach einem Timeout und funktioniert dann auch wieder? Ist das Python Skript groß, kann ich das hier evtl ausführen zum reproduzieren?
  10. Erstaunlich wie gut das mit DC Motoren funktioniert . Ich hätte gedacht, dass die Positioniergenauigkeit nach ein paar cm dahin ist.
  11. Kannst du einmal den Teil des Source Codes der nicht funktioniert hier posten?
  12. Ich bin dran, solche Sachen die sich nur alle paar Tage reproduzieren lassen sind leider wirklich schwer zu debuggen .
  13. Extensions müssen über über dem Master des Stapels stecken, sonst funktioniert das elektrisch gar nicht (Die Extensions shiften immer Signale nach oben durch). Wir sollte vermutlich "RS485 Extension Master" in der Doku schreiben?
  14. Schwer zu sagen, 2 Drähte klingt nach einem DC Motor. Kannst du mal ein Foto von dem Motor machen? War in dem Drucker denn auch ein Inkrementalgeber drin (etwas, was die zurückgelegte Entfernung mitmisst)?
  15. The PTC Bricklet will be able to read out a Pt100 and Pt1000 sensor with 2, 3 and 4 wire measurements. These temperature sensors usually measure from -200 to +800°C, so the Temperature Bricklet doesn't even compare to that .
  16. We try to choose a name that is most intuitive. ResistanceBricklet would not be intuitive for a Poti Bricklet, i think. AirPressure Bricklet instead of Barometer Bricklet would be OK, but we thought that most people know that a barometer can measure height (which the Barometer Bricklet can too). And for things like the Distance Bricklet it would be hard to use a name of the device: GP2Y0A41 Bricklet, ugh .
  17. Du kannst mit beiden Brickv beide Brick Firmwares flashen, aber nur mit dem passenden Brickd/Brickv die Bricklet Plugins (das geht ja über den Brick). Du musst in dem Fall natürlich das Bricklet anschließen, nachdem das Brick gestartet hat. Damit das falsche Plugin nicht auf dem Brick ausgeführt wird.
  18. Inwiefern? Gibt es einen Timeout? Also du rufst einfach alle 5 Minuten einen Getter auf? Oder wie kann ich das nachstellen?
  19. In der Theorie, wenn die Daten der IMU absolut perfekt wären, wäre das möglich. In der Praxis sind die Timings über USB nicht gut genug. D.h. wenn du zwei Nachrichten mit IMU Daten bekommst, weißt du nicht auf die ns genau wie weit die Messzeitpunkte auseinanderliegen. Je nachdem wann der gemessen wurde und das Betriebssystem per USB gepollt hat, kann eine Messung von außen um bis zu 2ms daneben liegen. Das ist leider viel zuviel .
  20. Ich befürchte das ist nicht möglich. Du könntest dir die Werte mit hoher Frequenz holen und dadrüber mitteln. Das Rauschen selbst könnte man nur durch bessere Sensoren verringern, dann wäre das IMU Brick aber nicht mehr bezahlbar .
  21. Mh, bei mir gehts. Edit: Ah, mit Python3 kann ich das reproduzieren. Komisch, dann müssen die Python bindings mit der IO16/IO4 noch nie richtig funktioniert haben . Gucke ich mir gleich an, ist vermutlich mal wieder so ein byte vs char gefummel.
  22. Das ist leider gewachsen, im alten Protokoll konnten wir an der Stelle nur die 50 Byte Nutzdaten übertragen. Das WIFI Modul könnte Passwörter bis Länge 64. Im neuen Protokoll haben wir allerdings 64Byte für den Payload, was genau für ein 64 Byte Passwort passen würde. Allerdings übergeben wir bei set_wifi_encryption key index, eap options und andere Dinge, wodurch der Payload wieder nicht reicht . Das einzige was mir dazu einfällt: Wir könnte die API um ein set_long_wifi_password erweitern. Dann müsste man natürlich immer erst set_wifi_encryption mit einem "Dummy-Passwort" aufrufen, um die Art der Verschlüsselung vorher zu setzen. Hat irgendwer eine bessere Idee? Sonst würde ich das denke ich implementieren. Bin sowieso gerade dabei am WIFI Code rumzufummeln.
  23. Welches Beispiel führst du aus? Gibt es keine Timeout oder sowas? Hast du die korrekte UID benutzt (im Beispiel ausgetauscht)?
  24. But you can connect to the IP of the WIFI Extension and do the Bricks/Bricklets that are connected to the Master Brick show up, right? If that is the case, i highly suspect that it is a problem with the timing of the status refresh. Since the refresh makes the WIFI module unresponsive for a small amount of time. I took a look at the WIFI module datasheet. We could try to get the RSSI from another command that does not have so much overhead and do the rx/tx count ourself. All of the other information must only be obtained on connects/disconnects and not every time the getStatus is called. We will try to make a firmware that works this way, that you can test.
  25. No worries, if it is broken we will of course replace it. It is just so unlikely that the 5V rail isn't working. Can you measure the voltage of pins in the green connector? And are you using the black connector for input (Black is input, Green is output) ?
×
×
  • Neu erstellen...