Seite 1 von 2

Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 10:30
von Consti9_9
Hallo zusammen,

ich habe gerade das Problem das ich eine Variable an meinem Display anzeigen will. Hierbei handelt es sich um Stromwerte nach einer ADC Messung. Das Programm hierfür ist schon fertig.
Jedoch möchte ich diese Variablen jetzt in einem anderen Programm in dem ich das Display ansteuere die Variablen importieren.
Mit dem Befehl:

from ADC_funkt import f,k

startet das Programm zwar, jedoch werden mir alle 8 Stromwerte angezeigt und das Programm startet nicht die Display Oberfläche.
Was könnte hier der Fehler sein?

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 10:48
von Sirius3
@Consti9_9: da keiner Dein Programm kennt, kann man dazu nichts sagen. Es kommen auch plötzlich 8 Stromwerte vor, und Du verrätst nicht, woher die plötzlich kommen. Statt ›Programm‹ meinst Du wahrscheinlich ›Modul‹ und das sollte ohne Nebeneffekte importierbar sein, was wahrscheinlich dein Problem erklärt.

Für eine vollständige Fehlerbeschreibung fehlt der Code, die Fehlermeldung und der Traceback, falls einer auftritt und eben eine verständliche Erklärung.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 10:51
von noisefloor
Hallo,

die Beschreibung ist ein bisschen schwer zu verstehen.

Grundsätzlich: wenn du eine Variable aus eine anderen Modul importierst, importierst du den Wert zum Zeitpunkt des Imports. Die Variable aktualisiert sich nicht auto-magisch. Für den Datenaustausch zwischen zwei unabhängigen Programmen läuft anders, da gibt es verschiedene Methoden, dass zu machen.

Besser wäre auch, wenn du mal deinen Quellcode zeigst, damit zu sehen ist, was du schon probiert hast.

Gruß, noisefloor

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 10:59
von Consti9_9
Das erste Programm berechnet Stromwerte mittels Strommesssensoren und einem AD-Wandler welche dann die Stromwerte anzeigt. Diese Werte will ich dann anschließend an dem Raspi-Display anzeigen jedoch in einem anderen Programm 2.

Programm 1(ADC_funkt):

Code: Alles auswählen

from mcp3208 import MCP3208 #import des MCP Moduls
import time #import des Zeitmoduls um Zeitverzögerungen zu erstellen
adc = MCP3208() #Namen um MCP ansprechen zu können und zu verkürzen
global  a #Definition Variable a
import numpy #Import der Bibliothek für Mittelwerte


while True: #Endlosschleife
    werte_0 = [] #Liste erstellen
    for i in range(32):
        werte_0.append(adc.read(0)) #Auslesen des 0. Kanals
    #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
    a = 3103 - numpy.mean(werte_0) #Berechnen der Differenz
    j = (a/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
    print("Stromwert 1:",j.round(3)) #Ausgabe des Stromwerts
    werte_1 = [] #Liste erstellen
    for i in range(32):
        werte_1.append(adc.read(1)) #Auslesen des 0. Kanals
    #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
    b = 3103 - numpy.mean(werte_1) #Berechnen der Differenz
    k = (b/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
    print("Stromwert 2:",k.round(3)) #Ausgabe des Stromwerts
    werte_2 = [] #Liste erstellen
    for i in range(32):
        werte_2.append(adc.read(2)) #Auslesen des 0. Kanals
    #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
    c = 3103 - numpy.mean(werte_2) #Berechnen der Differenz
    l = (c/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
    print("Stromwert 3:",l.round(3)) #Ausgabe des Stromwerts
    time.sleep(1) 
Programm 2(Taster):

Code: Alles auswählen

from tkinter import *
import tkinter as tk
import tkinter.font
#import Imagetk
import RPi.GPIO as GPIO
from ADC_funkt import j,k
          
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)

GPIO.setup(23, GPIO.OUT)
GPIO.output(23, GPIO.LOW)
GPIO.setup(24, GPIO.OUT)
GPIO.output(24, GPIO.LOW)
GPIO.setup(19, GPIO.OUT)
GPIO.output(19, GPIO.LOW)
GPIO.setup(25, GPIO.OUT)
GPIO.output(25, GPIO.LOW)

#Erstellen des Fenster
win = Tk()
#image = PhotoImage(file="hintergrund.jpg")
win.attributes("-fullscreen",True)
#background=Label(win, image=image)
#background.place(x=0,y=0,relwidth=1, relheights=1)


#Erstellen eines Hintergrunds
#image = PhotoImage(file="background.jpg")
#background=Label(win, image=image)
#background.place(x=0,y=0,relwidth=1, relheight=1)

#Erstellen einer Schrift
myFont = tkinter.font.Font(family = 'Helvetica', size = 20, weight = 'bold')

#Buttons 
def ScheinwerferON():
        print("Scheinwerfer eingeschaltet")
        if GPIO.input(23) :
            GPIO.output(23,GPIO.LOW)
            ScheinwerferButton["text"] = "Scheinwerfer an"
        else:
            GPIO.output(23,GPIO.HIGH)
            ScheinwerferButton["text"] = "Scheinwerfer aus"

def LuftpumpeON():
        print("Luftpumpe eingeschaltet")
        if GPIO.input(24) :
            GPIO.output(24,GPIO.LOW)
            LuftpumpeButton["text"] = "Luftpumpe an"
        else:
            GPIO.output(24,GPIO.HIGH)
            LuftpumpeButton["text"] = "Luftpumpe aus"

def LautsprecherON():
        print("Lautsprecher eingeschaltet")
        if GPIO.input(25) :
            GPIO.output(25,GPIO.LOW)
            LautsprecherButton["text"] = "Lautsprecher an"
        else:
            GPIO.output(25,GPIO.HIGH)
            LautsprecherButton["text"] = "Lautsprecher aus"
            
            
def KühlboxON():
        print("Kühlbox eingeschaltet")
        if GPIO.input(19) :
            GPIO.output(19,GPIO.LOW)
            KühlboxButton["text"] = "Kühlbox an"
        else:
            GPIO.output(19,GPIO.HIGH)
            KühlboxButton["text"] = "Kühlbox aus"

def exitProgram():
        win.destroy()
        print("Exit Button pressed")
        GPIO.cleanup()

#Name und Groese des Fensters
win.title("BeachBuggy")
win.geometry('800x480')

#Definition des Exit Buttons
exitButton = Button(win, text = "Exit", font = myFont, command = exitProgram, height = 2, width = 5)
exitButton.place(x=300, y=200)

#Definition des Luftpumpe Buttons
LuftpumpeButton = Button(win, text = "Luftpumpe ein", font = myFont, command = LuftpumpeON, height = 2, width = 14)
LuftpumpeButton.place(x=525, y=50)

#Definition des Kühlbox Buttons
KühlboxButton = Button(win, text = "Kühlbox ein", font = myFont, command = KühlboxON, height = 2, width = 14)
KühlboxButton.place(x=525, y=150)

#Definition des Lautsprecher Buttons
LautsprecherButton = Button(win, text = "Lautsprecher ein", font = myFont, command = LautsprecherON, height = 2, width = 14)
LautsprecherButton.place(x=525, y=350)

#Definiton des LED Buttons
ScheinwerferButton = Button(win, text = "Scheinwerfer ein", font = myFont, command = ScheinwerferON, height = 2, width = 14)
ScheinwerferButton.place(x=525, y=250)

mainloop()
Möchte es an dem Display anzeigen an welchem schon Taster zu sehen sind und Ausgänge ein und ausgeschaltet werden können.
Hierbei soll dann neben dem Ausgang der jeweilige Stromwert zu sehen sein.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:03
von Consti9_9
Und das Problem ist schätze ich das Programm 1 eine Endlosschleife ist und somit das Programm 2 nie weiter machen kann. Nur wie kann ich das verhindern weil die Werte müssen ja immer neu berechnet werden und dann in Programm 2 sich ändern

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:16
von Sirius3
@Consti9_9: Du redest immer von Programmen, aber es gibt immer nur ein Programm, das aus verschiedenen Modulen zusammengesetzt werden kann. Ein Modul besteht aus Funktionen, Du mußt also „Programm1” in eine Funktion umschreiben, die genau einmal mißt, keine Endlosschleife. Diese Funktion kannst Du dann regelmäßig in Deinem Tk-Inter-Programm aufrufen, z.B. per after.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:20
von Sirius3
Zum Programm selbst: `global` solltest Du nicht verwenden, macht auch, wie Du es benutzt, keinen Sinn. In der while-Schleife wird drei mal das selbe gemacht, was man gut in eine Funktion, die man drei mal aufruft, auslagern kann. Die Kommentare sind allesamt überflüssig, da sie nur beschreiben, was sowieso im Code steht, außer dass im Kommentar nicht die Änderungen beim Kopieren gemacht wurden, die im Code gemacht wurden, so dass die beiden sich widersprechen.
›ADC_funkt‹ ist ein seltsamer Name, denn da funkt ja gar nichts, sondern es wird nur eingelesen.

Für GUI-Programme braucht man relativ schnell Klassen, weil es sonst unübersichtlich wird. Funktionen sollten nur das benutzen, was sie per Argumente bekommen. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 8 und mal 4.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:30
von Consti9_9
Und wie schaffe ich es jetzt dann das obere in eine Funktion zu schreiben und diese dann in einem Label im unteren (welches noch nicht vorhanden ist) zu schreiben das es dann am Display angezeigt wird?

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:33
von Sirius3
Wie Funktionen geschrieben werden, hast Du scheinbar schon verstanden. Wo ist das konkrete Problem?

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:34
von __deets__
Den Code, den du hast, in eine Funktion stecken. Und die while-Schleife entfernen, ebenso wie die ueberfluessigen weil falschen Kommentare. Oder liest du wirklich 3mal ADC Kanal 0 aus? Sieht mir nicht so aus...

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:45
von Consti9_9
Das untere "Programm" oder wie man es nennen mag zeigt mir ja bis jetzt die Taster an. Jetzt weis ich nicht wie ich die beiden zusammenfügen soll bzw. wie ich es schaffe das in einem Label der Stromwert eines Kanals angezeigt wird. Also konkret weis ich gerade nicht wie und wo ich jetzt die Berechnung der Stromwerte einfüge das es das andere "Programm" nicht stört

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 11:59
von __blackjack__
@Consti9_9: Du schreibst erst einmal das obere ”Programm” so um, das es ein Modul mit einer Funktion ist, die die Stromwerte ermittelt, vielleicht auch besser nur einen, und man per Argument wählen kann welchen. Die Funktion muss den/die Stromwert(e) an den Aufrufer zurückgeben. Diese Funktion kannst Du dann im unteren Programm importieren und regelmässig aufrufen und das Ergebnis in einem Label darstellen. Dazu brauchst Du die `after()`-Methode. Nun könnte man dort natürlich das/die Label auch immer mit durchreichen, aber sauberer wäre eigentlich ein objektorientierter Ansatz.

`numpy` um den Mittelwert von 32 Werten zu berechnen ist vielleicht ein kleines bisschen overkill. Ich würde da ja das `statistics`-Modul aus der Standardbibliothek für verwenden. :-)

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 12:01
von noisefloor
Hallo,

im allerersten Schritt würde ich dir auch dringend dazu raten, die GUI in eine Klasse zu packen, sonst ist es mega-unübersichtlich. In dem Zuge kannst du auch die doppelten Importe rauskicken, weil die tkinter 1x komplett in dem globalen Namensraum importierst (schlecht) und 1x in den Namensraum tk (richtig).

Die Funktionsnamen deiner GUI sind schlecht, weil z.B. "ScheinwerferON" ja lt. Code den Scheinwerfer aus ausschalten kann. Funktionsnamen schreibt man per Konvention klein_mit_unterstrich. Und besser auch komplett in einer Sprache, also z.B. "scheinwerfer_an" und nicht in denglisch.

Wenn du die Messung des Stromwerts in eine Funktion _ohne_ while-Schleife packst, dann stört da gar nichts, weil du die Funktion ja explizit aufrufen musst, damit diese "läuft". Jeder Aufruf gibt dann die drei Werte zurück, die zeigst du dann als Label in Tkinter an.

Wenn dir das mit Funktionen und Rückgabewerten nicht klar ist, solltest du die entsprechende Sektion im Python-Tutorial nochsmal durcharbeiten.

Gruß, noisefloor

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 12:14
von Consti9_9
Danke schonmal, okay also ich versuche jetzt das erste Programm in eine Funktion bzw als Modul zu definieren. Jedoch stellt sich dann mir hier die Frage ob ich in dem unteren Programm dann eine Schleife brauche oder wie ich das löse das die Werte alle 2 Sekunden erneut ausgelesen und berechnet werden?

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 12:32
von __blackjack__
@Consti9_9: In dem GUI-Programm brauchst Du die `after()`-Methode. Schleife geht nicht, denn immer wenn diese Schleife laufen würde, könnte die GUI-Hauptschleife nicht laufen.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 13:17
von Consti9_9
Okay danke nur ich finde nichts wie ich die Methode anwende oder was diese Bezweckt

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 13:19
von Consti9_9
root.after(0, add_letter) # add_letter will run as soon as the mainloop starts.
root.mainloop()

Muss ich hier meine Funktion eintragen die ich erstellt habe um die Stromwerte auslesen zu können. Was dann bedeutet das ich die Variablen verwenden kann und in ein Label schreiben kann?

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 13:23
von __blackjack__
@Consti9_9: Ich würde den `after()`-Aufruf ans Ende der Methode setzen, die das macht und die am Anfang einmal aufrufen, denn Du willst das ja nicht nur einmal und sofort, sondern immer wieder, mit einer gewissen Verzögerung.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 13:25
von Sirius3
Nein, Du mußt eine Funktion angeben, die die Funktion mit den Stromwerten aufruft und diese dann in einem Label darstellt.

Re: Variable & Display

Verfasst: Donnerstag 3. Januar 2019, 13:37
von Consti9_9
Also einfach nur "after()" ans Ende des Programms:

Code: Alles auswählen

from mcp3208 import MCP3208 #import des MCP Moduls
import time #import des Zeitmoduls um Zeitverzögerungen zu erstellen
adc = MCP3208() #Namen um MCP ansprechen zu können und zu verkürzen
global  a #Definition Variable a
import numpy #Import der Bibliothek für Mittelwerte

def Stromwert():
        werte_0 = [] #Liste erstellen
        for i in range(32):
            werte_0.append(adc.read(0)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        a = 3103 - numpy.mean(werte_0) #Berechnen der Differenz
        j = (a/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 1:",j.round(3),"A") #Ausgabe des Stromwerts
        werte_1 = [] #Liste erstellen
        for i in range(32):
            werte_1.append(adc.read(1)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        b = 3103 - numpy.mean(werte_1) #Berechnen der Differenz
        k = (b/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 2:",k.round(3),"A") #Ausgabe des Stromwerts
        werte_2 = [] #Liste erstellen
        for i in range(32):
            werte_2.append(adc.read(2)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        c = 3103 - numpy.mean(werte_2) #Berechnen der Differenz
        l = (c/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 3:",l.round(3),"A") #Ausgabe des Stromwerts
        werte_3 = [] #Liste erstellen
        for i in range(32):
            werte_3.append(adc.read(3)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        d = 3103 - numpy.mean(werte_3) #Berechnen der Differenz
        m = (d/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 4:",l.round(3),"A") #Ausgabe des Stromwerts
        werte_4 = [] #Liste erstellen
        for i in range(32):
            werte_4.append(adc.read(4)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        e = 3103 - numpy.mean(werte_4) #Berechnen der Differenz
        n = (e/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 5:",l.round(3),"A") #Ausgabe des Stromwerts
        werte_5 = [] #Liste erstellen
        for i in range(32):
            werte_5.append(adc.read(5)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        f = 3103 - numpy.mean(werte_5) #Berechnen der Differenz
        o = (f/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 6:",l.round(3),"A") #Ausgabe des Stromwerts
        werte_6 = [] #Liste erstellen
        for i in range(32):
            werte_6.append(adc.read(6)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        g = 3103 - numpy.mean(werte_6) #Berechnen der Differenz
        p = (g/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 7:",l.round(3),"A") #Ausgabe des Stromwerts
        werte_7 = [] #Liste erstellen
        for i in range(32):
            werte_7.append(adc.read(7)) #Auslesen des 0. Kanals
        #print(werte_0) #Ausgabe der Werte in einer Liste aufgrund append
        h = 3103 - numpy.mean(werte_7) #Berechnen der Differenz
        q = (h/185)*1 #Berechnen des vorhandenen Stroms laut Berechnung
        print("Stromwert 8:",l.round(3),"A") #Ausgabe des Stromwerts
        time.sleep(2)
setzen? Und in dem zweiten Programm welches schon die Taster beinhaltet, rufe ich das Programm mit welchem Befehl auf?