Hier zunächst der Code von rys352a.py :
Code: Alles auswählen
class RYS352A():
def __init__(self, uart, ticks_ms):
self.uart = uart
self.ticks_ms = ticks_ms
self.timeout = 2000 # Timeout-Zeit in ms
def get_data(self, data_id):
try:
time0 = self.ticks_ms()
self.uart.readline()
while True:
gnss_list = []
data = self.uart.readline() # Bytestring
data_str = str(data, 'UTF-8') # String
row = data_str.split(',')
id = row.pop(0)
if id == data_id:
gnss_list = row
break
if (self.ticks_ms() - time0) > self.timeout:
print('Error: ' + data_id + '-Timeout')
break
return gnss_list
except BaseException as err:
print('Fehler:', err)
return []
def send_cmd(self, cmd):
cmd = bytes(cmd, 'UTF-8')
self.uart.write(cmd + b'\r\n')
def read_item(self):
data = self.uart.readline() # Bytestring
data_str = str(data, 'UTF-8') # String
return data_str
Und so wird eine Instanz gnss von RYS352A erzeugt:
Code: Alles auswählen
from machine import UART
from utime import ticks_ms
from rys352a import RYS352A
uart = UART(1, baudrate=115_200, bits=8, parity=None, stop=1, tx=12, rx=13, rts=-1, cts=-1, txbuf=256, rxbuf=256, timeout=5000, timeout_char=2)
gnss = RYS352A(uart, ticks_ms)
Mit Hilfe des Konstruktors werden uart und ticks_ms zu Eigenschaften der RYS352A-Klasse. Als weitere Eigenschaft wird noch timeout (mit dem Standardwert 2000) festgelegt. Dieser Wert kann vom Benutzer geändert werden, z. B. mit
gnns.timeout = 3500
Werfen wir jetzt einen Blick auf die Methoden unserer RYS352A-Klasse:
- get_data entspricht im Wesentlichen der Methode get_data (mit Timeout), welche wir im Kapitel 2 vorgestellt haben.
- Mit send_cmd können wir sogenannte PAIR-Kommandos an das RYS352A-Modul senden. Damit kann man z. B. bestimmen, welche Satellitensysteme benutzt werden sollen. Mehr dazu im Kapitel 4!
- Mit read_item können wir den gerade im Lesepuffer befindlichen Datensatz (als String) erhalten.
Eine Anwendung der RYS352A-Klasse
Mit der soeben vorgestellten Klasse können wir recht einfach GNSS-Daten auf dem Display anzeigen lassen (s. Abb. 1).
Zunächst die nötigen Importe und Instanziierungen:
Code: Alles auswählen
from machine import UART
from time import sleep
from utime import ticks_ms
from machine import Pin, SPI
import vga1_16x16 as font1
import vga2_8x16 as font2
import st7789
from rys352a import RYS352A
uart = UART(1, baudrate=115_200, bits=8, parity=None, stop=1, tx=12, rx=13, rts=-1, cts=-1, txbuf=256, rxbuf=256, timeout=5000, timeout_char=2)
id = 1 # id = 2 z. B. für Firmware V1.12 u. V1.14, id = 1 für V1.18 u. V.1.20
spi = SPI(id, baudrate=20_000_000, polarity=1, sck=Pin(18), mosi=Pin(19))
display = st7789.ST7789(spi, 135, 240, reset=Pin(23, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(16, Pin.OUT), backlight=Pin(4, Pin.OUT), rotation=3)
display.init()
display.fill(0)
display.rect(0,0,239,24,st7789.WHITE) # Titel mit Rahmen...
display.text(font1, 'TTGO-GNSS', 48, 5)
gnss = RYS352A(uart, ticks_ms)
Die in Abb. 1 aufgeführten Daten entnehmen wir den Datensätzen $GNRMC, $GNGGA und $GNVTG. Die zugehörigen Datensatz-Listen werden im Rahmen einer Endlos-Schleife ermittelt; deren Elemente liefern uns jeweils die gewünschten Parameter:
Code: Alles auswählen
while True:
RMC_list = gnss.get_data('$GNRMC')
GGA_list = gnss.get_data('$GNGGA')
VTG_list = gnss.get_data('$GNVTG')
# Block 1 (Koordinaten)
display.rect(0, 35, 239, 24, st7789.RED)
display.text(font2,N_S_to_degree(RMC_list[2]),5,40)
display.text(font2, RMC_list[3], 95, 40)
display.text(font2,E_W_to_degree(RMC_list[4]),130,40)
display.text(font2, RMC_list[5], 225, 40)
# Block 2 (Uhrzeit, Anzahl der Satelliten)
display.rect(0, 70, 239, 24, st7789.BLUE)
display.text(font2, 'Zeit: ' + time_to_h_min_s(GGA_list[0]), 5, 75)
display.text(font2, 'Anz. Sat.: ' + GGA_list[6], 130, 75)
# Block 3 (Höhe bzgl. Geoid, Geschwindigkeit über Grund)
display.rect(0, 105, 239, 24, st7789.GREEN)
display.text(font2, 'h(Geo): ' + GGA_list[8] + ' m', 5, 110)
display.text(font2, 'v: ' + VTG_list[6] + ' km/h', 130, 110)
sleep(2)
Dabei bietet sich bei einigen Parametern eine Umformatierung an: So schreiben wir statt der (abkürzenden) NMEA-Breiten-Angabe 5110.6341 üblicherweise 51̊ 10,6341'.
Die entsprechende Umformatierung geschieht durch die folgende Funktion:
Code: Alles auswählen
def N_S_to_degree(s) -> bytes: # Angaben für N/S in Grad umwandeln
v1 = s[0:2]
v2 = s[2:4]
v3 = s[5:9]
return bytes(v1, 'UTF-8')+b'\xF8'+bytes(v2+'.'+v3+chr(39), 'UTF-8')
Die text-Methode von display kann übrigens sowohl mit Strings als auch mit Byte-Strings arbeiten; eine Konvertierung brauchen wir hier also nicht vornehmen.
Für die Umformatierung der Längen- bzw. Zeit-Angaben setzen wir die folgenden beiden Funktionen ein:
Code: Alles auswählen
def E_W_to_degree(s) -> bytes: # Angaben für E/W in Grad umwandeln
v1 = s[0:3]
v2 = s[3:5]
v3 = s[6:10]
return bytes(v1, 'UTF-8')+b'\xF8'+bytes(v2+'.'+v3+chr(39), 'UTF-8')
def time_to_h_min_s(s) -> bytes: # Angaben in hh:mm:ss umwandeln
v1 = s[0:2]
v2 = s[2:4]
v3 = s[4:6]
return v1+':'+v2+':'+v3
Das gesamte Programm finden Sie in der Anlage unter dem Dateinamen RYS352A_Position_Datetime_more_Display.py.
.