Tipps

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Manuel22
User
Beiträge: 17
Registriert: Donnerstag 12. November 2015, 23:31

hallo, ich beschäftige mich mit Python erst seit 4 tagen und muss aber das Projekt beenden. Nun hoffe ich, dass ihr mir helfen könnt oder mir mit dem folgenden Code Verbesserungen vorschlagen könnt. Man hat mir gesagt ich soll einfach mal ein Thema aufmachen und ein netter mod würde den Post dann verschieben also habt erbramen:D

der Code soll eine gui erstellen mit einem Zahlenfeld und ein paar ausgabenfelder mit dem man dann eine zahl eingibt. Ein ultraschallsensor soll währenddessen eigentlich immer den Absatnd messen und soll dann je nachdem ob der gemessene Wert höher oder niedriger ist was machen.
Vielen Dank im Voraus

Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-
import time
import RPi.GPIO as GPIO
import math
from threading import Thread
import os
from Tkinter import *

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

Trigger = 13
Echo = 16
Pumpe_zu = 22
Pumpe_raus = 18


GPIO.setup(Trigger, GPIO.OUT)
GPIO.setup(Echo, GPIO.IN)
GPIO.setup(Pumpe_zu, GPIO.OUT)
GPIO.setup(Pumpe_raus, GPIO.OUT)

def run():
       
        while True:	
                
                i=1
                Ergebniskette=0
                n=4
                
                #tempmessung()
                      
                while i<=n:
                           
                        GPIO.output(Trigger, True)
                        time.sleep(0.000001)
                        GPIO.output(Trigger, False)

                        while GPIO.input(Echo) == 0:
                                StartZeit = time.time()

                        while GPIO.input(Echo) == 1:
                                StopZeit = time.time()

                        Zeitdifferenz = StopZeit - StartZeit
	
		#Temperatur einbinden-------------------------------------------------------------------------------------
                        wurzel = math.sqrt(1 + (17.8 / 273.15))

                        Entfernung = Zeitdifferenz * 33150 *wurzel/2

                        print round(Entfernung,2)

                        Ergebniskette = Ergebniskette + Entfernung

                        time.sleep(1)

                        i=i+1
	
		
                Durchschnitt= round(Ergebniskette / n)

                wasseranzeige_string.set(str(Durchschnitt))
                fenster.update()

                time.sleep(10)


def eingabe_start():

    s=0
    
    while s<1:

        Wunschwert=int(eingabe.get())
        
        if Wunschwert >= 45:
            string.set("Bitte Wert unter 45 eingeben")
            eingabe.delete(0,END)
            break

        else:
            string.set("")
            
        s=s+1

def clear():
    string.set("blabla")    
    eingabe.delete(0,END)
    
        
fenster = Tk()
fenster.geometry("320x240")
fenster.resizable(width=NO, height=NO)

def zahl0():
        eingabe.insert(10,"0")
        
zahl0 = Button(fenster, text="0",bg="green", command=zahl0)
zahl0.place(x=60, y=185 , width=50, height=50)

def zahl1():
        eingabe.insert(10,"1")

zahl1 = Button(fenster, text="1",bg="green", command=zahl1)
zahl1.place(x=10, y=35 , width=50, height=50)

def zahl2():
        eingabe.insert(10,"2")

zahl2 = Button(fenster, text="2",bg="green", command=zahl2)
zahl2.place(x=60, y=35 , width=50, height=50)

def zahl3():
        eingabe.insert(10,"3")
        
zahl3 = Button(fenster, text="3",bg="green", command=zahl3)
zahl3.place(x=110, y=35 , width=50, height=50)

def zahl4():
        eingabe.insert(10,"4")
        
zahl4 = Button(fenster, text="4",bg="green", command=zahl4)
zahl4.place(x=10, y=85 , width=50, height=50)

def zahl5():
        eingabe.insert(10,"5")
        
zahl5 = Button(fenster, text="5",bg="green", command=zahl5)
zahl5.place(x=60, y=85 , width=50, height=50)

def zahl6():
        eingabe.insert(10,"6")
        
zahl6 = Button(fenster, text="6",bg="green", command=zahl6)
zahl6.place(x=110, y=85 , width=50, height=50)

def zahl7():
        eingabe.insert(10,"7")
        
zahl7 = Button(fenster, text="7",bg="green", command=zahl7)
zahl7.place(x=10, y=135 , width=50, height=50)

def zahl8():
        eingabe.insert(10,"8")
        
zahl8 = Button(fenster, text="8",bg="green", command=zahl8)
zahl8.place(x=60, y=135 , width=50, height=50)

def zahl9():
        eingabe.insert(10,"9")
        
zahl9 = Button(fenster, text="9",bg="green", command=zahl9)
zahl9.place(x=110, y=135 , width=50, height=50)

clear = Button (fenster,bg="green", text="C", command=clear)
clear.place(x=10, y=185 , width=50, height=50)

string= StringVar()
string_eingabe= StringVar()

enter = Button(fenster, text="B",bg="green",command=eingabe_start)
enter.place(x=110, y=185 , width=50, height=50)

eingabe= Entry(fenster, width=2,font=160)
eingabe.focus()
eingabe.place(x=10, y=10)

string= StringVar()
string.set("Wunschhöhe des Wassers")

ausgabe= Label(fenster,bg="Black",fg="White", textvariable=string)
ausgabe.config(font=20)
ausgabe.place(x=50,y=10)

wasserstand= Label (fenster,bg="Black", fg="White",text="Wasserstand:")
wasserstand.config(font=20)
wasserstand.place(x=160,y=85)

wasseranzeige_string=StringVar()
wasseranzeige=Label(fenster, bg="Black", fg="White", font=20, textvariable=wasseranzeige_string)
wasseranzeige.place(x=271, y=85)

tempanzeige_string= StringVar()
tempanzeige=Label(fenster,bg="Black", fg="White", textvariable=tempanzeige_string, font=20)
tempanzeige.place(x=200, y=110)

temperatur= Label(fenster,bg="Black", fg="White", text="Temperatur:")
temperatur.config(font=20)
temperatur.place(x=160, y=110)

fenster.update()

m=Thread(tareget=run())
m.start()

while True:

 		Durchschnitt= round(Ergebniskette / n)

                wasseranzeige_string.set(str(Durchschnitt))
                fenster.update()

                if Durchschnitt == Wunschwert:
                        string.set ("Wasserstand ist Okay")
                        fenster.update()
                        GPIO.output(Pumpe_zu, False)
                        GPIO.output(Pumpe_raus, False) 
                        continue

                elif Durchschnitt <= Wunschwert:
                        string.set( "Wasser wird reingepumpt")
                        fenster.update()
                        GPIO.output(Pumpe_zu, True)
                        continue

                elif Durchschnitt >= Wunschwert:
                        string.set("Wasser wird abgepumpt")
                        fenster.update()
                        GPIO.output(Pumpe_raus, True)
                        continue

fenster.mainloop()
Zuletzt geändert von Anonymous am Montag 16. November 2015, 13:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @Manuel22:

Du solltest Deinen Code hier als Code formatieren. Das ist gerade unter Python sehr wichtig.

Du beschäftigst Dich mit Python erst seit 4 Tagen - und in dieser Zeit hast Du den von Dir geposteten Code selbst erstellt?

Was ist da von Dir und was ist vor allem schrittweise erstellt und getestet?

MfG, kodela
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ohne den besagten Codeblock kann man den Code schlecht beurteilen.

Was man aber zumindest mal sagen kann:
* sinnvolle & aussagekräftige Variablennamen verwenden - `string` ist z.B. viel zu generisch
* du hast mit `zahl0` bis `zahl9` 10 Funktionen, die das gleiche machen - schreib' dir dafür eine Funktion, die du dann 10x mit den entsprechenden Werten aufrufst.
* grundsätzlich Programmlogik von Darstellung trennen
ich beschäftige mich mit Python erst seit 4 tagen und muss aber das Projekt beenden
Kannst du eine andere Programmiersprache? Weil wenn man nach 4 Tagen sich schon mit GUI-Programmierung beschäftigen kann (und versteht, was man da tut)... nicht schlecht.

Gruß, noisefloor
Manuel22
User
Beiträge: 17
Registriert: Donnerstag 12. November 2015, 23:31

oh okay.. ich versuche das nochmal:D
Der gesamte Code ist von mir selbst geschrieben und funktioniert auch teilweise.
Mein Problem damit ist, dass sich das gui Fenster nur ab und zu aktualisiert. Ich denke das liegt daran, dass ich einen Raspberry PI B benutze und der nur ein Kern hat und dieser dann mit dem ausführen des Threads beschäftigt ist obwohl das mit dem Thread ja eigentlich auch mit einem Kern gehen müsste dachte ich.

hoffe das ist jetzt richtig:D

Code: Alles auswählen

# -*- coding: utf-8 -*-
import time
import RPi.GPIO as GPIO
import math
from threading import Thread
import os
from Tkinter import *

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

Trigger = 13
Echo = 16
Pumpe_zu = 22
Pumpe_raus = 18


GPIO.setup(Trigger, GPIO.OUT)
GPIO.setup(Echo, GPIO.IN)
GPIO.setup(Pumpe_zu, GPIO.OUT)
GPIO.setup(Pumpe_raus, GPIO.OUT)

def run():
       
        while True:	
                
                i=1
                Ergebniskette=0
                n=4
                
                #tempmessung()
                      
                while i<=n:
                           
                        GPIO.output(Trigger, True)
                        time.sleep(0.000001)
                        GPIO.output(Trigger, False)

                        while GPIO.input(Echo) == 0:
                                StartZeit = time.time()

                        while GPIO.input(Echo) == 1:
                                StopZeit = time.time()

                        Zeitdifferenz = StopZeit - StartZeit
	
		#Temperatur einbinden-------------------------------------------------------------------------------------
                        wurzel = math.sqrt(1 + (17.8 / 273.15))

                        Entfernung = Zeitdifferenz * 33150 *wurzel/2

                        print round(Entfernung,2)

                        Ergebniskette = Ergebniskette + Entfernung

                        time.sleep(1)

                        i=i+1
	
		
                Durchschnitt= round(Ergebniskette / n)

                wasseranzeige_string.set(str(Durchschnitt))
                fenster.update()

                time.sleep(10)


def eingabe_start():

    s=0
    
    while s<1:

        Wunschwert=int(eingabe.get())
        
        if Wunschwert >= 45:
            string.set("Bitte Wert unter 45 eingeben")
            eingabe.delete(0,END)
            break

        else:
            string.set("")
            
        s=s+1

def clear():
    string.set("Wunschhöhe des Wassers")    
    eingabe.delete(0,END)
    
        
fenster = Tk()
fenster.title("Terra Systems")
fenster.geometry("320x240")
fenster.configure(bg="black")
fenster.resizable(width=NO, height=NO)

def zahl0():
        eingabe.insert(10,"0")
        
zahl0 = Button(fenster, text="0",bg="green", command=zahl0)
zahl0.place(x=60, y=185 , width=50, height=50)

def zahl1():
        eingabe.insert(10,"1")

zahl1 = Button(fenster, text="1",bg="green", command=zahl1)
zahl1.place(x=10, y=35 , width=50, height=50)

def zahl2():
        eingabe.insert(10,"2")

zahl2 = Button(fenster, text="2",bg="green", command=zahl2)
zahl2.place(x=60, y=35 , width=50, height=50)

def zahl3():
        eingabe.insert(10,"3")
        
zahl3 = Button(fenster, text="3",bg="green", command=zahl3)
zahl3.place(x=110, y=35 , width=50, height=50)

def zahl4():
        eingabe.insert(10,"4")
        
zahl4 = Button(fenster, text="4",bg="green", command=zahl4)
zahl4.place(x=10, y=85 , width=50, height=50)

def zahl5():
        eingabe.insert(10,"5")
        
zahl5 = Button(fenster, text="5",bg="green", command=zahl5)
zahl5.place(x=60, y=85 , width=50, height=50)

def zahl6():
        eingabe.insert(10,"6")
        
zahl6 = Button(fenster, text="6",bg="green", command=zahl6)
zahl6.place(x=110, y=85 , width=50, height=50)

def zahl7():
        eingabe.insert(10,"7")
        
zahl7 = Button(fenster, text="7",bg="green", command=zahl7)
zahl7.place(x=10, y=135 , width=50, height=50)

def zahl8():
        eingabe.insert(10,"8")
        
zahl8 = Button(fenster, text="8",bg="green", command=zahl8)
zahl8.place(x=60, y=135 , width=50, height=50)

def zahl9():
        eingabe.insert(10,"9")
        
zahl9 = Button(fenster, text="9",bg="green", command=zahl9)
zahl9.place(x=110, y=135 , width=50, height=50)

clear = Button (fenster,bg="green", text="C", command=clear)
clear.place(x=10, y=185 , width=50, height=50)

string= StringVar()
string_eingabe= StringVar()

enter = Button(fenster, text="B",bg="green",command=eingabe_start)
enter.place(x=110, y=185 , width=50, height=50)

eingabe= Entry(fenster, width=2,font=160)
eingabe.focus()
eingabe.place(x=10, y=10)

string= StringVar()
string.set("Wunschhöhe des Wassers")

ausgabe= Label(fenster,bg="Black",fg="White", textvariable=string)
ausgabe.config(font=20)
ausgabe.place(x=50,y=10)

wasserstand= Label (fenster,bg="Black", fg="White",text="Wasserstand:")
wasserstand.config(font=20)
wasserstand.place(x=160,y=85)

wasseranzeige_string=StringVar()
wasseranzeige=Label(fenster, bg="Black", fg="White", font=20, textvariable=wasseranzeige_string)
wasseranzeige.place(x=271, y=85)

tempanzeige_string= StringVar()
tempanzeige=Label(fenster,bg="Black", fg="White", textvariable=tempanzeige_string, font=20)
tempanzeige.place(x=200, y=110)

temperatur= Label(fenster,bg="Black", fg="White", text="Temperatur:")
temperatur.config(font=20)
temperatur.place(x=160, y=110)

fenster.update()

m=Thread(tareget=run())
m.start()

while True:

 		Durchschnitt= round(Ergebniskette / n)

                wasseranzeige_string.set(str(Durchschnitt))
                fenster.update()

                if Durchschnitt == Wunschwert:
                        string.set ("Wasserstand ist Okay")
                        fenster.update()
                        GPIO.output(Pumpe_zu, False)
                        GPIO.output(Pumpe_raus, False) 
                        continue

                elif Durchschnitt <= Wunschwert:
                        string.set( "Wasser wird reingepumpt")
                        fenster.update()
                        GPIO.output(Pumpe_zu, True)
                        continue

                elif Durchschnitt >= Wunschwert:
                        string.set("Wasser wird abgepumpt")
                        fenster.update()
                        GPIO.output(Pumpe_raus, True)
                        continue

fenster.mainloop()
Manuel22
User
Beiträge: 17
Registriert: Donnerstag 12. November 2015, 23:31

Kannst du eine andere Programmiersprache? Weil wenn man nach 4 Tagen sich schon mit GUI-Programmierung beschäftigen kann (und versteht, was man da tut)... nicht schlecht.

dankeschön:)

nein ich kann eigentlich keine andere Sprache, deswegen mach ich ja auch die Fehler, die du angesprochen hast:D Weil ich dachte mir, dass es mit den Funktionen und den Buttons vielleicht irgendwie einfacher geht nur hab ich das noch nicht raus:D
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Der gesamte Code ist von mir selbst geschrieben und funktioniert auch teilweise.
Kommt irgendwann eine Fehlermeldung? Wenn ja, welche?
Mein Problem damit ist, dass sich das gui Fenster nur ab und zu aktualisiert.
Sollte halt immer der Fall sein, wenn du `update()` aufrufst.

Grundsätzlich kann auch das Mixen des Mainloops mit einem externen Thread problematisch sein - allerdings habe ich da selber zu wenig Erfahrung um zu sagen, ob das bei dir ein Problem sein könnte. Aber andere wissen das bestimmt :-)

Gruß, noisefloor
Manuel22
User
Beiträge: 17
Registriert: Donnerstag 12. November 2015, 23:31

Ne es funktioniert eigentlich nur eben will ich, dass das Fenster immer aktualisiert wird.
Habe jetzt vor einen Raspberry Pi 2 mit 4 Kernen zu nehmen. Hoffe das löst das Problem..
weil ich muss ja einen extrernen Thread erstellen oder? weil ich will ja, dass die Messung immer durchgeführt wird. wie eine Art polling
Eine andere Frage ist noch wie es mit den Variablen ist. Wenn der Thread arbeitet und nach den Messungen einen Wert in "Durchschnitt" speichert habe ich dann auch außerhalb des Threads darauf zugriff? Oder nur innerhalb des Threads?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Manuel22: damit man Deinen Code überhaupt lesen will, solltest Du einiges überarbeiten. Auf oberster Ebene sollten außer Definitionen und Konstanten nichts stehen. Das Mischen von Funktionsdefinitionen und Anweisungen macht alles sehr unübersichtlich. Die ganzen Anweisungen (zum GPIO-Initalisierung, GUI-Aufbau, usw.) packst Du am besten in eine Funktion, die man üblicherweise "main" nennt. Dann solltest Du alles, was per Copy-Paste entstanden ist, zu einer Funktion mit Parametern zusammenfassen. Eine Schleife zum Erzeugen der ganzen Buttons wäre auch nicht schlecht. Sternchenimporte sind schlecht, da sie unkontrolliert den eigenen Namensraum zumüllen. Ich importiere Tkinter immer als "import Tkinter as tk" und greife auf die Elemente z.B. per "tk.Button" zu.

Dein eigentliches Problem ist, dass Du keinen Thread startest, sondern den Rückgabewert der Funktion run. So sollte es heißen:

Code: Alles auswählen

m=Thread(target=run)
Die nachfolgende while-Schleife sollte dann auch noch in einen Thread wandern.
Die Einrückungen stimmen auch noch nicht ganz, so läuft das Programm eigentlich nicht. Wenn Du weißt, wie oft eine while-Schleife durchlaufen wird, solltest Du eine for-Schleife nehmen. Eine while-Schleife, die genau 1mal durchlaufen wird, ist dann auch ziemlich sinnfrei.
Manuel22
User
Beiträge: 17
Registriert: Donnerstag 12. November 2015, 23:31

okay, danke
versuch ich gleich mal alles umzusetzten:)
Antworten