Nachdem die Ansteuerung einer LED über telnet gut funktioniert
Beitrag "RasPi telent LED blnken"
versuche ich mein eigentliches Ziel, die Fernsteuerung der
SPI-Schnittstelle über telnet zu realisieren. Ich habe hierzu diesen
neuen Thread aufgemacht, weil die Überschrift für die Forensuche ja
wichtig ist.
Mein Code sieht momentan so aus:
GPIO.setmode(GPIO.BCM)# set board mode to Broadcom
15
16
GPIO.setup(RST_N,GPIO.OUT)# RST_N as output
17
GPIO.setup(ARDUINO_LED,GPIO.OUT)
18
19
spi=spidev.SpiDev()
20
spi.open(0,0)
21
spi.max_speed_hz=4000000
22
23
24
defled_blink(msg):
25
print"got msg",msg# Debug msg
26
27
spidata=spi.xfer(msg)
28
29
GPIO.output(ARDUINO_LED,GPIO.HIGH)
30
time.sleep(0.1)
31
GPIO.output(ARDUINO_LED,GPIO.LOW)
32
33
s=socket.socket()# Create a socket object
34
host=''# all interfaces
35
port=5006# Port
36
s.bind((host,port))# Bind to the port
37
s.listen(5)# Now wait for client connection.
38
print"Listening"
39
c,addr=s.accept()# Establish connection with client.
40
41
whileTrue:
42
msg=c.recv(1024)
43
printmap(ord,msg)
44
print'Got connection from',addr
45
ifmsg[0:4]=="Exit":
46
print"EXIT !!"
47
break
48
led_blink(msg)
49
50
c.close()
51
spi.close()
Die SPI habe ich zuvor getrennt getestet und sie lässt sich von Python
aus ansprechen.
Allerdings funktioniert das Ganze wohl nicht wenn ich den SPI-Befehl
spidata=spi.xfer(msg)
in den Server einbaue. Sobald der Sever eine Anfrage erhält, beendet er
sich kommentarlos.
Woran könnte das wohl liegen?
Was für eine Art von Daten kann spi.xfer verarbeiten? Kann das mehr als
ein einzelnes Byte bzw. Word verarbeiten?
Bedenke, daß SPI eine synchrone serielle Schnittstelle ist, die
gleichzeitig(!) sendet und empfängt.
Was für Daten erwartest Du in spidata?
spi.xfer([array of bytes]) Sendet ein Byte-Array, CEx wird vor jedem Byte aktiv und dann wieder inaktiv
und tatsächlich, dank Deiner Anmerkung habe ich einfach mal testweise
die Zeile
1
spi.xfer([1,2,3])
eingesetzt. Mit dem Logikanalysator geprüft werden jetzt die 3 bytes
gesendet und der Server beendet sich nicht mehr.
Es sieht also so aus, als wenn die xfer-Funktion sich an dem Text
verschluckt.
Damit ich die SPI-Schnittstelle steuern kann, müssen Daten zum
SPI-Server übertragen werden und die Empfangsdaten vom Server abgeholt
werden.
Das Senden funktioniert eigentlich. Ich kann via telnet zum obigen
Server senden, kann aber keine Daten empfangen.
Als Test für das zurücksenden habe ich folgendes probiert ( es wird
einfach nur ein ">" zurück gesendet ). Wenn ich das tue, bleibt der
Server aber wieder hängen, wenn ich ihn mit telnet anspreche. Woran
könnte das liegen?
Hier ist der funktionierende Code für das beschreiben der
SPI-Schnittstelle. Das Zurücksenden, welches nicht funktioniert, habe
ich auskommentiert.
Marcus schrieb:> Woran könnte das liegen?
Hat denn die spi.xfer-Funktion überhaupt einen Rückgabewert? Der von Dir
zitierten Dokumentation zufolge nicht, das Ding scheint eine
Einbahnstraße zu sein, nur senden, aber nichts empfangen.
Andererseits gibts da ja dieses Beispiel
1
# Einleseschleife
2
while True:
3
# Lese ADC-Kanal 1
4
rcv = spi.xfer2 ([1, 8 << 4, 0])
5
adcval = ((rcv[1] & 3) << 8) + rcv[2]
6
# Wert ausgeben
7
Print "ADC = ", adcval
8
# etwas warten
9
time.sleep(1)
10
# Ende Schleife
demzufolge spi.xfer(2) einen Rückgabewert hat. Und der ist wohl auch
vom Typ "array of byte".
Erzeugt denn die von Dir verwendete Funktion "str" aus diesem Datentyp
was lesbares?
Marcus schrieb:> #Zurücksenden zu telnet geht nicht> #message=raw_input(">")> #c.send(message);
Der Server sendet hier nichts, weil er auf eingaben wartet. raw_input
wartet das du dinge (TM) auf stdin deines Pi Eingibst nach dem return
werden die auch gesendet.
generell würde ich dir empfehlen deinen Server auf einen TCPServer
socketserver umzubauen. der nimmt dir das kümmern ums Netzwerk etwas ab
und solltest du feststellen das UPD oder ein Threading server oder so
brauchst kannst du dann einfach ein paar Klassen wechseln und das ding
ist fertig umgestellt.
>def toggleLed():> if not hasattr(toggleLed, "state"):> toggleLed.state = 0 # it doesn't exist yet, so initialize it> if toggleLed.state==1:
hier würde ich vorschlagen das toggleLed.state zu einen bool zu machen
imonbln (Gast)
>Der Server sendet hier nichts, weil er auf eingaben wartet. raw_input
Du hast Recht. Das war der Fehler.
Ich habe schon ewig nichts mehr mit Python gemacht und versuche den
Syntax wieder in die vorderen Speicherbereiche meines Gehirns zu bringen
..
Ob es wohl besser wäre eher UDP für's lokale Netzwerk zu nutzen?
Gibt's heutzutage eigentlich noch sowas wie den (x)inetd? Da konnte man
einfach Programme, die über stdin/stdout kommunizieren, in Server
verwandeln. Das Programm brauchte sich dann gar nicht um irgendwelche
Netzwerksachen kümmern.
Marcus schrieb:> Ob es wohl besser wäre eher UDP für's lokale Netzwerk zu nutzen?
Kommt letztendlich darauf an, wie du es verwenden willst. Mit TCP hast
du eher den Charakter einer "Session". Du baust eine Verbindung auf und
kannst darüber nun wie in einer Kommandozeile arbeiten. Wenn du fertig
bist, schließt du die Verbindung wieder.
Bei UDP hast du eher nach dem Prinzip "fire and forget" die Möglichkeit,
ohne den ganzen Verbindungskram einfach Nachrichten hinzuschicken. Wenn
du aber auch in der anderen Richtung übertragen willst, muss dein rpi
irgendwoher wissen, wohin er die Daten schicken muss.
Hey,
Rolf M. schrieb:> Gibt's heutzutage eigentlich noch sowas wie den (x)inetd? Da> konnte man> einfach Programme, die über stdin/stdout kommunizieren, in Server> verwandeln. Das Programm brauchte sich dann gar nicht um irgendwelche> Netzwerksachen kümmern.
netcat (nc)
Ein Lösung wäre evtl. der Einsatz von netcat und dem Linux "spidev"
Kernel Modul.
Mit nc einen Server zu starten, der seine Daten an ein "spidev" piped.
Damit sollte ein einfacher "TCPtoSPI-Proxy" möglich sein.