uart

18. SERIELLE SCHNITTSTELLE (UART) UND GPS

 

 

DU LERNST HIER...

 

wie du ein Gerät über eine serielle Schnittstelle anschliessen kannst. Als wichtige Anwendung verwendest du ein GPS-Modul zur Lokalisierung des aktuellen Standorts und stellst die Daten über das Internet zur Verfügung.

 

 

DAS RS-232-PROTOKOLL

 

Beim RS232C-Protokoll werden die 0-1-Werte eines Bytes zeitlich hintereinander übermittelt, wobei die einzelnen Bits eine bestimmte zeitliche Dauer haben, die durch die Baudrate (bits/s) festgelegt ist.

Üblich sind die Werte 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 Baud (und höher). Für eine Kommunikation zwischen dem Mikrocontroller und einem seriellen Gerät sind 3 Leitungen nötig: Ein GND, eine Datenleitung für den Datenstrom vom Controller zum Gerät (Transmit, TX) und eine Datenleitung für den Datenstrom vom Gerät zum Controller (Receive, RX). Auf dem ESP32-Mikrocontroller können fast alle IO-Ports als RX/TX definiert werden. Bei der Verwendung der Oxocard verwendest du die Ports IO19 als RX und IO18 als TX, die am GPIO-Stecker oben an der Karte zugänglich sind.

 

 


 

In MicroPython wird die serielle Kommunikation durch die Klasse UART modelliert. Dabei fasst man die Schnittstelle als ein Objekt der Klasse UART auf und gibt im Konstruktor  eine ID, die Baudrate sowie die verwendeten TX- und RX-Ports an (als ID muss auf der Oxocard 1 gewählt werden). Mit der Methode write(data) sendest du einen Bytearray data auf die Schnittstelle. Empfangene Daten werden in einem Receiverbuffer gespeichert. Mit any() erhältst du die Anzahl empfangener Datenbytes  und mit data = read(nbBytes) holst du sie ab.
Im Zusammenhang mit RS-232 ist es üblich, zum Test  die Buchsen TX und RX zu verbinden, sodass gesendete Daten gerade wieder empfangen werden. Das folgende Programm schreibt diese auf dem LED-Display als Scrolltext aus.

Programm:

from machine import UART
from time import sleep
from oxocard import *

uart = UART(1, baudrate = 9600, tx = 18, rx = 19) 
txdata = 'Hello Python'
uart.write(txdata)
sleep(1)
nbChars = uart.any()
rxdata = uart.read(nbChars) # bytes
rxStr = rxdata.decode('utf-8') 
bigTextScroll(rxStr)
► In Zwischenablage kopieren

 

 

GLOBAL POSITION SYSTEM (GPS)

 

Ein GPS-Modul bestimmt die Entfernungen zu mindestens 3 GPS-Satelliten und berechnet daraus die geografische Position mit Triangulation.

Hier wird ein GPS-Modul mit dem SIMCOM SIM28-Chip verwendet, das auf einem Breakout-Board von Seed mit einem analogen Grove-Anschluss erhältlich ist. Man schneidet ein Grove-Kabel entzwei und verbindet 3 Adern (schwarz, rot und gelb) mit dem GPIO-Port. (Es gibt ähnliche preisgünstige Module auf eBay.) Die Antenne musst du so anordnen, dass ein Empfang der GPS-Satelliten möglich ist, also draussen oder in der Nähe eines südlich gerichteten Fensters.

Nach dem Anlegen der Versorgungsspannung musst du einige Minuten warten, bis die GPS-Daten zur Verfügung stehen. Das Modul sendet sie ungefähr alle Sekunden über die serielle Schnittstelle zeilenweise als ASCII-Zeichen in einem speziellen Format, genannt NMEA Messages. Es ist etwas mühsam, die Datenstrings in ein lesbares Format zu konvertieren. Im folgenden Programm wird dies in der Funktion parseGPS() gemacht und die GPS-Informationen dann auf der Konsole ausgeschrieben.

 

Programm:

from machine import UART

def parseGPS(data):
    s = data.split(",")
    if s[6] == '0':
        print("no GPS data available")
        return None       
    time = s[1][0:2] + ":" + s[1][2:4] + ":" + s[1][4:6]
    lat = convert(s[2])
    dirLat = s[3]
    lon = convert(s[4])
    dirLon = s[5]
    alt = s[9] + " m"
    sat = s[7]
    return time, lat, dirLat, lon, dirLon, alt, sat

def convert(coord):
    # DDDMM.MMMMM -> DD deg MM.MMMMM min
    v = coord.split(".")
    head = v[0]
    tail =  v[1]
    deg = head[0:-2]
    min = head[-2:]
    return deg + " deg " + min + "." + tail + " min"

uart = UART(1, baudrate = 9600, rx = 19) # tx not used
print("starting")
inLine = False
while True:
    ch = uart.read(1)
    if ch == None:
        continue
    if ch == b'$':
        line = bytearray()
        inLine = True
    if inLine:
        line += ch
        if ch == b'\n':
            inLine = False
            line = bytes(line).decode('utf-8')
            #print(line)
            if line[0:6] == "$GPGGA": 
                parsed = parseGPS(line)
                if parsed != None:
                    time, lat, dirLat, lon, dirLon, alt, sat = parsed 
                    print("Time(UTC): %s--Latitude:%s(%s)--Longitude:%s(%s)\
-- Altitute:%s--(%s satellites)" %(time, lat, dirLat, lon, dirLon, alt, sat)) 
► In Zwischenablage kopieren

 

 

MERKE DIR...

 

Das RS232-Protokoll verwendet eine serielle Datenübertragung, bei dem die binären Daten bitweise zeitlich hintereinander mit einer zwischen Sender- und Empfänger vereinbarten Geschwindigkeit (Baudrate) übertragen werden.  Auch hier wird die objektorientierte Programmierung (OOP) erfolgreich eingesetzt und die Schnittstelle mit einem Objekt der Klasse UART modelliert.

 

 

ZUM SELBST LÖSEN

 

 

1.

Starte auf der Oxocard einen Webserver und übermittle die GPS-Informationen bei einem GET-Request im HTML-Format an einen Browser. Verwende dabei deine Kenntnisse aus dem Kapitel Webserver. Der HTML-String könnte lauten:

html = """<!DOCTYPE html>
<html>
  <head> <title>Oxocard IoT</title> 
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="refresh" content="5" >
  </head>
  <body> 
     <h1>Oxocard IoT</h1>
     Time: %s UTC<br>
     Lattidude: %s<br>
     Longitude: %s<br>
     Altitude: %s<br>
     #Satellites: %s<br>
  </body>
</html>
"""

2.

Erstelle einen GPS-Tracker, indem du die GPS-Daten in einer Cloud speicherst, damit sie von irgendwo über das Internet abrufbar sind. Verwende dazu deine Kenntnisse aus dem Kapitel Cloudcomputing.

3.*

Statt die Oxocard als Access Point zu verwenden, kannst du der Oxocard über ein Smartphone Zugang zum Internet geben, indem du dieses als Access Point konfigurierst, das seine Internet-Verbindung (über 3G/4G/5G) frei gibt (Tethering). Damit kannst du einen mobilen GPS-Tracker bauen, der von irgendwo den aktuellen Standort in der Cloud speichert.