Durchschnitt Berechnung mit Schleife

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
Baunty
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 20:59

Hallo zusammen ich habe ein Skript was von einem digital wandler den value in bar umrechnet und den dann anzeigt. Leider ist der Druck aufgrund günstiger Bauteile sehr ungenau bzw schwankend somit würde ich gerne so Ca 10 Messungen machen und den Durchschnitt ausgeben. Leider hat meine suche keine Lösung gebracht kann mir jemand weiterhelfen?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Baunty: Da brauchst Du nicht groß zu suchen. Du misst einfach n mal und teilst die Summer der Ergebnisse durch n. Wenn es auf Präzision ankommt, ist es aber angeraten nicht am Messgerät zu sparen.
Baunty
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 20:59

Ja das würde ich gerne mit irgendwie Schleife lösen um Dan einfach die mänge der Messungen anpassen zu können
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Was fehlt dir denn noch, um es mit einer Schleife lösen zu können?
Die Auswahl an Schleifen ist ja nicht so groß, es gibt for- und while-Schleifen.
Baunty
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 20:59

Ich habe es jetzt so gelöst. ich glaube zwar das ich noch auf die PSI umrechnung verzichten könnte aber anscheinen läuft das wohl so. Für feinschliff gerne komentieren oder wenn ich fehler drin habe.

Code: Alles auswählen

#!/usr/bin/python
import fhem
import time

# Connect via default protocol telnet, default port 7072:
fh = fhem.Fhem("myserver.home.org")


import Adafruit_ADS1x15
#variable fuer digital wandler mit anschrift
adc = Adafruit_ADS1x15.ADS1115(address=0x48, busnum=1) 

# Gain = 2/3 for reading voltages from 0 to 6.144V.
# See table 3 in ADS1115 datasheet
GAIN = 2/3

f1=open('/opt/fhem/log/PumpeDruck-2017.log', 'a') #oeffnen der log
jetzt=time.strftime("%Y-%m-%d_%H:%M:%S") # setzen von datum und zeit 

z = 0 #anfang fuer Schleife 
anzahl = 15 # Variable zur anzahl Messungen
bar_d = 0 #variable fuer bardurschnitt

# MessSchleife
while z < anzahl:
	value = [0]
	# Read ADC channel 0
	value[0] = adc.read_adc(0, gain=GAIN)
	# Ratio of 15 bit value to max volts determines volts
	volts = value[0] / 32767.0 * 6.144
	# Tests shows linear relationship between psi & voltage:
	psi = 13.333 * (volts -0.5)
	# Bar umrechnung
	bar = psi * 0.0689475729
	# zaehler hochzaehlen
	z = z + 1 
	#bar_d mit bar aufrechnen 
	bar_d = bar_d + bar
	#ausgabe zur ueberpruefung
	print (bar) 
	print (bar_d)
	# ende MessSchleife
	
#durschnitt berechnung
bar_d = bar_d / anzahl
#ausgabe zur ueberpruefung
print ("durchschnitt: ") +str(bar_d) 

#rundung des Durschnitt variable x (bar_d)
bar_d = round (bar_d,2)
#ausgabe zur ueberpruefung
print ("durchschnitt gerundet: ") +str(bar_d) 

# uebrgabe an fhem wen bar_d groesser 0.3		
if bar_d > 0.3:
	# uebrgabe an logdatei
	f1.write("\n"+str(jetzt)+" PumpeDruck: "+str(bar_d)+" Bar")
	# uebrgabe an fhem
	fh.send_cmd("set PumpeDruck  "+str(bar_d)) 

#ENDE
Zuletzt geändert von Anonymous am Freitag 14. Juli 2017, 08:53, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Deine while-Schleife würde man eher so schreiben:

Code: Alles auswählen

anzahl = 15
for z in range(anzahl):
    ...
Dann musst du den Zähler auch nicht hochzählen
For-Schleifen nimmt man immer, wenn bekannt ist wie oft die Schleife durchlaufen werden soll.
Baunty
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 20:59

Danke habe ich geänder auf:

Code: Alles auswählen

#!/usr/bin/python
import fhem
import time

# Connect via default protocol telnet, default port 7072:
fh = fhem.Fhem("myserver.home.org")


import Adafruit_ADS1x15
#variable fuer digital wandler mit anschrift
adc = Adafruit_ADS1x15.ADS1115(address=0x48, busnum=1) 

# Gain = 2/3 for reading voltages from 0 to 6.144V.
# See table 3 in ADS1115 datasheet
GAIN = 2/3

f1=open('/opt/fhem/log/PumpeDruck-2017.log', 'a') #oeffnen der log
jetzt=time.strftime("%Y-%m-%d_%H:%M:%S") # setzen von datum und zeit 

anzahl = 50 # Variable zur anzahl Messungen
bar_d = 0 #variable fuer bardurschnitt

# MessSchleife
for z in range(anzahl):
	value = [0]
	# Read ADC channel 0
	value[0] = adc.read_adc(0, gain=GAIN)
	# Ratio of 15 bit value to max volts determines volts
	volts = value[0] / 32768.0 * 6.144
	# Tests shows linear relationship between psi & voltage:
	psi = 13.33 * (volts -0.5)
	# Bar umrechnung
	bar = psi * 0.0689475729 
	#bar_d mit bar aufrechnen 
	bar_d = bar_d + bar
	#ausgabe zur ueberpruefung
	#print (bar) 
	#print (bar_d)
	# ende MessSchleife
	
#durschnitt berechnung
bar_d = bar_d / anzahl
#ausgabe zur ueberpruefung
#print ("durchschnitt: ") +str(bar_d) 

#rundung des Durschnitt variable (bar_d)
bar_d = round (bar_d,2)
#ausgabe zur ueberpruefung
#print ("durchschnitt gerundet: ") +str(bar_d) 

# uebrgabe an fhem wen bar_d groesser 0.3		
if bar_d > 0.3:
	# uebrgabe an logdatei
	f1.write("\n"+str(jetzt)+" PumpeDruck: "+str(bar_d)+" Bar")
	# uebrgabe an fhem
	fh.send_cmd("set PumpeDruck  "+str(bar_d)) 

#ENDE
:P
Zuletzt geändert von Anonymous am Freitag 14. Juli 2017, 08:56, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Baunty: Importe sollten alle am Anfang der Datei stehen, damit man schnell die Abhängigkeiten erkennen kann. Die Shebang-Zeile läßt vermuten, dass Du Python2 benutzt; dann ist GAIN = 2/3 = 0 eine Ganzzahldivision. Das läßt sich beheben durch eine "from __future__ import division".
Zeile 26 ist auch seltsam: warum erzeugst Du eine Liste mit dem Wert 0, nur um in der nächsten Zeile diesen Wert sofort wieder zu überscheiben? Die Liste mit einem Element wird auch nie als Liste gebraucht. Das könnte eine ganz normale Variable sein.
Die Kommentare sind auch zum Großteil überflüssig. Hieße anzahl anzahl_messungen bräuchte man keinen Kommentar, was für eine Anzahl das ist, ebenso bar_d -> durchschnitt_pumpendruck. Kommentare wie "bar_d mit bar aufrechnen" sagen nicht mehr als bar_d = bar_d + bar, solche Kommentare können weg. Man rundet keine Zahlen für die Ausgabe, sondern gibt die Zahlen mit einer festen Anzahl Nachkommastellen aus:

Code: Alles auswählen

print "Durchschnitt: {}".format(bar_d) 
print "Durchschnitt gerundet: {:.2d}".format(bar_d) 
Baunty
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 20:59

Das ich zimlich viele kommentare eigentlich weglassen könnte war mir bewust. Ich kenn anscheinend nur zu viel oder zu wenig :wink: .
wenn ich das so umschreibe kommt ein fehler. Python 2 nutze ich das ist richtig.

Code: Alles auswählen

#!/usr/bin/python
from __future__ import division
import fhem
import time

# Connect via default protocol telnet, default port 7072:
fh = fhem.Fhem("myserver.home.org")


import Adafruit_ADS1x15
#variable fuer digital wandler mit anschrift
adc = Adafruit_ADS1x15.ADS1115(address=0x48, busnum=1) 

# Gain = 2/3 for reading voltages from 0 to 6.144V.
# See table 3 in ADS1115 datasheet
GAIN = 2/3

f1=open('/opt/fhem/log/PumpeDruck-2017.log', 'a') #oeffnen der log
jetzt=time.strftime("%Y-%m-%d_%H:%M:%S") # setzen von datum und zeit 

anzahl = 50 # Variable zur anzahl Messungen

# MessSchleife
for z in range(anzahl):
	value = [0]
	# Read ADC channel 0
	value[0] = adc.read_adc(0, gain=GAIN)
	# Ratio of 15 bit value to max volts determines volts
	volts = value[0] / 32768.0 * 6.144
	# Tests shows linear relationship between psi & voltage:
	psi = 13.33 * (volts -0.5)
	# Bar umrechnung
	bar = psi * 0.0689475729 
	#bar_d mit bar aufrechnen 
	bar_d = bar_d + bar
	#ausgabe zur ueberpruefung
	#print (bar) 
	#print (bar_d)
	# ende MessSchleife
	
#durschnitt berechnung
bar_d = bar_d / anzahl
#ausgabe zur ueberpruefung
#print ("durchschnitt: ") +str(bar_d) 

#ausgabe zur ueberpruefung
#print "Durchschnitt gerundet: {:.2d}".format(bar_d)
#rundung des Durschnitt variable (bar_d)
bar_d = round (bar_d,2)
 

# uebrgabe an fhem wen bar_d groesser 0.3		
if bar_d > 0.2:
	# uebrgabe an logdatei
	f1.write("\n"+str(jetzt)+" PumpeDruck: "+str(bar_d)+" Bar")
	# uebrgabe an fhem
	fh.send_cmd("set PumpeDruck  "+str(bar_d)) 

#ENDE
Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "druck.py", line 27, in <module>
    value[0] = adc.read_adc(0, gain=GAIN)
  File "build/bdist.linux-armv6l/egg/Adafruit_ADS1x15/ADS1x15.py", line 192, in read_adc
  File "build/bdist.linux-armv6l/egg/Adafruit_ADS1x15/ADS1x15.py", line 114, in _read
ValueError: Gain must be one of: 2/3, 1, 2, 4, 8, 16
:K :K
Zuletzt geändert von Anonymous am Freitag 14. Juli 2017, 08:59, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Baunty: Also muss GAIN nicht 2/3 sein sondern 0. Oder 2//3. Was 0 ist. Dafür sollte man den Autor von dem `Adafruit_ADS1x15`-Modul mit Wattebällchen bewerfen. Mindestens.
BlackJack

@Baunty: Du hast das Zeilenendezeichen falsch → das gehört ans *Ende* der Zeile, nicht an den Anfang. Zumindest unter Unixoiden Sytemen gehen die allermeisten Programme die Textdateien verarbeiten davon aus, das jede Zeile mit einem '\n' abgeschlossen ist. Auch die letzte Zeile in einer Datei.

Dateien die man öffnet sollte man auch wieder schliessen. Die ``with``-Anweisung ist da sehr hilfreich. Ausserdem öffnest Du die Datei viel zu früh. Nicht nur vor der Messung, sondern auch bevor überhaupt feststeht ob etwas in die Datei geschrieben wird. Wenn nichts geschrieben wird braucht man sie auch nicht öffnen.
Antworten