×
produktlogotitle

Seite: ddg_knopf
Diese Seite wurde aktualisiert am 06.01.2021

LOGIN
Benutzer:
Passwort:
 
   if1.net-schulbuch.de

ESP32 Grundlagen - Ports als Eingänge konfigurieren und verwenden
 - Bedarfsgesteuerte Fußgängerampel -

 

Fußgängerüberwege haben an viel befahrenen Straßen häufig eine Bedarfssteuerung. Fußgänger müssen am Masten der Ampel eine Signaltaste drücken, wenn sie die Straße sicher überqueren wollen. Nach dem Auslösen des Signals dauert es meistens nicht sehr lange, bis die Fahrzeuge durch rote Ampeln angehalten werden. Die grüne Fußgängerampel lässt ausreichend Zeit zum Überqueren der Straße.

   

 

ACHTUNG: USB-Kabel vom Board abziehen: Die Schaltung am ESP32-Entwicklungsboard wird erweitert um einen Taster, der durch Drücken einen Kontakt schließt. Ein Anschluss dieses Schließers wird mit GND und der andere mit GPIO34 verbunden (orange Leitungen in der Abbildung). Zusätzlich wird ein4.7KΩ-Widerstand zwischen GPIO34 und dem 3.3V-Spannungs-PIN des Boards eingefügt. Ein vollständiges "Fritzing-Schema" findest Du unten auf der Seite.

 

GPIO34 kann ausschließlich als Eingang für Signale verwendet werden. Durch Drücken des Tasters wird ein LOW-Signal (0 Volt) an den GPIO34 gelegt. Wenn der Taster nicht geschlossen ist, dann liegt kein Signal am GPIO34 an. Das soll nicht sein! Deshalb ist der Widerstand eingefügt. Dieser sorgt dafür, dass bei nicht geschlossenem Taster eine Spannung von 3.3V am Eingang liegt, baer nur ein sehr geringer Strom fließt. Einen solchen Widerstand nennt man PULLUP-Widerstand, weil er einen Signaleingang auf  ein HIGH-Signal "hochzieht", wenn er nicht verbunden ist.

Den neuen Eingang initialisiert MicroPython mit 

Taste = machine.Pin(34, machine.Pin.IN) 

Zum Abfragen der Taste im Programmablauf dient dann

def Taste_gedrueckt():
    if Taste.value() == 0:
        return True
    else:
        return False

 

Forschungsauftrag 1

An welchen Stellen muss das vorhanden Programm fussgaengerampel.py geändert werden, damit das Drücken der Taste Wirkung zeigt?

Führe die geplanten Änderungen durch. Speichere in die Datei bedarfssteuerung.py und lass das neue Programm ausführen.

Arbeitet es wie erwartet?

Welche Probleme tauchen auf? Beschreibe diese möglichst genau!

Es ist sehr wichtig, dass du diesen Forschungsauftrag durchführst. Erst wenn du die dabei auftretenden Probleme erkannt hast, sind die folgenden Lösungsvorschläge nachvollziehbar Es handelt sich dabei um grundlegende Probleme in der Konstruktion von Informatiksystemen. Die Lösung ist überraschend, aber nicht einfach zu verstehen. ALSO: erst probieren, dann weiterlesen.

 

 

Ds Problem ist die Methode Taste_gedrueckt() - Diese Methode muss im Prinzip immer wieder aufgerufen werden, wenn jeder Druck auf die Taste auch vom Programm bemerkt werden soll. Ein Tastendruck wird aber nur bemerkt, wenn der Fußgänger lange genug die Taste gedrückt hält; und zwar solange, bis das Programm eine Stelle erreicht, an der genau dieser Tastendruck abgefragt wird. 

 

 Forschungsauftrag 2   

Ein Lösungsvorschlag ist:

Am Ende der Grünphase wird in einer Schleife die Methode Taste_gedrueckt() solange aufgerufen, bis der Wert True zurückgegeben wird. Nur dann wird die Grünphase verlassen. Die Angabe von Dauer für die Grünphase legt dann die Mindestdauer fest. Rechts die abgeänderte Methode.

  1. Implementiere diesen Lösungsvorschlag im Programm bedarfssteuerung.py .
  2. Teste das Programm.
    In welchen Fällen reagiert das Programm wie erwartet?
  3. "Spiele" mit der Taste.
    Gibt es Situationen, in denen das Programm nicht wie erwartet reagiert?
    Dokumentiere jeweils das Problem genau.


Die Fußgängerampel wird in diesem Szenario nur den Überweg freigeben, wenn der Tastendruck NACH der Mindestdauer der Grünphase erfolgt.
Vorher abgegebene Anforderungen durch einen Tastendruck werden ignoriert. Das funktioniert, ist aber nicht befriedigend.

def GruenPhase(Dauer):
    Rot.off()
    Gelb.off()
    Gruen.on()
    time.sleep(Dauer)
    while not Taste_gedrueckt():
        time.sleep(0.001) 

 

 Forschungsauftrag 3   

 

Einen anderen Lösungsvorschlag implementiert das rechts abgebildete Programm:

In allen Methoden wird der Aufruf von time.sleep(Dauer) durch warten(Dauer) ersetzt.
Alle weiteren Änderungen sind rechts dokumentiert.

warten(Dauer) ist eine neue Methode und wie rechts aufgeführt definiert.

Am Anfang des Programms wird einer globale Variablen Taste_gedrueckt der Wert False zugewiesen. Wird in der neuen Methode getTaste() ein Tastendruck festgestellt, dann erhält diese Variable den Wert True .

Weitere wichtige Änderungen erfolgen in der Methode GruenPhase(Dauer) und in der Endlosschleife des Hauptprogramms.

  1. Implementiere diesen Lösungsvorschlag vollständig durch Änderungen an der Datei bedarfssteuerung.py .
  2. Analysiere die Funktionsweise.
  3. Speichere das Programm unter bedarfssteuerung3.py .
  4. Teste die Lösung intensiv und versuche Probleme zu finden.
  5. Dokumentiere diese.

Erarbeite Lösungsvorschläge für die unter 4. dokumentierten Probleme. Setze diese um und beginne wieder bei Schritt 3.

Die Idee besteht darin, dass im Prinzip nach sehr wenigen ausgeführten Befehlen immer wieder in sehr kurzen Abständen auf eínen erfolgten Tastendruck überprüft wird. Ist ein solcher erfolgt, wird dieses Ereignis in der globalen Variablen Taste_gedrueckt vermerkt.
In der Grünphase des Programms befindet sich die entscheidende Änderung. Diese Phase wird solange ausgedehnt, bis ein Tastendruck festgestellt wird. Dann wird sie nach Löschen des Vermerks verlassen.

In der Endlosschleife des Hauptprogramms ist die Reihenfolge geändert. Es beginnt mit der Grünphase, in der auf einen Tastendruck gewartet wird. Aber auch in allen anderen Phasen werden Tastendrücke nicht verloren gehen. Sie werden dann erst in der nächsten GrünPhase wirksam.

Taste_gedrueckt = False   

def getTaste():
    global Taste_gedrueckt
    if Taste.value() == 0:
         Taste_gedrueckt = True

def warten(Dauer):
    for i in range(1000):
        getTaste()
        time.sleep(Dauer/1000)     

def GruenPhase(Dauer): 
    global Taste_gedrueckt
    Rot.off() 
    Gelb.off() 
    Gruen.on() 
    warten(Dauer) 
    while not Taste_gedrueckt:
        time.sleep(0.001)
        getTaste()
    Taste_gedrueckt = False

while True:
    GruenPhase(3)
    GelbPhase(1)
    RotPhase(5)
    RotGelbPhase(1)

  

 

 

Es gibt viele Beispiele für "Überwachungsaufgaben" in Informatiksystemen, die anfallen, während ein beliebiges Programm arbeitet. So muss z.B. ständig die Tastatur auf Tastendrücke überwacht werden. Bewegungen der Maus müssen auch Reaktionen auf dem Bildschirm zeigen, auf gedrückte Maustasten muss reagiert werden. Auch das Einstecken eines USB-Sticks in den USB-Slot erfordert eine Reaktion. Auf dem Desktop wird die Uhrzeit aktualisiert, während ein Programm läuft. Genaugenommen ist es sogar so, dass fast gleichzeitig mehrere solcher Ereignisse auftreten können. Bisher wurden in keinem unserer Python-Programme Aktionen der Maus berücksichtigt, obwohl wir den Abbruch des aktuell in einer Endlosschleife laufenden Programms durch eine Mausaktion auf der Oberfläche von Thonny herbeiführen konnten.

Informatiksysteme stellen verschiedene Konzepte zur Verfügung, mit denen man unabhängig vom laufenden Programm auf Ereignisse reagieren kann. Ein sehr wichtiges Konzept für diesen Zweck ist der Interrupt Request Service (IRS) oder kurz Interrupt genannt.

Bevor dieser Mechanismus erklärt wird, soll der Aufbau der Bedarfssteuerung mit dem Einbau einer LED für "Signal kommt" ergänzt werden, wie es bei bedarfsgesteuerten Ampelanlagen zu finden ist. Dafür wird im Beispiel eine kleine gelbe LED am GPIO23 genutzt.

Signal = machine.Pin(23, machine.Pin.OUT)

Diese LED soll leuchten sofort nachdem die Taste gedrückt wurde und wieder erlöschen, wenn die Fußgängerampel auf "grün" schaltet.

 

Der Interrupt Request Service ist eine Methode, die immer dann aufgerufen wird, wenn ein Ereignis auftritt, das bearbeitet werden muss, während ein  Programm abläuft. Die Zeichnung veranschaulicht den Vorgang.
Ein laufendes Programm wird nach Ausführung einer Instruktion unterbrochen. Die Interrupt-Service-Routine wird ausgeführt.
Nach ihrer Beendigung wird das unterbrochene Programm mit der Instruktion fortgesetzt, die als nächste ausgeführt worden wäre.

Der ESP32 erlaubt als Embedded Sytem Prozessor bei Einterten unterschiedlicher Ereignisse das Auslösen solcher Interruptprozesse:

  • an einem GPIO-Pin wechselt das Sinal von HIGH nach LOW
  • an einem GPIO-Pin wechselt das Signal von LOW nach HIGH
  • ein Timer löst in regeläßigen Abständen einen Interrupt aus
  • ein gestarteter Prozess löst nach Beendigung einen Interrupt aus
  • ... 

Es ist durchaus möglich, in einem Programm zuzulassen, dass mehrere verschiedene Ereignisse Interrupts auslösen.

Für die bedarfsgesteuerte Ampel soll ein Tastendruck einen Interrupt auslösen. Mit einem Druck auf die Taste wechselt am GPIO23-Pin das Signal von HIGH uaf LOW. Genau dieser Signalwechsel soll einen Interrupt auslösen. Die IRS-Routine ist sehr kurz: sie weist der globalen Variablen Taste_gedrueckt den Wert True zu.  In der Grünphase des Programms muss deshalb inb einer Schleife die globale Variable immer wieder daraufhin abgefragt werden. Ist ihr Wert True, wird die Schleife beendet und die Rotphase mit der Freigabe des Überwegs gestartet. Die Variable Taste_gedrueckt erhält den Wert False zugewiesen. Damit beginnt der Prozess erneut. Das vollständige Programm ist mit Kommentaren versehen und wird mit dem folgenden Link in einem neuen Fenster angezeigt: bedarfsampel.py

 

 Forschungsaufgabe 4   

Kopiere das Programm in Thonny und starte es.

Untersuche das Programm mit genau denselben Vorgehensweisen, die in der Forschungsaufgabe 3 beschrieben sind.

 

 

  

753
Impressum
© 2023  Net-Schulbuch.de
10.00  1.4073  8.1.28