Jump to content

[golöst] Python + Callbacks + WLAN


ulugutz

Recommended Posts

Ich habe vorhin versucht meine Python scripte auf das neue TF2.0 Protokoll umzustellen und dabei statt getter callbacks zu verwenden.

 

Ich habe mich hierbei am Beispiel "Robuster Ansatz" orientiert: http://www.tinkerforge.com/doc/Tutorials/Tutorial_Rugged/Tutorial.html

 

Nun ist mein Problem folgendes:

Ich bekomme nicht mitgeteilt, wenn der Brick (über WIFI angeschlossen) getrennt wird. Ich verwende hierbei zum Testen den "reset" Button.

 

Ebenso gibt sie Methode get_connection_state immer noch CONNECTION_STATE_CONNECTED zurück, selbst wenn der Brick seit einer Minute vom Strom getrennt ist.

 

Hat jemand einen Vorschlag was ich hier falsch mache? Oder geht das gar nicht mit dem WLAN?

 

Edit: Noch eine Frage zu den Callbacks: Ist es möglich mehr als einen Callback für einen Sensorwert zu haben? Sobald ich z.B. den Brickv auf habe und einen Callback auf einen (anderen) Rechner setze, wird die "callback period" auf diesen Wert gesetzt. Ebenso wird der Callback gelöscht, wenn ich das Programm beende. Dies bedeutet, dass ich effektiv nur einen Callback gleichzeitig laufen lassen kann  :-\

Link zu diesem Kommentar
Share on other sites

Ebenso gibt sie Methode get_connection_state immer noch CONNECTION_STATE_CONNECTED zurück, selbst wenn der Brick seit einer Minute vom Strom getrennt ist.

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!

 

 

Edit: Noch eine Frage zu den Callbacks: Ist es möglich mehr als einen Callback für einen Sensorwert zu haben? Sobald ich z.B. den Brickv auf habe und einen Callback auf einen (anderen) Rechner setze, wird die "callback period" auf diesen Wert gesetzt. Ebenso wird der Callback gelöscht, wenn ich das Programm beende. Dies bedeutet, dass ich effektiv nur einen Callback gleichzeitig laufen lassen kann  :-\

 

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.

Link zu diesem Kommentar
Share on other sites

Spätestens wenn der Brick wieder da ist wird die Verbindung allerdings neu aufgebaut, das sollte funktionieren!

 

Solange ich nur nur Callbacks am Laufen habe, bekomme ich das leider nicht mit und kann sie auch so nicht neu registrieren.

 

Rufe ich allerdings einen Getter auf, dann springt er mir mit einem connection error (Error.TIMEOUT) in den Tod. Auch wenn der Brick schon längst wieder da ist. Ich muss erst (mit hellseherischen Fähigkeiten) die IPcon neu aufbauen. Gibt es da einen Weg drum herum?

 

Der Brickv scheint das irgendwie mitzubekommen. Zumindest meldet der einen Fehler und verbindet dann neu. Ich habe bisher den Source nur grob gesichtet und dabei keinen so großen Unterschied zum Rugged Example gefunden.

Link zu diesem Kommentar
Share on other sites

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:

cb_enumerate 5Vihz1 1

cb_enumerate 5Vihz1 0

cb_enumerate 631cHu 0

x: 0.628215253353

y: -0.775457203388

z: -0.0249259658158

w: -0.00355566455983

 

x: 0.628773748875

y: -0.77499204874

z: -0.025115000084

w: -0.00476873433217

 

# Hier hab ich Reset gedrückt

# Nach ca. 20 Sekunden:

 

cb_connected 1

cb_enumerate 5Vihz1 1

cb_enumerate 5Vihz1 0

cb_enumerate 631cHu 0

x: 0.634201645851

y: -0.770636498928

z: -0.0226861666888

w: -0.00390662206337

 

x: 0.6333989501

y: -0.771231591702

z: -0.0245241578668

w: -0.00535446498543

 

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

Link zu diesem Kommentar
Share on other sites

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...