Poti
Dieses Lab zeigt Ihnen wie sie die wechselnde Spannung von einem Potentiometer als User Input nutzen können.
Vorkenntnisse:
Ziel:
- Poti verbinden
- ADC nutzen um Spannung zu messen.
- Wertebereich umrechnen.
Das Potentiometer
Ein Potentiometer wirkt wie ein verstellbarer Spannungsteiler, der die Spannung zwischen GND und VCC in Abhängigkeit von der Position des Schleifkontakts teilt. Durch Drehen des Potentiometers kann die Ausgangsspannung stufenlos verändert und an verschiedene Anforderungen angepasst werden
Aufbau
Bauen Sie die abgebildete Schaltung auf. (Wokwi)
Analog Digital Wandler
Zuerst müssen wir die Klasse ADC
aus dem Modul machine
importieren.
from machine import ADC
Der Konstruktor benötigt nur die Pin nummer.
from machine import ADC
adc = ADC(32)
Nicht jeder beliebige Pin kann als ADC verwendet werden. Welche Pins als ADC genutzt werden können steht im Pinout oder im Datenblatt des entprechenden Microcontrollers.
ADC-Block 2 wird auch von WiFi verwendet. Der Versuch, Analogwerte von den Pins des Blocks 2 zu lesen, wenn WiFi aktiv ist, führt daher zu einer Exception.
Der ADC bietet uns zwei verschieden Methoden um den aktuellen Wert am Pin zu lesen.
from machine import ADC
adc = ADC(32)
value = adc.read_u16() # Wert zwischen 0 und 2^16
microvolts = adc.read_uv() # Wert in microvolts
Die interne ADC-Referenzspannung beträgt typischerweise 1,1 V und hat eine minimale Messspannung um 100mV, Spannungen <= diesem Wert werden als 0 gelesen.
Schreiben Sie ein Program welches den Wert vom Poti einliest und jede Sekunde den aktuellen Wert über die serielle Schnittstelle wieder ausgibt.
Solution
Solution
from machine import ADC
from time import sleep
poti = ADC(32)
while True:
value = poti.read_u16()
print(f"Aktueller Wert: {value}")
sleep(1)
Schreiben Sie ein Program welches es ermöglicht eine LED über den Poti ein und aus zu schalten. Die Grenze soll genau in der Mitte des Wertebereichs liegen.
Solution
Solution
from machine import ADC, Pin
poti = ADC(32)
led = Pin(27, Pin.OUT)
while True:
value = poti.read_u16()
# Hälfte von 2¹⁶ = 32768
if value > 32768:
led.on()
else:
led.off()
Messbereich auf Steuerungsbereich mappen
Ein häufiges Problem im Zusammenhang mit dem Einlesen analoger Werte ist das Umrechnen dieser Werte in einen anderen Wertebereich. Als Beispiel soll mit einem Potentiometer eine LED gedimmt werden. Wir haben nun gesehen, dass wir Werte zwischen 0 und 2^16 einlesen können. Zum Dimmen der LED benötigen wir nun einen Wertebereich zwischen 0 und 255.
Der gewünschte Wertebereich hat also 256 Schritte. Wir müssen nun also den ursprünglichen Bereich in 256 Schritte unterteilen.
Ursprungsbereich | Zielbereich |
---|---|
0 - 255 | 0 |
256 - 512 | 1 |
513 - 768 | 2 |
... | ... |
65024 - 65279 | 254 |
65280 - 65535 | 255 |
Foglende Formel kann für die Umrechnung genutzt werden: Dabei ist der Ursprungsbereich und der Zielwertebereich.
Schritt für Schritt Erklärung
Schritt für Schritt Erklärung
- Normalisierung auf den Bereich Hier wird der Eingabewert relativ zu seinem Ursprungsbereich skaliert.
- Skalierung auf den Zielbereich: Das Ergebnis der Normalisierung wird mit der Größe des Zielbereichs multipliziert.
- Verschiebung in den Zielbereich: Schließlich wird das Ergebnis an den Startpunkt (min_out) des Zielbereichs angepasst.
Beispiel
Beispiel
Sie wollen den Wert 30 aus dem Wertebereich in den Zielbereich umrechnen.
-
Normalisierung auf den Bereich
-
Skalierung auf den Zielbereich: Hinweis: Beginnt der Zielbereich bei wären wir schon fertig.
-
Verschiebung in den Zielbereich:
Das Ergebnis ist ✅
👉 Schreiben Sie eine Funktion map(value, min_in, max_in, min_out, max_out)
welche diese in Code umsetzt.
Hinweis: Achten Sie darauf, dass sie nicht durch NULL teilen dürfen.
Tip
Tip
Testen Sie ihre Funktion z.B mit folgenden Werten:
Value | Expected Output |
---|---|
65279 | 254,99609375 |
65280 | 255 |
Solution
Solution
def map(value, min_in, max_in, min_out, max_out):
if min_in == max_in:
raise ValueError("Der Eingabebereich darf nicht null sein.")
return (value - min_in)/(max_in - min_in) * (max_out - min_out) + min_out
Diese Funktion gibt einen float
zurück. Oft brauchen wir jedoch nur den ganzzahligen Anteil (int
) zum weiterrechnen. Dies können Sie zum Beispiel durch eine Typumwandlung int(output)
oder eine Integer Division output//1
erreichen.
Übungsaufgaben
-
Schreiben Sie ein Program, dass den Poti nutzt um 3 Zustände (AUS, AN, BLINKEN) einer LED auszuwählen.
-
Schreiben Sie ein Program, dass die Blinkfrequenz einer LED über einen Poti einstellbar macht.
-
Bauen Sie einen Spannungsteiler aus 220 Ω und 1kΩ auf. Berechnen Sie den Wert welcher vom ADC eingelesen wird und überprüfen Sie dies mit einem kleinen Program nach. Analysieren Sie mögliche Abweichungen des Messwertes von dem theoretischen Ergebnis.
-
Der Ladestand eines Akkus soll über 5 LEDs optisch dargestellt werden. Nutzen Sie einen Poti um die Spannung des Akkus zu simulieren. Programmieren Sie Ihre Schaltung so, dass proportional zur Stellung des Potentiometers die Anzahl der leuchtenden LEDs variiert. Nutzen Sie die eine
for
-Schleife. -
Begründen Sie warum Sie einen 9V Akku nicht einfach an den ADC Pin anschließen dürfen. Skizzieren Sie anschließend eine mögliche Lösung um den Akkustand trotzdem zu messen.
-
Werte, die über einen analogen Eingang eingelesen wurden, sollen auf dem seriellen Monitor mit einer Art Balkenanzeige dargestellt werden. Je größer der eingelesen Wert, desto mehr > werden dargestellt. Die Balkenanzeige soll 25 Balken haben und das Maximum wird durch | angezeigt. Mit einem angeschlossenen Potentiometer soll die Balkenanzeige gesteuert werden.2