Raspberry Pi Pico und das 35 in 1 Sensors Kit in MicroPython - Teil 2 - AZ-Delivery

Im ersten Teil dieser Blogreihe haben wir die GPIOs als Ausgang für LEDs, Buzzer und Relais kennengelernt. Nun soll die Programmierung der GPIOs als Eingang folgen, zunächst am Beispiel des Tasters.

Benötigte Teile (wie in Teil 1)

1

Raspberry Pi Pico oder Pico W

1

35 in 1 Sensor Kit

alt

16 in 1 Sensor Kit

1

Steckbrett/Breadboard oder Half-Breadboard

Jumperkabel, Taster/Button

Widerstände 220 bis 330 Ω, 1 kΩ, 4,7 kΩ, 10 kΩ

optional

weitere Sensoren oder Displays


Ein Taster (Button) ist ein federbelasteter Schalter, der nach dem Loslassen den Stromkreis wieder öffnet. Es gilt, zwei Besonderheiten zu beachten: Erstens muss ein Kurzschluss in der Schaltung vermieden werden und zweitens können gerade die preiswerten Taster „prellen“ (engl. bounce, bouncing), d.h. statt des sofortigen elektrischen Kontaktes ruft die Betätigung des Schalters kurzzeitig ein mehrfaches Schließen und Öffnen des Kontakts hervor.

Wenn der GPIO Pin als Eingang deklariert wurde, kann man mit dem Programm abfragen, ob ein HIGH-Signal (Spannung ca. 2 - 3,3V) oder ein LOW-Signal (GND=0V bis max. ca. 1,2V) anliegt. Wenn man durch Drücken des Tasters also 3,3V anlegt, liegt eindeutig HIGH an. Wenn man den Taster wieder loslässt, hat man jedoch einen undefinierten Zustand. LOW wird nur erkannt, wenn Verbindung zu GND hergestellt wird. Wenn dann der Button gedrückt wird, hat man jedoch einen satten Kurzschluss und beschädigt den Mikro Controller. Abhilfe schafft hier ein Pull-down-Widerstand von 10 kΩ, der den Pin auf LOW zieht. Beim Drücken des Tasters wird der Zustand am Pin HIGH, es fließt dabei ein geringer Strom durch den Widerstand gegen GND, der im zulässigen Bereich liegt. Es gilt: I = U / R, also 3,3V / 10 kΩ = 0,33 mA.

Das gleiche gilt bei inverser Logik: Der Pin wird dauerhaft über einen Pull-up-Widerstand auf HIGH gehalten und beim Drücken des Tasters auf LOW gezogen. Das Schöne ist, dass die Mikrocontroller einen internen Pull-up-Widerstand besitzen, der im Programm zugeschaltet werden kann. Deshalb wird diese Schaltung heutzutage häufiger angewendet.

Nun zur Programmierung mit dem MicroPython-Modul picozero. Hier gibt es die Klasse Button, die zu Beginn des Programms mit

 from picozero import Button

importiert wird, Anschließend wird das Objekt button instanziiert mit z.B.

 button = Button(16) # GP16 = phys. Pin 21

In der Klassendefinition erkennt man, dass es zwei optionale Parameter gibt, die voreingestellt sind:

 class picozero.Button(pin, pull_up=True, bounce_time=0.02)

Mit diesen Voreinstellungen sind die beiden o.g. Probleme gelöst. Der Button kann gegen GND geschaltet werden und Prellen wird durch eine „bounce_time“ von 20 ms unterdrückt. Selbstverständlich können diese Werte bei der Instanziierung des Objekts geändert werden, z.B.

 button = Button(17, pull_up=False, bounce_time=0.01)        # GP17 = phys. Pin 22
Zwei einfache Beispielprogramme, das erste sicherlich selbsterklärend:
 from picozero import Button
 import utime as time
 button = Button(16)
 
 
 while True:
     if button.is_pressed:
         print("Button is pressed")
         start = time.ticks_ms()
     else:
         print("Button is not pressed")
     sleep(0.1)

Beim zweiten Beispielprogramm sieht es auf den ersten Blick aus, als würde die Funktion pico_led.on() aufgerufen. Allerdings dürfen bei button.when_pressed=pico_led.on keine Klammern() verwendet werden. Die Dokumentation schreibt: Die Funktion wird nicht aufgerufen, sondern es wird eine Referenz zur Funktion eingerichtet.

 from picozero import Button, pico_led   # internal LED
 button = Button(16) # default: pull_up=True, bounce_time=0.02
 button.when_pressed = pico_led.on # Remark: no brackets ()
 button.when_released = pico_led.off

Etwas aufwendiger ist das Programm mit dem MicoPython-Modul machine, das jedoch ggf. auch bei anderen Mikrocontrollern wie ESP32 verwendet werden kann.

 from machine import Pin
 import utime as time
 button = Pin(16, Pin.IN, Pin.PULL_UP)
 reset = Pin(17, Pin.IN, Pin.PULL_UP)
 # Codezeile für Raspberry Pi Pico (ohne WLAN)
 led_onboard = Pin(25, machine.Pin.OUT)
 # Codezeile für Raspberry Pi Pico W (mit WLAN)
 #led_onboard = Pin("LED", machine.Pin.OUT)
 while True:
     if button.value() == 0:
         print("button is pressed")
         led_onboard.on()
     if reset.value() == 0:
         print("reset is pressed")
         led_onboard.off()
     time.sleep(0.1)
Im Vorgriff auf den nächsten Abschnitt Sensoren, die meist nur einen kurzen Schaltimpuls erzeugen, habe ich bereits einen zweiten Taster zum Ausschalten mit Namen reset eingeführt. 

Sensoren

Nun zu den Sensoren, die wie Schalter oder Taster funktionieren; zunächst die rein digitalen Sensoren: (Gabel-)Lichtschranke, Familie der Schüttelsensoren (auch Schock-, Klopf-), Bewegungsmelder, Magnetschalter, Digitaler Hallsensor, Flammensensor. (Die Zahlen beziehen sich auf die Abschnitte im eBook für das Sensor Kit am ATmega Mikrocontroller.)


Diese Sensoren haben drei Pins, die exakt in das Breadboard passen. Einer ist mit dem Minus - gekennzeichnet, einer mit S (für Signal) oder OUT. Auch wenn der mittlere Pin wegen der Beschaltung nicht beschriftet ist, bitte an Vcc=3,3V anschließen, denn auf der kleinen Platine befindet sich auch ein 10 kOhm-Widerstand (Pull-up oder Pull-down). Der Signal-Pin wird an den GPIO-Eingang angeschlossen. Neben dem o.a. Programm möchte ich auch noch die Variante mit dem Modul picozero zeigen:
 from picozero import pico_led, Button
 import utime as time
 button = Button(16)
 reset = Button(17)
 
 while True:
     button.when_pressed = pico_led.on
     reset.when_pressed = pico_led.off

Die eingebaute LED pico_led braucht nicht instanziiert werden. Wer eine externe LED oder einen Buzzer anschließen möchte, muss diese Klassen importieren und die Objekte mit der gewünschten Pin-Nummer instanziieren (siehe Teil 1).

Analoge Eingänge des Pico/Pico W

Bevor ich die Sensoren mit vier Anschlüssen, neben + und GND häufig D0 und A0 (für digitaler und analoger Ausgang) anspreche, möchte ich zunächst die analogen Eingänge des Pico beschreiben.

Analoger Eingang bedeutet, dass nicht nur Low oder High erkannt wird, sondern eine Spannung zwischen Null und der Referenzspannung (beim Pico 3,3V, sofern am Pin 35 (=ADC_VREF) keine andere Spannung angelegt wird) in einen Zahlenwert umgewandelt wird. Die Auflösung liegt beim Pico bei 12-Bit, also grundsätzlich einem Wert zwischen 0 und 4095, dieser wird jedoch mit der Methode adc.read_u16() aus dem Modul machine skaliert auf den Bereich 0 bis 65535, bei dem Modul picozero normiert auf den Bereich 0 bis 1. Zum Vergleich beim Uno ist die Auflösung 10-Bit, das ergibt einen Wert zwischen 0 und 1023.

Der RP2040 hat grundsätzlich fünf ADC-Kanäle, von denen beim Raspberry Pi Pico drei voll nutzbar sind. ADC0 liegt an GP26 (phys. Pin 31), ADC1 an GP27 (phys. Pin 32) und ADC2 an GP28 (phys. Pin 34); ADC3 ist beim Pico mit VSYS verbunden und ADC4 mit dem internen Temperatursensor, der allerdings wenig geeignet ist für die Messung der Umgebungstemperatur.

Hier Beispielcode für das Modul machine und anschließend Modul picozero.
N.B. Grundsätzlich kennt das Modul machine auch die Methode adc.read_uv(), also das Erkennen der Spannung. Das funktioniert jedoch nicht beim Pico. 

 from machine import ADC, Pin
 import utime as time
 adc = ADC(Pin(26))          # create ADC object on ADC pin
 while True:
     value = adc.read_u16()     # read value, 0-65535 across voltage range 0.0v - 3.3v
     print("value = ",value)
     time.sleep(0.1)
 
 
 # Potentiometer connected to GP26 (ADC0), GND and 3V3
 from time import sleep
 from picozero import Pot
 pot = Pot(26)
 while True:
     print(pot.value, pot.voltage)
     sleep(0.1)
Das Joystick-Modul besteht aus zwei Potentiometern und einem Taster. Hier ein Programmbeispiel:
 # Joystick module connected to GP26 (ADC0), GP27 (ADC1), GP16 (button), GND and 3V3
 from time import sleep
 from picozero import Pot, Button
 potx = Pot(26)
 poty = Pot(27)
 button = Button(16)
 while True:
     x = potx.value
     y = poty.value
     b = button.value
     print("x = ", x, " y = ", y, "b = ", b)
     sleep(0.1)
Bitte beachten: Auch hier werden nach den Aufrufen von .value keine Klammern gesetzt. Ansonsten erhält man die Fehlermeldung „… is not callable“.

Zwei weitere Sensoren liefern analoge Werte und können wie ein Potentiometer angeschlossen werden: der Lichtsensor (LDR Widerstand) und der Thermistor.

Da diese Sensoren nicht wirklich leicht zu kalibrieren sind, um exakte physikalische Werte zu liefern, bietet es sich hier an, die Werte des „Normalzustands“ zu notieren und das Über- oder Unterschreiten von Grenzwerten als Trigger für weitere Aktionen zu nutzen. Beispiel: Auf der Thermistor-Platine befindet sich ein Spannungsteiler mit einem festen Widerstand von ca. 10 kOhm und dem Thermistor, der bei Umgebungstemperatur einen Widerstand von ca. 100 kOhm hat. Bei starker Hitze nimmt dieser Widerstand - und damit die Spannung an diesem Widerstand - deutlich ab, es handelt sich also um einen NTC-Thermistor (NTC=Negativer Temperatur Koeffizient, abnehmender Widerstand bei steigender Temperatur).

Ebenso kann man mit logischen Verknüpfungen bei Erkennen einer Bewegung das Licht erst einschalten, wenn gleichzeitig eine gewisse Lichtstärke unterschritten wird.

Sensoren mit digitalen und analogen Anschlüssen

Nun zu den Sensoren mit vier Anschlüssen, außer der Spannungsversorgung einem digitalen und einem analogen Ausgang. Meist haben diese Sensoren auf der Platine noch ein kleines, blaues Trimm-Potentiometer und eine LED.

Wir haben bereits gesehen, wie die digitalen und wie die analogen Signale ausgewertet werden. Macht es also Sinn, beide Signale gleichzeitig auszuwerten? Ja, macht es. Insbesondere im Hinblick auf das eingebaute Potentiometer! Denn mit Hilfe der analogen Werte kann man den Grenzwert am Poti einstellen, bei dem die LED aufleuchtet und der digitale Pin auf High geschaltet wird. Denn die Auswertung des digitalen Signals ist einfacher und in Schaltungen leichter zu realisieren.

Noch ein Wort zu den Mikrofon-Modulen. Damit werden keine Sprache oder Musik aufgezeichnet, es geht nur um den Lärmpegel! Als Anwendung kommt z.B. ein „Klatschschalter“ in Frage, wie er 1959 im Film „Bettgeflüster“ mit Doris Day und Rock Hudson noch ohne Mikrocontroller realisiert wurde.

Bei den letzten beiden Sensoren muss man auf das analoge Signal für die Justierung verzichten, aber auch hier kann die Empfindlichkeit mit Trimm-Potentiometern verändert werden. Da hilft vor allem Ausprobieren.

Soweit die Nutzung der Pins als Eingänge. Beim nächsten Mal geht es um Sensoren mit besonderen Schnittstellen.
Projekte für anfängerRaspberry piSensoren

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery