DU LERNST HIER... |
wie du einfache Aktoren ansteuerst, die nur ein- und ausgeschaltet werden, die also nur die digitalen Zustände 1 (HIGH) oder 0 (LOW) kennen. Du lernst auch, digitale Sensoren auszulesen, die nur zwei Zustände 1 oder 0 haben, das heisst eine Spannung oder keine Spannung abgeben. |
DIGITALER AUSGANG |
So wie fast jeder Programmierlehrgang mit dem Ausschreiben von "Hello World" beginnt, ist das klassische Einsteigerprogramm für Mikrocontroller eine blinkende LED. Dazu musst du eine LED über einen Vorwiderstand von einigen hundert Ohm an den IO-Port anschliessen, wobei die Polarität der LED wichtig ist. Ist sie verkehrt eingesteckt, so wird sie nicht beschädigt, sondern blinkt nicht.
Programm: from machine import Pin from time import sleep P_LED = 5 p = Pin(P__LED, Pin.OUT) while True: p.value(1) sleep(0.5) p.value(0) sleep(0.5)
Programm: from machine import Pin from time import sleep P_BUZZER = 5 # adapt to your wiring dt = 0.1 # adapt to your Morse speed morse = { 'a':'.-' , 'b':'-...' , 'c':'-.-.' , 'd':'-..' , 'e':'.' , 'f':'..-.' , 'g':'--.' , 'h':'....' , 'i':'..' , 'j':'.---' , 'k':'-.-' , 'l':'.-..' , 'm':'--' , 'n':'-.' , 'o':'---' , 'p':'.--.' , 'q':'--.-' , 'r':'.-.' , 's':'...' , 't':'-' , 'u':'..-' , 'v':'...-' , 'w':'.--' , 'x':'-..-' , 'y':'-.--' , 'z':'--..' , '1':'.----', '2':'..---', '3':'...--', '4':'....-', '5':'.....', '6':'-....', '7':'--...', '8':'---..', '9':'----.', '0':'-----', '-':'-....-', '?':'..--..', ',':'--..--', ':':'---...', '=':'-...-'} def s(n): # wait sleep(n * dt) def dot(): p.value(1) s(1) p.value(0) s(1) def dash(): p.value(1) s(3) p.value(0) s(1) def transmit(text): for c in text: if c == " ": s(4) else: c = c.lower() if c in morse: k = morse[c] for x in k: if x == '.': dot() else: dash() s(2) p = Pin(P_BUZZER, Pin.OUT) transmit("cq de hb9abh pse k") |
DIGITALER EINGANG |
Ein digitaler Eingang detektiert logische Pegel 0 (LOW, GND, ca. 0V) und 1 (HIGH, VCC, ca. 3.3V).
Programm: from oxocard import * from machine import Pin from time import sleep P_BUTTON = 5 p = Pin(P_BUTTON, Pin.IN, Pin.PULL_UP) while True: v = p.value() # 1: released, 0: pressed if v == 0: clear(GREEN) else: clear(RED) Beim Button kann es sich um einen Berührungssensor handeln, der in einer Anlage eingebaut ist und durch irgendeine mechanische Betätigung ausgelöst wird, aber auch um einen Schalter, der ein- oder ausgeschaltet ist. Achtung: Die Eingänge sind ungeschützt und eine Spannung grösser als 3.3 V oder eine negative Spannung (falsche Polarität) zerstören den Mikrocontroller! |
PIR-SENSOR AM DIGITALEN EINGANG |
Der Pyroelektrische Infrarot-Sensor (PIR) verwendet die Eigenschaft einiger Halbleiter, dass eine Temperaturänderung zu einer elektrischen Spannung führt. Da Lebewesen eine Temperaturstrahlung im Infrarot-Bereich abgeben, können PIR-Sensoren die Bewegung von Lebewesen im Bereich von bis zu einigen Metern detektieren. Sie werden vor allem in Alarmanlagen eingesetzt.
Programm: from oxocard import * from machine import Pin from music import playTone def alert(): playTone(1500, 200) playTone(2000, 200) P_PIR = 19 p = Pin(P_PIR, Pin.IN, Pin.PULL_UP) while True: v = p.value() if v == 0: clear(GREEN) else: clear(RED) alert() |
MERKE DIR... |
Digitale Ein- und Ausgangsports (GPIO) stellen das einfachste Interface eines Mikrocontrollers mit seiner Umwelt dar. Ein bestimmter Port wird softwaremässig als Input oder Output definiert. Als Output musst du darauf achten, dass der Port einen maximalen Strom von 40 mA liefern kann (sowohl beim Ziehen auf GND oder VCC). Als Input kannst du einen internen Pullup, ein Pulldown oder einen hochohmigen Eingang definieren.. |
ZUM SELBST LÖSEN |
|
ZUSATZSTOFF: ZUSTANDSPROGRAMMIERUNG, SCHALTERPRELLEN |
Du willst ein Programm schreiben, das beim Drücken des Buttons eine Lichtquelle, hier das Pixel in der Mitte des LED-Displays, einschaltet und beim nächsten Drücken wieder ausschaltet. Da du die LED von hell auf dunkel und wieder zurück "umschaltest", ist es sinnvoll, dazu die Funktion toggle() zu definieren. def toggle(): if getColor(3, 3) == BLACK: dot(3, 3, WHITE) else: dot(3, 3, BLACK) Das Problem hat aber seine Tücken, denn du kannst nicht einfach in einer Schleife testen, ob der Button gedrückt ist und dann die LED umschalten. Beim nächsten Schleifendurchgang würde das Licht sofort wieder erneut umgeschaltet. Du darfst also das Umschalten der LED nur dann ausführen, wenn der Button in der Zwischenzeit wieder losgelassen wurde. Dazu führst du eine "Zustandsvariable" state ein, die den Wert "PRESSED" bzw. "RELEASED" hat. Nur wenn der Zustand auf PRESSED geht, schaltest du die LED um. Programm: from oxocard import * from machine import Pin from time import sleep def toggle(): if getColor(3, 3) == BLACK: dot(3, 3, WHITE) else: dot(3, 3, BLACK) P_BUTTON = 5 p = Pin(P_BUTTON, Pin.IN, Pin.PULL_UP) state = "RELEASED" while True: v = p.value() # 0: pressed if v == 0 and state == "RELEASED": state = "PRESSED" toggle() if v == 1 and state == "PRESSED": state = "RELEASED" Trotz deinen Anstrengungen benimmt sich das Programm leider nicht bei jeder Betätigung korrekt. Manchmal geht die LED beim Drücken des Buttons gerade wieder in den vorhergehenden Zustand zurück. Das Fehlverhalten ist nicht reproduzierbar und tritt nur sporadisch auf. Wir haben es mit einem ganz schlimmen Programmierfehler zu tun! Wie ist der Fehler zu erklären? Beim Schliessen des Schalters drückt man zwei mechanische Kontakte zusammen und erstellt damit eine leitende elektrische Verbindung zwischen den Kontakten.
Das Gleiche kann sich beim Loslassen ereignen: Der Kontakt öffnet und schliesst mehrere Male kurz hintereinander. Dieser Effekt, der als Schalterprellen bezeichnet wird, bewirkt bei Anwendungen, bei denen die Anzahl der Schliess- oder Öffnungsoperationen eine Rolle spielt, unvorhersehbare Resultate. Wir beseitigen das Problem gemäss folgender Idee: Nach dem Erfassen des ersten Press-Ereignis unterbindest du die sofortige Abfrage des Tastenzustands während einer kurzen Zeit, indem du ein Sleep() einbaust. Damit haben die in dieser Zeit auftretenden "Preller" keine Auswirkungen. Dasselbe machst du beim Release-Ereignis. Das gewählte Zeitintervall für Sleep() ist kritisch, da du bei zu langen Wartezeiten kurz dauernde Tastenklicks nicht mehr erfasst und bei zu kurzen die Taste prellt. Programm: from oxocard import * from machine import Pin from time import sleep def toggle(): if getColor(3, 3) == BLACK: dot(3, 3, WHITE) else: dot(3, 3, BLACK) P_BUTTON = 5 p = Pin(P_BUTTON, Pin.IN, Pin.PULL_UP) state = "RELEASED" while True: v = p.value() # 0: pressed if v == 0 and state == "RELEASED": state = "PRESSED" toggle() sleep(0.05) if v == 1 and state == "PRESSED": state = "RELEASED" sleep(0.05)
|