# Plotten von Motordaten

Um interessante Korrelationen hervorzuheben. So kann man Gyro-Werte, Grad-Zahlen von Motoren, Geschwindigkeiten von Motoren oder Messwerte der Lichtsensoren graphisch anzeigen.

# Wie funktioniert der Plot?

Es geht darum, wie man es einrichten kann, Daten auf einem Plot anzuzeigen. Um gesetzt wurde das ganze erstmal über [Matplotlib](https://matplotlib.org/) und Tigerente.

```python
import numpy as np
import matplotlib.pyplot as plt
import os
import time

plt.style.use('dark_background') #am wichtigsten ;)
fig, ax = plt.subplots()

ts, dt = [], []

with open('C://Users//Finn//.config//tigerente//info.log', 'r') as f: #öffnen der .log Datei
    while f.readline() != "": ... #alten Linien "überlesen"
    while True:
        last_line = f.readline() #neue Linie einlesen
        print(last_line.strip()) #nur der Wert; muss angepasst werden, je nach dem, wie man die Daten schickt
        if last_line[:11] == "INFO:root:>": #nach dem > kommen die Daten
            print(dt)
            dt.append(int(last_line[11:].strip())) #nur der Wert; muss angepasst werden, je nach dem, wie man die Daten schickt
            ts.append(time.time()) #timestamp für die x-Achse

            if len(dt)>10*5: #alten Werte werden wieder gelöscht
                dt.pop(0)
                ts.pop(0)
        ax.clear()
        ax.set_ylim(-100, 100) #je nach dem Was man sich anzeigen will, kann man das hier ändern
        ax.plot(ts, dt) #Einstellen der Werte
        plt.pause(0.05) #Anzeigen der Werte
    plt.show()

```

Auf der Seite des Spikes braucht man nur:

```python
print(">", <dein_Wert>, sep="")
```

Und natürlich die Verbindung via Tigerente

# Auslesen des Motorspiels

Der Motor hat ein gewisses Spiel, dieses kann man aber auslesen.[![Screenshot 2026-06-26 134047.png](https://bookstack.gsg-robots.de/uploads/images/gallery/2026-06/scaled-1680-/screenshot-2026-06-26-134047.png)](https://bookstack.gsg-robots.de/uploads/images/gallery/2026-06/screenshot-2026-06-26-134047.png)

Man sieht also, dass der Motor ein Spiel von circa 8° hat.

# Plotten von Geschwindigkeitsänderungen und Stop on Resistance

Hierbei geht es darum, die Geschwindigkeit von Motoren auszulesen und Veränderungen z.B. bei Blockaden zu erkennen.

```python
import hub
import motor
import device
import time

async def loop():
    motor.run(hub.port.A, 1000) #Geschwindigkeit des Motors auf 1000 stellen
    while not hub.button.pressed(hub.button.POWER):
        print(">", device.data(hub.port.A)[0], sep="") #Übertragung der Geschwindigkeit
        time.sleep(0.2) #Damit es möglichst live, ist. Wenn zu niedrig kommt die BT-Übertragung nicht hinterher
    while hub.button.pressed(hub.button.POWER):
        ...

```

Das ist ein einfach Aufbau, der die Geschwindigkeit des Motors ausließt. Die gemessene Geschwindigkeit ist immer 1/10 so groß, wie die eingestellte.

Damit kann man jetzt zum Beispiel für präzise Outputs ([Zum Artikel](https://bookstack.gsg-robots.de/books/experimente/chapter/prazise-ausgange "Präzise Ausgänge")) richtig nullen, ohne unterschiedlich am Ende zu stehen und zu stark zu verziehen.

```python
import hub
import motor
import device
import time

def until_stalled(speed, limfuck=0.8): #Funktion: speed: Geschwindigkeit vom Motor, limfuck: Prozent der Zielgeschwindigkeit, ab der gestoppt werden soll
    lim = abs(speed) / 10 * limfuck #limfuck * 10, weil die Geschwindigkeit nur 1/10 so groß ist
    motor.run(hub.port.A, speed)
    time.sleep(0.5) #Kann man noch besser machen, damit der Motor Zeit hat zu beschleunigen
    while not hub.button.pressed(hub.button.POWER):
        print(">", device.data(hub.port.A)[0], sep="") #Für BT-Übertragung
        
        sped = device.data(hub.port.A)[0] #gemessene Geschwindigkeit
        if lim > sped > -lim: #Überprüfun, ob die Geschwingigkeit zu niedrig ist
            break
        time.sleep(0.2) #Damit nicht zu viel via BT übertragen wird, sollte man aus dem Fenster schmeißen, wenn man keine BT-Übertragung macht
        
    
    motor.run(hub.port.A, 0) Motor wieder  ausschalten
    return

async def loop():
    while not hub.button.pressed(hub.button.POWER): #Unendlich vor und zurück
        until_stalled(500)
        until_stalled(-500)

    while hub.button.pressed(hub.button.POWER): #Debounce
        ...

```

# Fazit - Stop on Resistance

Verwendungszwecke:

- Wenn man präzise Ausgänge braucht ([Zum Artikel](https://bookstack.gsg-robots.de/books/experimente/chapter/prazise-ausgange "Präzise Ausgänge"))
- Um zu Überprüfen, ob eine Motorbewegung geklappt hat:  
    
    - wenn nicht nochmal irgendwas machen, z.B.: Wackeln
- Für Motorbewegungen die nach einer bestimmten Kraft Verwendung aufhören sollen

Probleme:

- Verzieht immer noch bisschen
- einfach nur 0.5 Sekunden warten, vor Überprüfung

ToDo:

- am echten Roboter testen

Rating: ⭐⭐⭐⭐⭐ von 5

# Fazit - Plotten

Verwendungszwecke:

- Motordaten - z.B.: um Stop on Resistance zu konfigurieren
- Lichtsensordaten - z.B.: für Sonar oder C3PO
- Gyrodaten - z.B.: um PID-Werte zu konfigurieren (oder LQR)

Probleme:

- gewisse Zeitverzögerung durch BT
- man braucht ein extra Programm

ToDo:

- ohne print zu machen

Rating: ⭐⭐⭐⭐⭐ von 5