DesignSpark Electrical Logolinkedin
Menu Suche
Ask a Question

20 Aug 2019, 14:39

Embedded Networking mit dem Cypress WiFi-BT Pioneer Kit – auf die einfache Art

Da in der Werbung derzeit überall so viel Wert auf „smarte“ Geräte gelegt wird, entspricht es wohl kaum dem Trend zu sagen, dass nicht jede „verbundene“ Anwendung die Cloud braucht.

Manchmal reicht es aus, wenn ein Embedded-Gerät einfach Daten von einem bekannten Standort abruft oder über Ihr lokales Netzwerk mit anderen Geräten kommuniziert. Vielleicht muss nur jemand Ihr Gerät über ein lokales Netzwerk abfragen, z. B. mit einem Webbrowser.

Dank einiger leistungsstarker Bibliotheken lassen sich derartige Interaktionen in Python mit nur wenigen Codezeilen erstellen. So können Sie ganz einfach verschiedene Ansätze ausprobieren und herausfinden, welcher am besten zu Ihnen passt. Und das in der gleichen Zeit, in der Sie normalerweise eine einzige dieser Interaktionen codieren würden.

Die Zerynth-Toolchain erleichtert diesen Vorgang zusätzlich mit einer Vielzahl praktischer Codebeispiele, auf denen Sie Ihre eigenen maßgeschneiderten Anwendungen aufbauen können. Einige davon werden wir in unserem heutigen Artikel mithilfe des Cypress WiFi-BT Pioneer Kit (175-4669) untersuchen – des neuesten Mitglieds der „Familie“ von Zerynth unterstützter Platinen.

Erste Schritte

Ich gehe davon aus, dass Sie Zerynth bereits installiert und die Anleitung für die Einrichtung Ihres Pioneer Kit, einschließlich Anschluss, Registrierung und Virtualisierung Ihres Geräts, befolgt haben.

Wenn dies geschehen ist, können wir alle Beispielprogramme auf die Platine laden. Wie ich bereits erwähnt habe, gibt es viele davon. Sie finden sie, wenn Sie auf das Glühbirnensymbol links neben dem IDE-Projektfenster klicken. Anschließend wählen Sie eines der Beispiele aus dem Abschnitt „Networking“ aus:

Mini-Webserver

Ich habe mit dem Beispiel für den Mini-Webserver angefangen, da es uns die Grundlagen zeigt, wie Informationen einem menschlichen Benutzer per Fernzugriff in einem Format präsentiert werden können, das er mit HTML lesen kann. Um dieses Beispiel selbst zu verwenden, müssen wir auf die Schaltfläche „Clone“ (Klonen) klicken und es in unserem eigenen Projektverzeichnis speichern. Wir können das Projekt umbenennen und an einem beliebigen Ort auf unserer Festplatte ablegen.

Da wir jetzt unser eigenes Exemplar haben, können wir es verändern, um mit unserer Platine zu arbeiten. Es gibt nur zwei Dinge, die wir tun müssen:

  1. Den richtigen Treiber für das WLAN-Gerät auf der Platine importieren. Es handelt sich bloß um eine einzige Codezeile.
  2. Dem Programm die Anmeldedaten für unser Netzwerk geben, damit es sich einloggen kann. Ich habe den Code etwas mehr als nötig geändert, da ich es mag, wenn diese Informationen oben in der Programmdatei stehen, sodass ich sie leicht finden und je nach Standort ändern kann.

Probieren wir es aus. 

###############################################################################
# Mini Web Server
#
# Created by Zerynth Team 2015 CC
# Authors: G. Baldi, D. Mazzei
###############################################################################

# import streams & socket
import streams
import socket

# import the wifi interface
# the wifi module needs a networking driver to be loaded
# in order to control the board hardware.
from wireless import wifi
from murata.lbee5kl1dx import lbee5kl1dx as wifi_driver

NetName = "Network_Name"
NetPassword = "Network_Password"


streams.serial()

# init the wifi driver!
# The driver automatically registers itself to the wifi interface
# with the correct configuration for the selected board
wifi_driver.auto_init()
# use the wifi interface to link to the Access Point
# change network name, security and password as needed
print("Establishing Link...")
try:
    # FOR THIS EXAMPLE TO WORK, "Network-Name" AND "Wifi-Password" MUST BE SET
    # TO MATCH YOUR ACTUAL NETWORK CONFIGURATION
    wifi.link(NetName,wifi.WIFI_WPA2,NetPassword)
except Exception as e:
    print("ooops, something wrong while linking :(", e)
    while True:
        sleep(1000)

# Yes! we are connected
print("Linked!")

# Let's print our ip, it will be needed soon
info = wifi.link_info()
print("My IP is:",info[0])

# Now let's create a socket and listen for incoming connections on port 80
sock = socket.socket()
sock.bind(80)
sock.listen()


while True:
    try:
        # Type in your browser the board ip!
        print("Waiting for connection...")
        # here we wait for a connection
        clientsock,addr = sock.accept()
        print("Incoming connection from",addr)

        # yes! a connection is ready to use
        # first let's create a SocketStream
        # it's like a serial stream, but with a socket underneath.
        # This way we can read and print to the socket
        client = streams.SocketStream(clientsock)

        # let's read all the HTTP headers from the browser
        # stop when a blank line is received
        line = client.readline()
        while line!="\n" and line!="\r\n":
            line = client.readline()
        print("HTTP request received!")

        # let's now send our headers (very minimal)
        # hint: \n is added by print
        print("HTTP/1.1 200 OK\r",stream=client)
        print("Content-Type: text/html\r",stream=client)
        print("Connection: close\r\n\r",stream=client)
        # see? as easy as print!
        print("<html><body>Hello Zerynth!",random(0,100),"</body></html>",stream=client)
        # close connection and go waiting for another one
        client.close()
    except Exception as e:
        print("ooops, something wrong:",e)

Hinweis: Wenn Sie Ihre Platine nicht zur Hand haben, können Sie Ihren Code dennoch kompilieren (oder „überprüfen“), um sicherzugehen, dass die Syntax korrekt ist. Klicken Sie hierzu auf das Feld „Device:“ (Gerät:) über dem Hauptfenster. Klicken Sie auf „Select virtual device“ (Virtuelles Gerät auswählen) und wählen Sie (in unserem Fall) „PSoC6 WiFi-Bt Pioneer Kit“ und die Schaltfläche „Set“ (Festlegen) unten in der Liste aus. Dann ist alles bereit. Klicken Sie auf die Schaltfläche „Verify“ (Überprüfen) (das ist die linke der drei Schaltflächen links neben dem Gerätefeld). Ihr Code wird kompiliert – hoffentlich ohne Fehler.

Damit der Code auf die Platine gelangt, müssen wir die Schaltfläche „Upload“ (Hochladen) anklicken, d. h. die mittlere der drei Schaltflächen links neben dem Gerätefeld. Dadurch wird der Code kompiliert und hochgeladen. Bei diesem Vorgang wird an einem bestimmten Punkt der Speicher der Platine gelöscht, bevor das neue Programm geladen werden kann:

Dieser automatische Löschvorgang kann eine Weile dauern. Seien Sie also nicht allzu beunruhigt, wenn etwa 30 Sekunden lang nichts passiert.

Das geladene Programm wird gestartet und Sie können den Status anzeigen, indem Sie mit der rechten der Schaltflächen rechts neben dem Gerätefeld ein Konsolenfenster öffnen.

Wenn wir im selben Netzwerk wie unser PSoC6 einen Webbrowser auf einem PC öffnen und die IP-Adresse aus dem Konsolenfenster in die Adresszeile eingeben, erhalten wir die folgende Meldung:

Sehr gut! Wir haben die erwartete Meldung mit Zufallszahl erhalten. Nach demselben einfachen Prinzip können wir jetzt etwas anderes ausprobieren.

HTTP-Uhrzeit

Dieses Mal wollen wir ein paar Daten per Fernzugriff abrufen. Wie wäre es mit der Uhrzeit? Wie zuvor öffnen wir ein Beispiel:

Anschließend können wir das Beispiel klonen und die gleichen Änderungen wie zuvor vornehmen:

Wenn das Programm geladen ist, kontaktiert es den Server und ruft die Zeitdaten ab, um sie in unserem Konsolenfenster anzuzeigen:

Uhrzeit vom Server

Natürlich können wir auf Grundlage dieser Codebeispiele schnell eigene Beispielprogramme für die Dinge erstellen, die wir gerne tun möchten. Vielleicht möchten wir, dass unser Gerät Daten von einem Server abruft und dem Benutzer in einem Webbrowser anzeigt? Dann könnten wir die Beispiele einfach folgendermaßen kombinieren:

###############################################################################
# Mini Time Web Server
###############################################################################

# import streams & socket
import streams
import socket
import json
import requests

# import the wifi interface
from wireless import wifi
from murata.lbee5kl1dx import lbee5kl1dx as wifi_driver
#from espressif.esp32net import esp32wifi as wifi_driver

NetName = "Network_Name"
NetPassword = "Network_Password"

def getTime():
    for i in range(3):
        try:
            print("Trying to connect to time server...")
            # go get that time!
            # url resolution and http protocol handling are hidden inside the requests module
            response = requests.get('http://now.zerynth.com/')
            
            # let's check the http response status: if different than 200, something went wrong
            print("Http Status:",response.status)
            # if we get here, there has been no exception, exit the loop
            
            js = json.loads(response.content)
            StrDate = ("Date:",js['now']['rfc2822'][:16])
            StrTime = ("Time:",js['now']['rfc2822'][17:])
            return StrDate,StrTime
        except Exception as e:
            print("Error while getting date and time")
            print(e)

            
streams.serial()

# init the wifi driver!
# The driver automatically registers itself to the wifi interface
# with the correct configuration for the selected board
wifi_driver.auto_init()
# use the wifi interface to link to the Access Point
# change network name, security and password as needed
print("Establishing Link...")
try:
    # FOR THIS EXAMPLE TO WORK, "Network-Name" AND "Wifi-Password" MUST BE SET
    # TO MATCH YOUR ACTUAL NETWORK CONFIGURATION
    wifi.link(NetName, wifi.WIFI_WPA2, NetPassword)
except Exception as e:
    print("ooops, something wrong while linking :(", e)
    while True:
        sleep(1000)

# Yes! we are connected
print("Linked!")

# Let's print our ip, it will be needed soon
info = wifi.link_info()
print("My IP is:",info[0])

# Now let's create a socket and listen for incoming connections on port 80
sock = socket.socket()
sock.bind(80)
sock.listen()


while True:
    try:
        # Type in your browser the board ip!
        print("Waiting for connection...")
        # here we wait for a connection
        clientsock,addr = sock.accept()
        print("Incoming connection from",addr)

        # yes! a connection is ready to use
        # first let's create a SocketStream
        # it's like a serial stream, but with a socket underneath.
        # This way we can read and print to the socket
        client = streams.SocketStream(clientsock)

        # let's read all the HTTP headers from the browser
        # stop when a blank line is received
        line = client.readline()
        while line!="\n" and line!="\r\n":
            line = client.readline()
        print("HTTP request received!")


        # let's now send our headers (very minimal)
        # hint: \n is added by print
        print("HTTP/1.1 200 OK\r",stream=client)
        print("Content-Type: text/html\r",stream=client)
        print("Connection: close\r\n\r",stream=client)
        StrD, StrT = getTime()

        # see? as easy as print!
        print(StrD,"",stream=client)
        print(StrT,"",stream=client)
        
        print("\r\n\r",stream=client)
        # close connection and go waiting for another one
        client.close()
    except Exception as e:
        print("ooops, something wrong:",e)

Probieren Sie dieses Beispiel selbst auf Ihrer eigenen Plattform aus. Mal sehen, wer als erster einen Kommentar mit Link zur Programmausgabe veröffentlicht!

Wenn wir dies als Grundlage nehmen, können wir Erweiterungen für die Daten, die wir eigentlich abrufen möchten (z. B. die neueste verfügbare Firmware-Version), und das Erscheinungsbild, das wir am Ende in unserem Browser wünschen (z. B. unsere aktuelle Firmware im Vergleich zur neuesten Version), erstellen.

Abschließende Worte

Es macht mir immer Spaß, kurz ein Python-Programm auf Zerynth laufen zu lassen, egal, mit welcher Hardwareplattform. Es geht schnell, macht Spaß und bringt sofort Ergebnisse.

Mark completed his Electronic Engineering degree in 1991 and went on to work in real-time digital signal processing applications engineering, later moving into technical marketing.

20 Aug 2019, 14:39

Kommentare