Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

MicroPython und das Mapping von Sensorwerten: So funktioniert’s

Posted on 19. Juni 202314. Juni 2023 by Stefan Draeger

Herzlich willkommen zu meinem neuesten Blogbeitrag, in dem es um das Mapping von Sensorwerten mit MicroPython geht! Heute werde ich euch eine Funktion vorstellen und erklären, mit der ihr einen Messbereich von einem Sensor auf einen anderen umwandeln könnt. Diese Funktion ist besonders nützlich beim Visualisieren von Umweltsensoren und anderen Messwerten. Ich werde euch Schritt für Schritt durch den Prozess führen und euch zeigen, wie ihr diese Funktion unter Verwendung von MicroPython in euren Projekten nutzen könnt.

Wie man Sensorwerte am Mikrocontroller Calliope Mini im Open Roberta Lab mappt habe ich dir bereits im Beitrag Open Roberta Lab – analoges Signal auf PWM mappen erläutert. Hier greife ich auf die gesammelte Erkenntnis zurück und schreibe den Code für MicroPython um.

Wozu benötigen wir das Mapping von Sensorwerten in MicroPython?

Nehmen wir an du hast einen Temperatursensor welcher einen Messbereich von 0 °C bis 125 °C hat und eine LED Balkenanzeige mit 24 Segmenten. Dann könntest du nun den Messbereich des Sensors (0-125) auf die 24 LEDs mappen und somit je nach Temperatur die LEDs aktivieren.

Ein anderer Fall wäre ein Servomotor mit einem maximalen Winkel von 180° welchen du mit einem analogen Sensor (Drehpotentiometer, Joystick etc.) bewegen möchtest. Dann musst du in diesem Fall den Drehbereich des Servos 0° bis 180° auf die möglichen analogen Werte 0 bis, 65535 mappen.

Ein kleiner Aufbau mit dem Raspberry Pi Pico

Damit wir unsere Funktion testen können, benötigen wir einen Mikrocontroller, auf welchen MicroPython läuft. Hier kann man sich selber einen ESP32 flashen oder man verwendet einen Raspberry Pi Pico / Pico W welcher das ganze schon von hause aus kann.

Ich möchte das zuletzt genannte Beispiel aufgreifen und einen Servomotor mit einem Drehpotentiometer steuern. Ein recht kleines Projekt, welches jedoch sehr gut verdeutlicht, wie die Funktion map welche wir schreiben, möchten funktioniert.

Schaltung - Raspberry Pi Pico mit Servomotor SG90 & Drehpotentiometer
Schaltung – Raspberry Pi Pico mit Servomotor SG90 & Drehpotentiometer

Was benötigen wir für den Aufbau der Schaltung?

Für den Nachbau der Schaltung benötigst du:

  • einen Raspberry Pi Pico / Pico W,
  • ein Micro-USB Datenkabel,
  • einen Servomotor SG90,
  • einen Drehpotentiometer,
  • sechs Breadboardkabel,
  • ein 400 Pin Breadboard

Pinout des Raspberry Pi Pico

Für die Unterstützung beim Aufbau der Schaltung gebe ich dir hier noch das Pinout des Raspberry Pi Pico an die Hand.

Pinout des Raspberry PI Pico
Pinout des Raspberry PI Pico

Programmieren der Funktion map in MicroPython zum Erzeugen eines Mapping von Sensorwerten

In der Arduino IDE gibt es bereits die Funktion map welche genau das macht, was wir hier nachbauen möchten.

Die Parameter sind:

  • value – der Wert, welcher verarbeitet werden soll,
  • fromLow – die untere Grenze des aktuellen Bereichs des Werts,
  • fromHigh – die obere Grenze des aktuellen Bereichs des Wertes,
  • toLow – die untere Grenze des Zielbereichs für den Wert,
  • toHigh – die obere Grenze des Zielbereichs des Wertes

Dieses übernehmen wir für die neue Funktion.

def map(value, fromLow, fromHigh, toLow, toHigh):
  return round((value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow)

Hier ist eine schrittweise Erklärung der Funktionsweise:

  1. (value - fromLow): Dieser Ausdruck berechnet die Differenz zwischen dem Eingabewert und dem unteren Grenzwert des Eingabebereichs (fromLow). Dieser Schritt normalisiert den Eingabewert auf den Bereich von 0 bis (fromHigh – fromLow).
  2. (toHigh - toLow): Dieser Ausdruck gibt die Größe des Ausgabebereichs an, also die Differenz zwischen dem oberen und unteren Grenzwert des Ausgabebereichs. Dieser Schritt bestimmt die Skalierung des transformierten Werts.
  3. (fromHigh - fromLow): Dieser Ausdruck gibt die Größe des Eingabebereichs an, also die Differenz zwischen dem oberen und unteren Grenzwert des Eingabebereichs. Dieser Schritt bestimmt die relative Position des Eingabewerts innerhalb des Eingabebereichs.
  4. ((value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow): Dieser Ausdruck führt die eigentliche Transformation durch. Zuerst wird der normalisierte Eingabewert mit der Skalierung des Ausgabebereichs multipliziert, um den transformierten Wert zu erhalten. Dann wird der untere Grenzwert des Ausgabebereichs (toLow) zum Ergebnis addiert, um den endgültigen transformierten Wert zu erhalten.
  5. round(...): Die Funktion round() rundet den transformierten Wert auf die nächstgelegene ganze Zahl.

Steuern eines Servomotors mit einem Drehpotentiometer in MicroPython

Hier nun das kleine Programm, um mit einem Drehpotentiometer einen Servomotor zu steuern.

#import des Moduls um
#den analogen Pin auszulesen
#und den Servo per PWM zu steuern
from machine import ADC, Pin, PWM
#import des Moduls um eine
#kleine Pause im Code einzulegen
from time import sleep

#wir benutzen in der Schaltung
#den ADC0 Pin / GP26 für den Drehpotentiometer
adc = ADC(Pin(26))

#der Servomotor ist am GP15 angeschlossen
pwm = PWM(Pin(15))

pwm.freq(50)

#untere & obere Grenze des Servomotors
servoMin = 100
servoMax = 8000

#untere & obere Grenze des Drehpotentiometers
drehpotiMin = 224
drehpotiMax = 65535

# Funktion zum setzen eines Winkels
# als Parameter wird die Position erwartet
def setServoCycle(position):
  pwm.duty_u16(position)
  sleep(0.01)

#Funktion zum mappen eines Wertes mit einer oberen und unteren Grenze
def map(value, fromLow, fromHigh, toLow, toHigh):
  return round((value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow)

#starten der Endlosschleife
while True:
    #auslesen des Wertes vom Drehpotentiometer
    value = adc.read_u16()
    #ermitteln der Servoposition
    servoPosition = map(value, drehpotiMin, drehpotiMax, servoMin, servoMax)
    #zuweisen der Servoposition
    setServoCycle(servoPosition)
    #eine kleine Pause von 125 Millisekunden
    sleep(0.125)
    

Im Video erkennst du, dass der Servo sich je nach Position des Drehpotentiometers bewegt. Ein Problem ist jedoch, dass der analoge Wert nicht konstant gleich ist, d.h. wenn du den Drehpotentiometer nicht bewegst, dass der Servo trotzdem zuckt.

Ermitteln der Grenzen des Sensors & Aktors

Hier jetzt der vollständigkeitshalber die beiden Programme um die untere & obere Grenze des Drehpotentiometers & des Servomotors zu ermitteln.

Die Werte des Servomotors habe ich selbst durch Trial-and-Error ermittelt, diese können je nach Modell variieren.

Auslesen des Drehpotentiometers am Raspberry Pi Pico

Zunächst einmal lesen wir den Drehpotentiometer aus, um die untere und obere Grenze zu ermitteln.

#import des Moduls um
#den analogen Pin auszulesen
from machine import ADC, Pin
#import des Moduls um eine
#kleine Pause im Code einzulegen
from time import sleep

#wir benutzen in der Schaltung
#den ADC0 Pin / GP26
adc = ADC(Pin(26))

#starten der Endlosschleife
while True:
    #auslesen des Wertes
    value = adc.read_u16()
    #ausgeben des Wertes
    print("Drehpotentiometer Wert: "+ str(value))
    #eine kleine Pause von 125 Millisekunden
    sleep(0.125)

Mit dem Code habe ich jetzt ermittelt das die untere Grenze 224 und die obere Grenze 65535 ist.

Steuern des Servomotors per PWM Signal

Im Beitrag Raspberry PI Pico #3 – PWM Signale erzeugen habe ich dir bereits gezeigt, wie man einen Servomotor vom Typ SG90 per PWM Signal steuern kann. Mit dem nachfolgenden Code können wir diesen jetzt von 0° bis 180° drehen.

from time import sleep
from machine import Pin 
from machine import PWM

pwm = PWM(Pin(15))
pwm.freq(50)

# Funktion zum setzen eines Winkels
# als Parameter wird die Position erwartet
def setServoCycle(position):
  pwm.duty_u16(position)
  sleep(0.01)


while True:
    for pos in range(100, 8000,50):
      setServoCycle(pos)
    for pos in range(8000, 100,-50):
      setServoCycle(pos)

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}