ich suche nun schon seit tagen und komme nicht wirklich weiter. Dazu muss ich sagen, daß ich ein Python-Frischling bin.
Ich bin dabei ein kleines Programm zu schreiben, welches über eine Raspberry Pi2 mit Python 3.4.3 die Impulse eines Messgerätes zählt.
Der Part mit dem GPIO und Abfrage der Impulse (möglichst viele - ca. max. 5000/min gibt das Messgerät - da kann der Raspi nicht mit, macht aber nichts, ca. 500/min bekomme ich maximal mit) ist nun nicht das Problem. Möchte aber gern die Verzögerungen so gering als möglich halten.
Angefangen habe ich mit einer GUI mit TKinter. Da die Software in Zukunft aber nur optional mit einer Grafischen Oberfläche laufen soll, möchte ich Tkinter nur modular laden, wenn das Programm über VNC oder direkten Anschluss an Monitor/Tastatur/Maus aufgerufen wird.
Die anderen Optionen wären dann ein Aufruf über den GPIO (einen Taster drücken) mit Darstellung der Werte über ein LCD-Display oder der Aufruf über SSH und Steuerung über eine Handy-App.
Da alle optionen zusammen na klar Rechenleistung erfordern, würd ich gern nur die Option(en) laden, welche auch benötigt werden bzw. auch verbaut sind.
Aktuell hab ich halt das Problem, daß ich Tkinter nur optional in einem Thread aufrufen möchte und die Daten dann per Queue austauschen möchte:
Der User sagt: mach mir eine Summe über 1 / 3 oder 5 Minuten, Starte die Messung, Beende die Messung würd von der GUI kommen.
Das eigendliche Programm gibt dann halt alle 1 / 3 oder 5 Minuten zurück: Summe X / Durchschnitt vorher.
Diese Informationen werden dann alternativ / optional auch auf einem LCD-Display bereitgestellt und in Zukunft auch über eine Verbindung zum Handy.
Evtl. hat da jemand einen Tip für mich.
Der aktuelle Code funktioniert nicht. Ich hab mal eine alte Version angehangen. Tkinter soll halt in einen eigenen Thread abgeteilt werden. Über Kritik würde ich mich auch sehr freuen.
Code: Alles auswählen
#!/usr/bin/env python3.4
from tkinter import *
import datetime
import time
import pigpio
import threading
import sys
import mysql.connector
import LCD_PIGPIO
import os
Hauptfenster = Tk()
Hauptfenster.title("Sferics-Test ")
Hauptfenster.geometry("300x400+30+30")
Anzeigefeld = Label(Hauptfenster, text="Herzlich Willkommen", bg="light grey")
Anzeigefeld.pack(pady=10)
FrequenzAbfrage = Entry(Hauptfenster)
FrequenzAbfrage.pack(pady=10)
ReadFreqButton = Button(Hauptfenster, text="Abfragezeit in Minuten angeben")
ReadFreqButton.pack(pady=10)
DoitButton = Button(Hauptfenster, text="Warte auf Eingabe der Abfragezeit", state=DISABLED)
DoitButton.pack(pady=10)
Wertefeld = Label(Hauptfenster, text="", bg="light grey")
Wertefeld.pack(pady=10)
ShutdownButton = Button(Hauptfenster, text="Herunterfahren")
ShutdownButton.pack(pady=10)
#LED_PIN = 5
OPTO_PIN = 6
ZAEHLTAST_PIN = 12
STARTTAST_PIN = 13
SHUTDOWNTAST_PIN = 16
Aktiv = 0
AbfrageFrequenz = 0
AktuelleSumme = 0
LetzteSumme = 0
LetzteSumme2 = 0
LetzteSumme3 = 0
#LedAn = 0
Tabellenname = "Werte"
StartTastAktiv = 0
ShutdownTastAktiv = 0
ZaehlTastAktiv = 0
OptoAktiv = 0
TICK = 0
def usleep(microseconds):
"""Sleep the specified amount of microseconds."""
time.sleep(microseconds / 1000000.0)
def Datenbank_aktivieren():
global Datenbank
global Datentabelle
global Tabellenname
Tabellenname = "Werte-" + time.strftime("%Y%m%d")
Datenbank = mysql.connector.connect(host='localhost', user='root', password='Metwurst', db='Messwerte',autocommit=True)
Datentabelle = Datenbank.cursor()
Tabellenstring = """\
CREATE TABLE IF NOT EXISTS `""" + Tabellenname + """`(
ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
Unixzeit DOUBLE(18,7) NOT NULL,
Wert INTEGER
)"""
Datentabelle.execute(Tabellenstring)
def Datenbank_schreiben():
global Datenbank
global Datentabelle
global Tabellenname
global AktuelleSumme
global LetzteSumme
global LetzteSumme2
global LetzteSumme3
global LCD
global Startzeit
LetzterDurchschnitt = 0
# unixzeit = float(time.time())
# windowszeit= ((unixzeit/86400)+25569)
Anzeigestring = "Summe: " + str(AktuelleSumme) + " um " + time.strftime("%H:%M:%S")
LCDString = "Summe: " + str(AktuelleSumme)
Anzeigestring += chr(13) + chr(13)
Anzeigestring += "Vorherige Summe: " + str(LetzteSumme) + chr(13) + chr(13) + "Tendenz: "
LCD2String = "Vorher:" + str(LetzteSumme) + " T:"
Gesamtsumme = LetzteSumme + LetzteSumme2 + LetzteSumme3
if LetzteSumme3 > 0:
LetzterDuchschnitt = Gesamtsumme / 3
else
if letzteSumme2 > 0:
LetzterDuchschnitt = Gesamtsumme / 2
else
LetzterDurchschnitt = Gesamtsumme
if LetzterDurchschnitt == AktuelleSumme:
Anzeigestring += "gleichbleibend"
LCD2String += " ="
elif LetzterDurchschnitt > AktuelleSumme:
Anzeigestring += "Fallend"
LCD2String += " <"
elif LetzterDurchschnitt < AktuelleSumme:
Anzeigestring += "Steigend"
LCD2String += " >"
Wertefeld["text"] = Anzeigestring
Tabellenstring = """\
INSERT INTO `""" + Tabellenname + """`(
Unixzeit,
Wert
) VALUES ( """ + str(Startzeit + (AbfrageFrequenz*60)) + ", " + str(AktuelleSumme) + ")"
LCD.clear()
LCD.write_string(LCDString + '\n\r' + LCD2String)
Datentabelle.execute(Tabellenstring)
LetzteSumme3 = LetzteSumme2
LetzteSumme2 = LetzteSumme
LetzteSumme = AktuelleSumme
AktuelleSumme = 0
def Messwert_da():
global Startzeit
global AktuelleSumme
global AbfrageFrequenz
#LED_steuern()
if (Startzeit + (AbfrageFrequenz*60)) <= float(time.time()):
#Startseit muss noch neu berechnet werden - falls mal eine Minute nix passiert
Startzeit = float(time.time())
Datenbank_schreiben()
AktuelleSumme = AktuelleSumme + 1
#def LED_steuern():
# global LedAn
# global LED_PIN
# global gpio
#if LedAn == 0:
# gpio.write(LED_PIN, 0)
# LedAn = 1
#else:
# Hauptfenster.update()
# gpio.write(LED_PIN, 1)
# LedAn = 0
#def Impuls_erkannt(gpio, level, tick):
# LED_steuern()
# Messwert_da()
def Messung_starten_beenden():
global Aktiv
global AbfrageFrequenz
global LCD
global Startzeit
#global LED_PIN
#global gpio
#global OPTO_PIN
#global Starttast
#global STARTTAST_PIN
#if not gpio:
# GPIO_aktivieren()
Startzeit = float(time.time())
if Aktiv == 0:
Aktiv = 1
Datenbank_aktivieren()
Zaehltast_deaktivieren()
Shutdown_deaktivieren()
ReadFreqButton["state"] = "disabled"
ShutdownButton["state"] = "disabled"
FrequenzAbfrage["state"] = "disabled"
DoitButton["text"] = "beenden"
Anzeigefeld["text"] = "Abfrage eingestellt auf " + str(AbfrageFrequenz) + " Minuten" + chr(13) + "Messung gestartet"
Anzeigefeld["bg"] = "red"
LCD.clear()
LCD.write_string("Messung start\n\r keine Werte")
Startzeit = float(time.time())
Opto_aktivieren()
#Zaehltast_aktivieren()
#Shutdown_aktivieren()
else:
Aktiv = 0
Opto_deaktivieren()
Datenbank.close()
ReadFreqButton["state"] = "active"
ShutdownButton["state"] = "active"
FrequenzAbfrage["state"] = "normal"
DoitButton["text"] = "starten"
Anzeigefeld["text"] = "Abfrage eingestellt auf " + str(AbfrageFrequenz) + " Minuten" + chr(13) + "Messung beendet"
Anzeigefeld["bg"] = "light grey"
LCD.clear()
LCD.write_string("Messung stop\n\r" + time.strftime("%H:%M:%S"))
Zaehltast_aktivieren()
Shutdown_aktivieren()
#Startzeit = float(time.time())
#Opto_aktivieren()
#gpio.set_pull_up_down(OPTO_PIN, pigpio.PUD_UP)
#Opto1 = gpio.callback(OPTO_PIN, pigpio.FALLING_EDGE, Callback_detected)
#Opto1 = gpio.callback(OPTO_PIN, pigpio.FALLING_EDGE, Impuls_erkannt)
#gpio.set_pull_up_down(STARTTAST_PIN, pigpio.PUD_UP)
#Starttast = gpio.callback(STARTTAST_PIN, pigpio.FALLING_EDGE, Callback_detected)
#usleep(1)
#LCD.clear()
#LCD.write_string("Messung start\n\r keine Werte")
#while Aktiv==1:
# Hauptfenster.update()
# usleep(1)
# if (Startzeit + (AbfrageFrequenz*60)) <= float(time.time()):
# Datenbank_schreiben()
# Startzeit = float(time.time())
#else:
#Opto1.cancel()
# Opto_deaktivieren()
# LCD.clear()
# LCD.write_string("Messung beendet\n\r Tanke")
# gpio.write(LED_PIN, 1)
# gpio.set_pull_up_down(OPTO_PIN, pigpio.PUD_OFF)
# Datenbank.close()
def FrequenzLesen():
global AbfrageFrequenz
global StartTastAktiv
try:
AbfrageFrequenz = float(FrequenzAbfrage.get())
Anzeigefeld["text"] = "Abfrage eingestellt auf " + str(AbfrageFrequenz) + " Minuten"
Anzeigefeld["bg"] = "light grey"
DoitButton["text"] = "Starten"
DoitButton["state"] = "active"
LCD.clear()
LCD.write_string('Alle ' + str(AbfrageFrequenz) + ' min\n\r Start klicken')
if StartTastAktiv == 0:
StartTastAktiv = 1
Starttast_aktivieren()
except ValueError:
Anzeigefeld["text"] = "Bitte eine gueltige Zahl eingeben"
Anzeigefeld["bg"] = "red"
DoitButton["text"] = "Warte auf Eingabe der Abfragezeit"
DoitButton["state"] = "disabled"
StartTastAktiv = 0
Starttast_deaktivieren()
print('Mist')
return(0)
def Callback_detected(cb_gpio, level, tick):
global gpio
global TICK
global ZAEHLTAST_PIN
global STARTTAST_PIN
global SHUTDOWNTAST_PIN
global OPTO_PIN
global ZaehlTastAktiv
global StartTastAktiv
global ShutdownTastAktiv
global OptoAktiv
if cb_gpio == OPTO_PIN:
if OptoAktiv == 1:
#print('opto ', tick)
Messwert_da()
else:
if (TICK + 200000) < tick:
TICK = tick
print('GPIO:', cb_gpio, '\n Level:' , level, '\n tick:', tick)
if level == 0:
if cb_gpio == ZAEHLTAST_PIN:
if ZaehlTastAktiv == 1:
#print('Zaehler hoch')
Frequenz_einstellen()
elif cb_gpio == STARTTAST_PIN:
if StartTastAktiv == 1:
#print('Startstop gedrueckt')
Messung_starten_beenden()
elif cb_gpio == SHUTDOWNTAST_PIN:
if ShutdownTastAktiv == 1:
#print('Runterfahren gedrueckt')
Herunterfahren()
elif level == 1:
print('falscher Level ', str(level))
if cb_gpio == ZAEHLTAST_PIN:
print('Zaehler hoch')
#Frequenz_einstellen()
elif cb_gpio == STARTTAST_PIN:
print('Startstop gedrueckt')
#Messung_Start_aktivieren()
elif cb_gpio == SHUTDOWNTAST_PIN:
print('Runterfahren gedrueckt')
else:
print('falscher Level ', str(level))
if cb_gpio == ZAEHLTAST_PIN:
print('Zaehler hoch')
#Frequenz_einstellen()
Zaehltast_deaktivieren()
elif cb_gpio == STARTTAST_PIN:
print('Startstop gedrueckt')
#gpio.set_watchdog(STARTTAST_PIN,10)
#Messung_Start_aktivieren()
Starttast_deaktivieren()
elif cb_gpio == SHUTDOWNTAST_PIN:
print('Runterfahren gedrueckt')
Shutdown_deaktivieren()
#Zaehltast_deaktivieren()
#Starttast_deaktivieren()
#Opto_deaktivieren()
stop()
#def Messung_Start_aktivieren():
# global Aktiv
# global gpio
# global LCD
#if not gpio:
# print("Kein GPIO - also GPIO-aktivieren")
# GPIO_aktivieren()
# if Aktiv == 0:
# Zaehltast_deaktivieren()
# Shutdown_deaktivieren()
# ReadFreqButton["state"] = "disabled"
# ShutdownButton["state"] = "disabled"
# FrequenzAbfrage["state"] = "disabled"
# DoitButton["text"] = "beenden"
# Anzeigefeld["text"] = "Abfrage eingestellt auf " + str(AbfrageFrequenz) + " Minuten" + chr(13) + "Messung gestartet"
# Anzeigefeld["bg"] = "red"
# Aktiv = 1
# Messung_starten()
# LCD.clear()
# LCD.write_string("Messung stop\n\r" + time.strftime("%H:%M:%S"))
#Zaehltast_aktivieren()
#Shutdown_aktivieren()
# else:
# ReadFreqButton["state"] = "active"
# ShutdownButton["state"] = "active"
# FrequenzAbfrage["state"] = "normal"
# DoitButton["text"] = "starten"
# Anzeigefeld["text"] = "Abfrage eingestellt auf " + str(AbfrageFrequenz) + " Minuten" + chr(13) + "Messung beendet"
# Anzeigefeld["bg"] = "light grey"
# Aktiv = 0
#Zaehltast_aktivieren()
#Shutdown_aktivieren()
# return(0)
def GPIO_aktivieren():
global gpio
gpio = pigpio.pi()
gpio.set_mode(LED_PIN, pigpio.OUTPUT)
gpio.write(LED_PIN, 1)
def LCD_aktivieren():
global LCD
global gpio
LCD = LCD_PIGPIO.CharLCD (MYGPIO=gpio, cols=16, rows=2)
LCD.clear()
LCD.write_string('Hallo Jens\n\r viel Spass')
def Herunterfahren():
global gpio
global LCD
Zaehltast_deaktivieren()
Starttast_deaktivieren()
LCD.clear()
LCD.write_string('Herunterfahren')
gpio.stop()
os.system("sudo shutdown -h now")
Hauptfenster.destroy()
def Frequenz_einstellen():
global AbfrageFrequenz
if AbfrageFrequenz == 0:
AbfrageFrequenz = 1
elif AbfrageFrequenz < 3:
AbfrageFrequenz = 3
elif AbfrageFrequenz < 5:
AbfrageFrequenz = 5
elif AbfrageFrequenz < 10:
AbfrageFrequenz = 10
elif AbfrageFrequenz < 15:
AbfrageFrequenz = 15
elif AbfrageFrequenz == 15:
AbfrageFrequenz = 1
elif AbfrageFrequenz > 15:
AbfrageFrequenz = 1
print(AbfrageFrequenz)
FrequenzAbfrage.delete(0,10)
FrequenzAbfrage.insert(1,str(AbfrageFrequenz))
FrequenzLesen()
def Shutdown_aktivieren():
global gpio
global SHUTDOWNTAST_PIN
global Shutdowntast
global ShutdownTastAktiv
gpio.set_pull_up_down(SHUTDOWNTAST_PIN, pigpio.PUD_UP)
Shutdowntast = gpio.callback(SHUTDOWNTAST_PIN, pigpio.FALLING_EDGE, Callback_detected)
ShutdownButton["state"] = "active"
usleep(2000)
ShutdownTastAktiv = 1
def Shutdown_deaktivieren():
global gpio
global SHUTDOWNTAST_PIN
global Shutdowntast
global ShutdownTastAktiv
ShutdownTastAktiv = 0
Shutdowntast.cancel()
gpio.set_pull_up_down(SHUTDOWNTAST_PIN, pigpio.PUD_OFF)
def Zaehltast_aktivieren():
global gpio
global ZAEHLTAST_PIN
global Zaehltast
global ZaehlTastAktiv
gpio.set_mode(ZAEHLTAST_PIN, pigpio.INPUT)
gpio.set_pull_up_down(ZAEHLTAST_PIN, pigpio.PUD_UP)
Zaehltast = gpio.callback(ZAEHLTAST_PIN, pigpio.FALLING_EDGE, Callback_detected)
usleep(20000)
ZaehlTastAktiv = 1
def Zaehltast_deaktivieren():
global gpio
global ZAEHLTAST_PIN
global Zaehltast
global ZaehlTastAktiv
ZaehlTastAktiv = 0
Zaehltast.cancel()
gpio.set_pull_up_down(ZAEHLTAST_PIN, pigpio.PUD_OFF)
def Starttast_aktivieren():
global gpio
global STARTTAST_PIN
global Starttast
global StartTastAktiv
gpio.set_mode(STARTTAST_PIN, pigpio.INPUT)
gpio.set_pull_up_down(STARTTAST_PIN, pigpio.PUD_UP)
Starttast = gpio.callback(STARTTAST_PIN, pigpio.FALLING_EDGE, Callback_detected)
usleep(20000)
StartTastAktiv = 1
def Starttast_deaktivieren():
global gpio
global STARTTAST_PIN
global Starttast
global StartTastAktiv
if StartTastAktiv == 1:
StartTastAktiv = 0
Starttast.cancel()
gpio.set_pull_up_down(STARTTAST_PIN, pigpio.PUD_OFF)
def Opto_aktivieren():
global gpio
global OPTO_PIN
global Opto1
global OptoAktiv
gpio.set_pull_up_down(OPTO_PIN, pigpio.PUD_UP)
Opto1 = gpio.callback(OPTO_PIN, pigpio.FALLING_EDGE, Callback_detected)
usleep(20000)
OptoAktiv = 1
def Opto_deaktivieren():
global gpio
global OPTO_PIN
global Opto1
global OptoAktiv
OptoAktiv = 0
Opto1.cancel()
gpio.set_pull_up_down(OPTO_PIN, pigpio.PUD_OFF)
ShutdownButton["command"] = Herunterfahren
ReadFreqButton["command"] = FrequenzLesen
DoitButton["command"] = Messung_starten_beenden
GPIO_aktivieren()
LCD_aktivieren()
Shutdown_aktivieren()
Zaehltast_aktivieren()
mainloop()