Python-Programm für einen Zähler
Gefragt war ein Impulszähler mit einer graphischen Oberfläche. Wenn der Zähler einen Grenzwert erreicht, soll ein Ausgang geschaltet werden.
Weil tkinter in meiner Code-Sammlung noch fehlte, habe ich mich dahinter geklemmt:
tkinter ist etwas gewöhnungsbedürftig, aber nicht unüberwindbar.
Das Script
Nutzt die "Interrupts" von RPi.GPIO, um auch recht kurze Impulse zu erfassen. Weil es auf Flanken reagiert, ist es auf saubere Impulse angewiesen. Jegliches Prellen würde gnadenlos mitgezählt so lange die "Interrupts" schnell genug sind.
Wegen der Kohäsion sollte der Code für die GPIOs sollte eigentlich nicht in MainWindow stehen, aber der Einfachheit halber ist er trotzdem dort eingebaut. Bei einer Erweiterung müsste das refactored werden.
Die verwendeten GPIO-Pins und das Update-Intervall werden bei der Instanzierung der Klasse übergeben.
Das Limit wird im Konstruktor gesetzt. Das ist wahrscheinlich nicht passend für eine praktische Anwendung, kann aber einfach geändert werden.
from tkinter import Tk, Label, Button, E, X import RPi.GPIO as GPIO class MainWindow: """The GUI for this system It implements all the functions which are necessary for the application. """ def __init__( self, inputpin, outputpin, interval ): """Sets up the GPIOs and constructs the Window. Parameters ---------- inputpin: integer the GPIO pin used as input outputpin: integer the GPIO pin used as output interval: integer the interval between updates (ms) """ # Initialize the member variables self.limit = 10000 self.counter = 0 self.interval = interval self.outputpin = outputpin # Sets up the GPIOs GPIO.setmode( GPIO.BCM ) GPIO.setup( inputpin, GPIO.IN ) GPIO.setup( outputpin, GPIO.OUT ) GPIO.add_event_detect( inputpin, GPIO.RISING, callback=self.count ) GPIO.output( outputpin, GPIO.LOW ) # Constructs the Window self.root = Tk() self.root.title( "Found at http://blog.heimetli.ch" ) lbl = Label( self.root, text="Counter", font=("Helvetica",40,"bold") ) lbl.pack( fill=X ) self.label = Label( self.root, text=str(self.counter), anchor=E, width=7, font=("Helvetica",120,"bold") ) self.label.pack() lbl = Label( self.root, text="Limit", font=("Helvetica",40,"bold") ) lbl.pack( fill=X ) lbl = Label( self.root, text=str(self.limit), anchor=E, width=7, font=("Helvetica",120,"bold") ) lbl.pack() btn = Button( self.root, text="Reset", command=self.reset, font=("Helvetica",40,"bold") ) btn.pack() # Starts the update mechanism self.root.after( self.interval, self.update ) # Shows the window and runs the application self.root.mainloop() def update( self ): """Displays the current counter value and schedules a call to itself.""" self.label["text"] = str(self.counter) self.root.after( self.interval, self.update ) def count( self, channel ): """Counts the pulses.""" self.counter = self.counter + 1 # Turn off the machine if the limit is reached if self.counter >= self.limit: GPIO.output( self.outputpin, GPIO.HIGH ) def reset( self ): """Resets the counter.""" self.counter = 0 # Starts the application # # The GPIO used as input is GPIO4 # The GPIO used as output is GPIO18 # The window is updated every 100ms app = MainWindow( 4, 18, 100 )
Update 25.03.2020
Variablen umbenannt und die globalen Variablen zu Attributen der Klasse gemacht.