tcp

19. TCP/IP-KOMMUNIKATION

 

 

DU LERNST HIER...

 

wie du mit wenig Aufwand eine drahtlose Verbindung für den Datenaustausch zwischen zwei Oxocards einrichten kannst.

Damit Oxocard A und Oxocard B miteinander Daten austauschen können, müssen sie über das TCP/IP-Protokoll miteinander verbunden sein. Dazu startet eine Oxocard einen Access Point und einen TCP/IP-Server und die andere verbindet sich als TCP/IP-Client mit ihr.

Access Point
TCP/IP-Server


TCP/IP-Client


Du machst hier Bekanntschaft mit dem Parallel Computing, wo mehrere Rechner gleichzeitig ein Programm ausführen, aber miteinander über einen Kommunikationskanal verbunden sind.

 

 

MUSTERBEISPIELE

 

Der Code für die TCP/IP-Kommunikation ist im Modul radio gekapselt. Du erstellst auf Oxocard A und B eine Instanz von Radio mit unterschiedlichen Parameterwerten 'A' und 'B'. Dann rufst du die Methode waitConnection() auf, die solange blockiert, bis eine erfolgreiche Verbindung zwischen A und B erstellt ist. Mit send(msg) sendest du String-Messages, die beim Partner in einem Empfangsbuffer der Reihe nach gespeichert werden. Du holst mit receive()die älteste Message zurück, wodurch sie im Buffer gelöscht wird.  Ist der Buffer leer, so wird ein leerer String zurückgegeben.

In folgendem Szenario ist A ein Sender, der alle 3 Sekunden eine Zahl an den Empfänger B sendet, die dort auf dem LED-Display erscheint.

Oxocard A (Sender) Oxocard B (Empfänger)
from radio import Radio
from oxocard import *

def initRadio():
    global radio
    dot(7, 0, RED)
    radio = Radio("A")
    radio.on()
    radio.waitConnection()
    dot(7, 0, GREEN)

initRadio()
n = 0
while True:
    radio.send(str(n))
    display(n)
    n += 1
    sleep(3)
from radio import Radio
from oxocard import *

def initRadio():
    global radio
    dot(7, 0, RED)
    radio = Radio("B")
    radio.on()
    radio.waitConnection()
    dot(7, 0, GREEN)

initRadio()
while True:
    data = radio.receive()
    if data != "":
        display(data)
        
        
► In Zwischenablage kopieren ► In Zwischenablage kopieren

Nach diesem erfolgreichen Test kannst du nun echte Messdaten von Oxocard A an Oxocard B übermitteln, beispielsweise von A aktuell gemessene Temperatur. Hier verwendest du den Temperatur-/Feuchtigkeitssensor von Sensirion, du kannst aber auch einen anderen Messsensor einsetzen.

Programm:

from radio import Radio
from oxocard import *
from sht31 import SHT31

def initRadio():
    global radio
    dot(7, 0, RED)
    radio = Radio("A")
    radio.on()
    radio.waitConnection()
    dot(7, 0, GREEN)

initRadio()
sht = SHT31()
while True:
    temp, humi = sht.get_temp_humi()
    t = int(temp + 0.5)
    radio.send(str(t))
    display(t)
    sleep(3)
► In Zwischenablage kopieren

Die miteinander kommunizierenden Oxocards können auch praktisch denselben Code ausführen. Dies ist im Zusammenhang mit Zweipersonenspielen wichtig, wo sich die Spieler A und B nur durch ihre Identifikation unterscheiden. Im folgenden Programm verwendest du beide Oxocard zugleich als Sender und Empfänger. Sie senden periodisch (mit unterschiedlicher Periode) Messages (hier Zahlen 0..99) an die Partnerkarte. Der Unterschied der beiden Programme besteht nur in den im Programmkopf auskommentierten zwei Zeilen.

Programm:

from radio import Radio
from oxocard import *
import time

id = "A"
period = 2
#id = "B"
#period = 5

def initRadio():
    global radio
    dot(7, 0, RED)
    radio = Radio(id)
    radio.on()
    radio.waitConnection()
    dot(7, 0, GREEN)

def sendData():
    global tOld, n
    t = time.time()
    if t - tOld >= period:
        dot(7, 0, GREEN)
        dot(7, 0, BLACK)
        radio.send(n)
        n = (n + 1) % 100
        tOld = t

initRadio()
tOld = time.time()
n = 0
while True:
    data = radio.receive()
    if data != "":
        display(data, BLUE)
    sendData()
► In Zwischenablage kopieren

Das Hauptprogramm ist damit beschäftigt, die ankommende Message auf dem Display auszuschreiben und mit sendData() eine Message zu senden, vorausgesetzt dass die Periodendauer abgelaufen ist. Dazu wird die Methode time() des internen Timers verwendet, der die Systemzeit zurückgibt.

 

 

MERKE DIR...

 

Mit dem Kommunikationsmodul radio können zwei Oxocard miteinander über das WLAN kommunizieren. Auf der einen Oxocard (mit id = "B") läuft ein Access Point und ein TCP/IP-Server und auf der anderen (mit id = "A") ein TCP/IP-Client.

Die Datenübertragung reagiert etwas schneller, wenn die Daten vom Programm mit id = "A" gesendet und von id = "B" empfangen werden. Es spielt keine Rolle, welche Oxocard zuerst startet. Wird aber eines der Programme unterbrochen, so musst du beide Programme wieder neu starten.

 

 

ZUM SELBST LÖSEN

 

 

1.

Erstelle eine Kommunikation zwischen Oxocard A und B derart, dass bei jedem Drücken eines bestimmten Buttons auf dem Sender A dieser Event dem Empfänger B übermittelt wird und dort eine LED kurz blinkt.

2.

Schliesse an dem Empfänger B einen beliebigen Tonerzeuger an. Wenn du auf dem Sender A eine Taste drückst, so ertönt auf B ein Ton, der so lange dauert, bis du die Taste wieder loslässt. Übermittle damit drahtlos eine Message im Morsecode, z.B. von einem Raum in den anderen.

3.

Zwei Benutzer A und B können sich die Farben rot und blau zusenden. Dazu klicken sie den Button BUTTON_L3 für rot und BUTTON_R3 für blau. Beim Partner werden damit alle LEDs in dieser Farbe aufleuchten.

Etwas lustiger ist es, sich zwei Ikonen zuzusenden, die du mit dem OxoEditor erzeugst.

 



 

ZUSATZSTOFF: FERNSTEUERUNG EINES OXOROVERS

 

Du kannst die Kommunikation mit dem Radio-Modul dazu verwenden, um eine Oxocard als Fernsteuerung für einen OxoRover einzusetzen. Dazu konfigurierst du die Oxocard auf dem OxoRover als Empfänger für die Buchstaben "F" (Forward), "B" (Backward), "L": Left, "R": Right und "S": Stop.

Programm:

from oxorover import *
from radio import Radio
from oxocard import *

def initRadio():
    global radio
    insertBigChar("X", RED)
    radio = Radio("B", verbose = True)
    radio.on()
    radio.waitConnection()

def stateChanged():
    global oldState
    if oldState != state:
        oldState = state
        return True
    return False
    
gear = Gear()
state = "stop"
oldState= "stop"
dim(6)
initRadio()
while True:
    if stateChanged():
        if state == "forward":    
            gear.forward()
        elif state == "backward":
            gear.backward()
        elif state == "left":
            gear.leftArc(20)
        elif state == "right":
            gear.rightArc(20)          
        elif state == "stop":
            gear.stop()
    data = radio.receive()
    if data != "":
        insertBigChar(data)
        if data == "F":
            state = "forward"
        elif data == "B":
            state = "backward"
        elif data == "R":
            state = "right"
        elif data == "L":
            state = "left"
        elif data == "S":
            state = "stop"
► In Zwischenablage kopieren

Auf der Fernsteuerung verwendest du 5 Buttons, die beim Drücken einen der Buchstaben F, B, L, R, S senden.

Programm:

from radio import Radio
from oxocard import *
from oxobutton import *

def initRadio():
    global radio
    insertBigChar("X", RED)
    radio = Radio("A")
    radio.on()
    radio.waitConnection()
    radio.send("S")
    insertBigChar("S")

btnForward = Button(BUTTON_R1) 
btnBackward = Button(BUTTON_R2) 
btnStop = Button(BUTTON_R3) 
btnLeft = Button(BUTTON_L2) 
btnRight = Button(BUTTON_L3) 
initRadio()

while True:
    if btnStop.wasPressed():
        radio.send("S")
        insertBigChar("S")
    elif btnForward.wasPressed():
        radio.send("F")
        insertBigChar("F")
    elif btnBackward.wasPressed():
        radio.send("B")
        insertBigChar("B")
    elif btnLeft.wasPressed():
        radio.send("L")
        insertBigChar("L")
    elif btnRight.wasPressed():
        radio.send("R")
        insertBigChar("R")
► In Zwischenablage kopieren

Zur Kontrolle werden die Buchstaben auf dem Sender und Empfänger auf dem LED-Display angezeigt.