Button abfragen

Hardware vorbereiten

Schließen Sie den Button wie abgebildet an Ihren Raspberry Pi an.

Abfragen eines Buttons mit Flask. Abbildung hergestellt mit fritzing. [Quelle zum Editieren in GitLab](https://collaborating.tuhh.de/itbh/oer/informatik/einfuehrung-in-die-informationstechnik-i-wise-2021_22/-/tree/main/content/de/einheiten/webanwendungen-mit-flask/button-abfragen).
Abfragen eines Buttons mit Flask. Abbildung hergestellt mit fritzing. Quelle zum Editieren in GitLab.

Skripte schreiben

Legen Sie im Ordner Codeprojekte einen neuen Ordner button-abfragen an und darin eine Datei mit Namen app-manuell.py. Öffnen Sie die app-manuell.py in Ihrem Editor.

Fügen Sie nun den folgenden Code in die Datei ein.

Skript: Button abfragen mit manuellem Reload

#!/usr/bin/env python3

from flask import Flask, jsonify
import RPi.GPIO as GPIO

app = Flask(__name__)

# GPIO Setup
BUTTON_PIN = 17  # GPIO-Pin-Nummer (BCM-Nummerierung)
# GPIO-Zählung festlegen
GPIO.setmode(GPIO.BCM)

GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#          ↓          ↓          ↓
#          Pin        Modus      Pull-Resistor

@app.route('/')
def index():

    """Gibt den aktuellen Status des Buttons zurück"""

    # Fragt den Zustand des Eingangs ab
    button_state = GPIO.input(BUTTON_PIN)

    # Speichert den Zustand als Boolschen Wert
    is_pressed = not button_state  # Bei Pull-up ist LOW = gedrückt

    # In Abhängigkeit von diesem Boolschen Wert wird ein String gespeichert
    state = 'gedrückt' if is_pressed else 'nicht gedrückt'

    # Der String wird mit f eingeleitet, um Variablen einzufüllen
    return f'''
    <!DOCTYPE html>
    <html>
    <head>
        <title>Button abfragen</title>
    </head>
    <body>
        <h1>Button-Status</h1>
        <p>Laden Sie die Seite neu, um den aktuellen Status des Buttons zu sehen.</p>
        <div id="status">{state}</div>
    </body>
    </html>
    '''

if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=5000, debug=True)
    finally:
        GPIO.cleanup()

Anwendung starten

Starten Sie das Skript mit folgendem Befehl:

1
../venv/bin/python -m flask --app app-manuell.py run --host=0.0.0.0

Rufen Sie nun die Anwendung im Browser auf. Drücken Sie den Button und beobachten Sie die Änderung des Status auf der Webseite, wenn Sie die Seite neu laden. Spielen Sie mit dem Button und dem Reload der Seite.

Skript: Button abfragen mit Pollling

Im nächsten Schritt erweitern wir die Anwendung so, dass der Status des Buttons automatisch aktualisiert wird, ohne die Seite neu laden zu müssen.

Erstellen Sie eine neue Datei app-polling.py im selben Ordner und fügen Sie den folgenden Code ein:

#!/usr/bin/env python3
from flask import Flask, jsonify
import RPi.GPIO as GPIO

app = Flask(__name__)

# GPIO Setup
BUTTON_PIN = 17  # GPIO-Pin-Nummer (BCM-Nummerierung)
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

@app.route('/button/status')
def button_status():
    """Gibt den aktuellen Status des Buttons zurück"""
    button_state = GPIO.input(BUTTON_PIN)
    is_pressed = not button_state  # Bei Pull-up ist LOW = gedrückt
    
    return jsonify({
        'pressed': is_pressed,
        'state': 'pressed' if is_pressed else 'released'
    })

@app.route('/')
def index():
    return '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>Button abfragen</title>
    </head>
    <body>
        <h1>Button-Status</h1>
        <div id="status">Lädt...</div>
        <!-- Hier folgt ein Schnippsel JavaScript -->
        <script>
            function checkButton() {
                fetch('/button/status')
                    .then(response => response.json())
                    .then(data => {
                        document.getElementById('status').innerHTML = 
                            `Button frist: <strong>${data.state}</strong>`;
                    });
            }
            setInterval(checkButton, 100);  // Alle 500ms abfragen
            checkButton();
        </script>
    </body>
    </html>
    '''

if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=5000, debug=True)
    finally:
        GPIO.cleanup()

Anwendung starten

Starten Sie das Skript mit folgendem Befehl:

1
../venv/bin/python -m flask --app app-polling.py run --host=0.0.0.0

Rufen Sie nun die Anwendung im Browser auf. Drücken Sie den Button und beobachten Sie die Änderung des Status auf der Webseite, ohne die Seite neu laden zu müssen. Spielen Sie mit dem Button.

Skript: Button abfragen per Interrupt

Der Raspberry Pi bietet die Möglichkeit, auf Änderungen an GPIO-Pins per Interrupt zu reagieren. Dies ist effizienter als das ständige Abfragen (Polling) des Pin-Zustands. Interrupts sind besonders nützlich, wenn Sie auf Ereignisse reagieren möchten, ohne die CPU mit ständigen Abfragen zu belasten.

Erstellen Sie eine neue Datei app-interrupt.py im selben Ordner und fügen Sie den folgenden Code ein:

#!/usr/bin/env python3

from flask import Flask
import RPi.GPIO as GPIO

app = Flask(__name__)

# GPIO Setup
BUTTON_PIN = 17
button_press_count = 0

GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def button_callback(channel):
    """Wird bei Button-Druck aufgerufen"""
    global button_press_count
    button_press_count += 1
    print(f"Button gedrückt! Anzahl: {button_press_count}")

# Interrupt aktivieren
GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, 
                      callback=button_callback, 
                      bouncetime=200)

@app.route('/')
def index():
    button_state = GPIO.input(BUTTON_PIN)
    is_pressed = not button_state
    state = 'pressed' if is_pressed else 'released'
    
    return f'''
    <!DOCTYPE html>
    <html>
    <head>
        <title>Button abfragen</title>
        <meta http-equiv="refresh" content="1">
    </head>
    <body>
        <h1>Button-Status: {state}</h1>
        <p>Gesamt-Drücke: {button_press_count}</p>
    </body>
    </html>
    '''

if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=5000, debug=False)
    finally:
        GPIO.cleanup()

Anwendung starten

Starten Sie das Skript mit folgendem Befehl:

1
../venv/bin/python -m flask --app app-interrupt.py run --host=0 0.0.0

Aufgaben und Fragestellungen

Schließen Sie einen zweiten Button an einen weiteren GPIO-Pin an. Erweitern Sie das Skript so, dass der Status beider Buttons auf der Webseite angezeigt wird.
Zurück
Weiter