Forum: Mikrocontroller und Digitale Elektronik Temperaturkompensation Spannungsdrift mit Software (RPI3, ADS1115DGST, MP3V5050DP)


von Andreas G. (andreasgs)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

Zunächst mal zum Projekt:
Ich wohne neben einem kleinen Bächlein, das je nach Niederschlag Wasser 
führt oder nicht. Diesen Wasserstand (i.d.R 0...5cm, maximal 1m) möchte 
ich über den Staudruck der Wassersäule wie in einer Waschmaschine 
messen.

Ich verwende dazu:
- Ein Hutschienenschaltnetzteil, das 5V erzeugt.
- einen LM1084-H (ohne Kühlkörper) der die 3.0V für den Sensor erzeugt
- Einen MP3V5050DP Differenzdrucksensor bis 50kPa
- Einen ADS1115DGST AD - Wandler
- Und einen RPi3+

Wie man in der Datei Pegel_V1_Messwerte erkennen kann, funktioniert die 
Software soweit, dass ich auch entsprechend die Werte mitloggen kann.

Mein Problem ist jetzt: Der Sensor ist ratiometrik. Heist, ändert sich 
die Versorgungsspannung, ändert sich auch der Sensorwert. Bei gleichem 
Druckwert, ändert sich also die Ausgangsspannung mit der 
Eingangsspanung.

Der AD - Wandler wird wie der Sensor aus der selben 3.0V Line versorgt, 
damit der Aussteuerbereich des Sensor auch dem maximalen Wertebereich 
des AD - Wandlers erfassen kann. Damit ich nun den Fehler aus der 
Spannungsversorgung rausrechnen kann, hab ich einen Spannungsteiler 
eingebaut, der auf etwa 2,0V eingestellt ist. Ändert sich nun der 3.0V 
Spannungswert, ändert sich der Spannungsabfall und den kann ich dann 
wiederrum aus dem Sensorausgang rausrechnen. Die eingebaute 
Spannungsreferenz im AD - Wandler müsste doch temperaturkompensiert 
sein...

Wie man an den Messwerten aber erkennen kann, funktioniert das nicht. 
Der Differenzwert wird zwar gebildet und auch korrekt abgezogen. Bei 
Konstanten Druckwert, ändert sich aber der Pegel mit der 
Versorgungsspannung.

Der Sensorausgabewert liegt aktuell etwa bei 140mV. Die Druckänderung 
durch den Wasserstand inetwa im einstelligen Millivolt Bereich. Die 3.0V 
Spannungline rauscht nun etwa um 1-5mV was das Messergebnis natürlich 
verfälscht.

So nun zur Frage: Kann ich hier Softwareseitig noch was machen? Habt ihr 
eine Idee? Bringt es etwas, den AD - Wandler vor den Festspannungsregler 
einzubauen?

von Klaus R. (klara)


Lesenswert?

Andreas G. schrieb:
> Mein Problem ist jetzt: Der Sensor ist ratiometrik. Heist, ändert sich
> die Versorgungsspannung, ändert sich auch der Sensorwert. Bei gleichem
> Druckwert, ändert sich also die Ausgangsspannung mit der
> Eingangsspanung.

Ja und?

https://www.all-electronics.de/ratiometrische-messungen-und-signalkonditionierung/

Ratiometrisch funktioniert so, dass man Verhälnisse von zwei Meßwerten 
vergleicht. Zum einen Deinen Sensorwert und zum anderen einen Wert über 
einen Spannungsteiler. Deshalb darf die Versorgungsspannung auch 
schwanken. Zuerst mißt man den feststeheden, bekannten Spannungsteiler 
und kann so die anliegende Spannung zum Messen berechnen. Dann mißt man 
den Sensor.

Andreas G. schrieb:
> Die eingebaute
> Spannungsreferenz im AD - Wandler müsste doch temperaturkompensiert
> sein...

Ist im Datenblatt genau beschrieben.
mfg Klaus

von Achim S. (Gast)


Lesenswert?

Andreas G. schrieb:
> Mein Problem ist jetzt: Der Sensor ist ratiometrik. Heist, ändert sich
> die Versorgungsspannung, ändert sich auch der Sensorwert.

Du musst zwei Punkte unterscheiden
1) wie stark ändert sich die Empfindlichkeit des Sensors mit Vss
2) wie stark ändert sich der Offset des Sensors mit Vss

Der Empfindlichkeitsänderung kommst du am einfachsten mit der 
ratiometrischen Messung bei: d.h. die Referenzspannung des ADC und die 
Versorgungsspannung des Sensors müssen identisch sein. Dann hebt sich 
die Empfindlichkeitsänderung heraus.

Die Offsetverschiebung kann etwas komplizierter sein. Falls sich der 
Offset des Sensors ebenfalls ratiometrisch zur Versorgung ändert, dann 
geht die Korrektur tatsächlich über einen Spannungsteiler, zu dem du die 
Differenz bildest.

Aber dann darf der Spannungsteiler natürlich nicht auf 2V eingestellt 
sein sondern auf den Offsetwert des Sensors (also typsich 0,12V). Wenn 
du den Teiler auf 2V einstellst verschiebt er sich natürlich um einen zu 
großen Wert, wenn sich die Versorgung ändert.

Für mich geht aus dem Datenblatt des Sensors nicht ganz eindeutig 
hervor, ob die "GND reference shift circuitry" ebenfalls ratiometrisch 
arbeitet oder nicht. Wenn das der Fall ist, funktioniert die 
Differenzmessung zu deinem Teiler, sobald du das Teilerverhältnis 
richtig einstellst.

Wenn das nicht der Fall ist und der Offset unabhängig von der Versorgung 
ist, dann solltest du keinen Teilerwert subtrahieren sondern einen 
konstanten Wert, den du in einer Kalibriermessung festlegst.

von Klaus R. (klara)


Lesenswert?

Hallo Andreas,
Du solltest eine Fehlerrechnung erstellen, damit Du weisst in welchen 
Bereichen Du Dich bewegst. Der LM1084 hat eine Temperaturstabilität von 
typisch 0,5%. Die Langzeit Temperaturstabilität beläuft sich von typisch 
0,3% bis max. 1%.RMS Noise mit 0,003% kann man vergessen. In Deinem 
Diagramm der 2,0V hast Du eine Schwankung von ca. 20mV. Das sind 1%.

Der Drucksensor misst ratiometrisch. Da im Datenblatt des Sensors keine 
Angaben zur Spannungsabhängigkeit gemacht werden, kannst Du davon 
ausgehen, NXP misst ratiometrisch so, daß keine nennenswerte 
Spannungsabhängigkeit auftritt. Zum Temperaturfehler findest Du unter 
Figure 6 etwas.

mfg klaus

von Andreas G. (andreasgs)


Angehängte Dateien:

Lesenswert?

Hallo,

Danke für die Antworten bisher.

Ambei das Python Script. Ich habe gesehen, dass ich die Spannung des 
Sensors mit GAIN = 1 also mit einem Wertebereich bis etwa 4 Volt 
einlesen kann. Für die Sensorspannung könnte man sich jetzt überlegen, 
auf 2 Volt runterzugehen, hätte dann aber das Problem, dass der Ausgang 
des Sensors mit 3 Volt den Eingang des AD - Kanals überschreiten könnte.

Was auch möglich wäre, eine Bereichsumschaltung, vgl. Anhang. I.d.R. 
wird sich die Ausgangsspannung im breich <,5V befinden. Den Messbereich 
mit GAIN=1 initialisieren und dann den Gain solange hochstellen, bis der 
Ausgabewert sauber in den Spannungsbereich passt. Aber ich vermute, dass 
sich hier der Fehler nur noch stärker auswirkt :-C
1
PYTHON SCRIPT::::
2
#!/usr/bin/python
3
import time
4
5
# Import the ADS1x15 module.
6
import Adafruit_ADS1x15
7
8
#aus der Beispielconfiguration von Pypi
9
import logging
10
import fhem
11
12
# import time module
13
import time
14
15
#logging.basicConfig(logging.DEBUG)
16
logging.basicConfig()
17
18
# Connect via default protocol telnet, default port 7072:
19
fh = fhem.Fhem('pegelrpi.fritz.box', port=7072, use_ssl=False, password='CndoOS39#')
20
fh.connect()
21
22
23
# Note you can change the I2C address from its default (0x48), and/or the I2C
24
# bus by passing in these optional parameters:
25
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, busnum=1)
26
  # Create an ADS1115 ADC (16-bit) instance.
27
adc = Adafruit_ADS1x15.ADS1115()
28
  # Or create an ADS1015 ADC (12-bit) instance.
29
#adc = Adafruit_ADS1x15.ADS1015()
30
31
32
33
# Choose a gain of 1 for reading voltages from 0 to 4.09V.
34
# Or pick a different gain to change the range of voltages that are read:
35
#  - 2/3 = +/-6.144V
36
#  -   1 = +/-4.096V
37
#  -   2 = +/-2.048V
38
#  -   4 = +/-1.024V
39
#  -   8 = +/-0.512V
40
#  -  16 = +/-0.256V
41
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
42
GAIN = 1
43
44
#Hier werden die Variablendefintion
45
SizeMeasBuffer = 20                                    #Defniert die Groesse des Buffers, ueber die gemittelt werden soll                      
46
AN0_RAW_Array = [0]*SizeMeasBuffer                     #Array, das die Anzahl von SizeMeasBuffer an alten gemessenen Werten des AN0 AD - Kanals speichert
47
AN1_RAW_Array = [0]*SizeMeasBuffer                     #Array, das die Anzahl von SizeMeasBuffer an alten gemessenen Werten des AN1 AD - Kanals speichert
48
AN0_RAW_sum = 0                                        #Summe aller in AN0_RAW_Array gespeicherten AD - Messwerte
49
AN1_RAW_sum = 0                                        #Summe aller in AN1_RAW_Array gespeicherten AD - Messwerte
50
AN0_RAW_avg = 0                                        #Quotient aus der Summe von AN0_RAW_Array und SizeMeasBuffer --> Mittelwert des Arrays
51
AN0_CON_avg = 0                                        #AN0_RAW_avg auf Pegel umgerechnet
52
AN1_RAW_avg = 0                                        #Quotient aus der Summe von AN0_RAW_Array und SizeMeasBuffer --> Mittelwert des Arrays
53
AN1_CON_avg = 0                                        #AN1_RAW_avg auf Referenzspannung umgerechnet
54
AN0_RAW_act = 0                                        #Momentanwert des AD - Kanals mit der Geradengleichung umgerechnet
55
AN1_RAW_act = 0                                        #Momentanwert des AD - Kanals mit der Geradengleichung umgerechnet
56
AN0_CON_act = 0                                        #Momentanwert des AD - Kanals mit der Geradengleichung umgerechnet
57
AN1_CON_act = 0                                        #Momentanwert des AD - Kanals mit der Geradengleichung umgerechnet
58
TempDriftRaw = 0                                       #DifferenAD - Wert, wenn der Festspannungsregler weglaeuft zur Kompensation des Spannungsdrifts am Spannungsausgang des Sensors
59
60
Time_Sleep = 1                                         #Zeit in Sekunden, wie lange die While Schleife wartet, um den naechsten Wert zu capturen
61
Time_SleepSlow = 60                                    #Zeit in Sekunden, wie lange die While Schleife im Slow wartet, um den naechsten Wert zu capturen
62
Time_SleepFast = 1                                     #Zeit in Sekunden, wie lange die While Schleife im Fast wartet, um den naechsten Wert zu capturen
63
Time_SleepHysSlFs = 10                                 #Schwellwert in AD - Rohwert, ab dem von slow auf fast umgestellt wird
64
Time_SleepHysFsSl = 3                                  #Schwellwert in AD - Rohwert, ab dem von fast auf slow umgestellt wird
65
Time_SleepCycleLock = 100                              #Wenn eine Umschaltung erfolgt ist, muss eine kann eine erneute umschaltung erst nach "Lock" Zyklen erfolgen
66
Time_SleepCycleLockFor = 0                             #Momentanwert in Sekunden der Zyklenumschaltsperre
67
AN0_RAW_Dif = 0                                        #Unterschied zwischen Mittelwert und aktuellen Messwert von AD - Kanal AN0
68
AN1_RAW_Dif = 0                                        #Unterschied zwischen Mittelwert und aktuellen Messwert von AD - Kanal AN0
69
AN0_RAW_sum = 0                                        #Summe aller in AN0_RAW_Array gespeicherten Werte
70
AN1_RAW_sum = 0                                        #Summe aller in AN1_RAW_Array gespeicherten Werte
71
Voffset_constant = 0.1416                              #Offsetspannung, die der Sensor ohne Eingangsdruck, d.h. ohne Pegel misst
72
LinEq_quotient = 0                                     #Quotient aus Offsetspannung des Sensors und Faktor aus der linearen Gleichung Sensorspannung als Funktion des Wasserpegels. Vsens=0.0046*Pegel+Offestspannung y=ax+b entsp. b
73
LinEq_Fac = 216.35                                     #Faktor, der mit der Sensorspannung multipliziet wird. y=ax+b. Hier also a
74
Vref_fac = 1.47                                        #Faktor fuer die Sensorversorgungsspannung, der aus dem Spannungsteiler von VDD und Masse kommt. 
75
76
#Hier wird der String defniert, der spaeter zum senden an FHEM benutzt wird
77
op = "setreading"                                      #Befehl, der in FHEM Syntax zu beginn steht
78
dev = "Pegel"                                          #FHEM - Device, dass mit dem befehl angesprochen werden soll
79
usrReadPegel = "Wasserstand"                           #FHEM - userReading zum FHEM Device, 
80
                                                       #z.B: attr Pegel userReading Wasserstand { ReadingsVal("Pegel", "Wasserstand", 0);; }
81
usrReadVRev = "VRef_Spannung"                          #FHEM - userReading zum FHEM Device
82
usrReadPegel_avg = "Wasserstand_AVG"                   #FHEM - userReading zum FHEM Device,
83
usrReadVRev_avg = "VRef_Spannung_AVG"                  #FHEM - userReading zum FHEM Device,
84
usrReadAN0_act = "AN0_Spannung_act"                    #FHEM - userReading zum FHEM Device,
85
usrReadAN1_act = "AN1_Spannung_act"                    #FHEM - userReading zum FHEM Device,
86
usrReadAN0_raw = "AN0_Spannung_act_raw"                #FHEM - userReading zum FHEM Device,
87
usrReadAN1_raw = "AN1_Spannung_act_raw"                #FHEM - userReading zum FHEM Device,
88
unit_cm = "cm"                                         #Einheit, die mit dem userReading ueertragen werden koennte
89
unit_volt  = "V"                                       #Einheit, die mit dem userReading ueertragen werden koennte
90
91
 
92
#AN0 misst die Spannung am Sensorausgang des Drucksensors
93
AN0_RAW_act = adc.read_adc(0, gain=GAIN)                   # Setzten der Variable mit dem ersten AN0 Messwert
94
for i in range (SizeMeasBuffer):                       # Durch iterieren des gesamten Arrays und erstbefuellung mit dem AN0 Messwert
95
    AN0_RAW_Array[i]=AN0_RAW_act                            
96
    print(AN0_RAW_Array[i])
97
#AN1 misst die Versorgungsspannung des Sensors, da die Ausgangsspannung immer im Verhaeltnis zur Eingangsspannung steht.
98
AN1_RAW_act = adc.read_adc(1, gain=GAIN)                   # Setzten der Variable mit dem ersten AN0 Messwert
99
for i in range (SizeMeasBuffer):                       # Durch iterieren des gesamten Arrays und erstbefuellung mit dem AN0 Messwert
100
    AN1_RAW_Array[i]=AN1_RAW_act
101
    print(AN1_RAW_Array[i])
102
103
  
104
    
105
106
    
107
#________________________________________________
108
n=0
109
while n<50 :
110
    print ("_____________________________________________________________________________________________")
111
    print ("Start : %s" % time.ctime())
112
113
# Konzept:
114
# Beim Durchlaufen der Whileschleife wird der AD - Wandler einmal eingelesen. Jeder Wert wird in einem Array der Groesse SizeMeasBuffer abgelegt. In jedem Schleifendurchlauf wird n um eins Inkrementiert, bis n SizeMeasBuffer entspricht. Dann wird n Zurueckgesetzt. Zum indizieren der SizeMeasBuffer grossen Arrays wird n verwendet. Wenn n == SizeMeasBuffer ist, wird n wieder nach 0 gesetzt. Die Oben mit den AN - Werten initalisierten Arrays werden in jedem Schleifendurchlauf durchlaufen und jedes element des Arrays aufsummiert. Durch Teilen der Summe ANx_RAW_sum durch SizeMeasBuffer bekommt man nun den Mittelwert der im Array gespeicherten Werte ANx_RAW_avg. Wenn nun der aktuelle Messwert AN0_RAW_Array[n] um einen Bestimmten Schwellwert vom Mittelwert des Arrays abweicht, und zusaetzlich die Zyklusumschaltsperre Time_SleepCycleLockFor = 0 ist, wird in den schnellen Messzyklus umgeschaltet und eine Rueckschaltung in den Langsamen Zyklus fuer Time_SleepCycleLock gesperrt. So kann die Anfallende Datenmenge in FHEM reduziert werden, wenn der Pegel sich nicht aendert. Es kann immer in den schnellen Zyklus umgeschaltet werden, eine Rueckschaltung in den langsamen kann aber erst erfolgen, wenn der Istwert des Analogkanals kleiner Time_SleepHysFsSl ist und die Umschaltsperre Time_SleepCycleLockFor = 0 abgelaufen ist. 
115
116
#Einlesen, der in Konstante fuer die Offsetspannung aus FHEM. Diese kann per 'setreading Pegel Voffset_constant WERT' im FHEM Eingabefenster gesetzt werden. Die Anfrage fh.get_device_Reding liefert fuer ein userReading aus FHEM den Wert und das dazugehoerige Datum im dict - Format "{u'Value': 0.2, u'Time': datetime.datetime(2019, 1 , 9, 21, 1, 45)}". Damit nun auf den Wert zugegriffen werden kann, muss dieser mit u'Value als Schluessel aus dem Dictionary herausgeloesen werden. print(Voffset_constant[u'Value'])   
117
    Voffset_constant = fh.get_device_reading('Pegel', 'Voffset_constant')
118
119
  # Berechnung des Quotienten fuer die linieare Gleichung
120
    LinEq_quotient=Voffset_constant[u'Value']/0.0046
121
122
    if n == SizeMeasBuffer :                             # Schleifenzaehler, der maximal bis SizeMeasBuffer laeuft. Je schleifendurchlauf werden die AD - Kanaele
123
        n=0                                                # eingelesen    
124
    n += 1
125
    #valuesRAW[i] = adc.read_adc(i, gain=GAIN)
126
    #valuesComp[i] = adc.read_adc(i, gain=GAIN)*0.000125# At a convertion Gain of 0 the LSB resulution is 125uV. The ADC Read should therefore multiplied bei 125uV 
127
                                                       # Note you can also pass in an optional data_rate parameter that controls
128
                                                       # the ADC conversion time (in samples/second). Each chip has a different
129
                                                       # set of allowed data rate values, see datasheet Table 9 config register
130
                                                       # DR bit values.
131
                                                       #values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
132
                                                       # Each value will be a 12 or 16 bit signed integer value depending on the
133
                                                       # ADC (ADS1015 = 12-bit, ADS1115 = 16-bit).      
134
# Read the specified ADC channel using the previously set gain value.                                                  
135
      
136
    AN1_RAW_act = adc.read_adc(1, gain=GAIN)             #Einlesen des AN1 AD - Kanals
137
    TempDriftRaw = 16185 - adc.read_adc(1, gain=GAIN)    #Bilden der Temperaturdifferenzkonstante: 16185*125uV = 2,023125V Referenzspannung
138
    AN0_RAW_act = adc.read_adc(0, gain=GAIN) + TempDriftRaw
139
    AN0_RAW_Array[n-1]=AN0_RAW_act                       #Am AN0 ist der Spannungsausgang des Drucksensors angeschlossen
140
    AN1_RAW_Array[n-1]=AN1_RAW_act                       #Am AN1 wird die Versorgungsspannung des Drucksensors gemessen
141
    AN0_RAW_sum = 0                                    #Summe aller in AN0_RAW_Array gespeicherten Werte muessen zurueckgesetzt werden
142
    AN1_RAW_sum = 0                                    #Summe aller in AN1_RAW_Array gespeicherten Werte muessen zurueckgesetzt werden
143
    for i in range (SizeMeasBuffer):                   #Durchlaufen des Arrays und Bilden der summe
144
        AN0_RAW_sum = AN0_RAW_sum + AN0_RAW_Array[i]     #Aufaddieren der Werte an Stelle I auf das Ergebniss des letzten for - Schleifendurchlaufs
145
        AN1_RAW_sum = AN1_RAW_sum + AN1_RAW_Array[i]     #Aufaddieren der Werte an Stelle I auf das Ergebniss des letzten for - Schleifendurchlaufs
146
    AN0_RAW_avg = AN0_RAW_sum/SizeMeasBuffer           #Bilden des Mittelwertes / Quotienten durch Teilen der Summe durch die Puffergroesse
147
    AN1_RAW_avg = AN1_RAW_sum/SizeMeasBuffer           #Bilden des Mittelwertes / Quotienten durch Teilen der Summe durch die Puffergroesse
148
    AN0_RAW_Dif =  AN0_RAW_Array[n-1] - AN0_RAW_avg    #Bilden der Differenz zwischen aktuellen Messwert und des Mittelwertes
149
    AN1_RAW_Dif =  AN1_RAW_Array[n-1] - AN1_RAW_avg    #Bilden der Differenz zwischen aktuellen Messwert und des Mittelwertes
150
151
# Umrechnung der AD - Kanal - Werte auf Pegel und Referenzspannung
152
#AD - Kanal einlesen -> AD Integer -> Multiplikation mit 125uV aus AD - Kanalaufoesung --> AD - Spannung --> Multiplikation mit factor aus Lin. Gleichung -> Sensorspannung --> Subtraktion Quotienten aus der Geradensteigung.
153
    AN0_CON_act = AN0_RAW_act*0.000125*LinEq_Fac-LinEq_quotient  #Sensorspannung                                  
154
    AN1_CON_act = AN1_RAW_act*0.000125*Vref_fac                  #Sensorversorgungsspannung
155
    AN0_CON_avg = AN0_RAW_avg*0.000125*LinEq_Fac-LinEq_quotient                 #Sensorspannung
156
    AN1_CON_avg = AN1_RAW_avg*0.000125*Vref_fac                                 #Sensorversorgungsspannung 
157
    
158
# Defaulttextausgabe
159
    print('')
160
    print('')
161
    print('X' * 45)
162
    print('Reading ADS1x15 values, press Ctrl-C to quit')
163
    print('%s %f' % ('Schleifendurchlauf                        ', n))
164
    print('%s %d' % ('AN0 Summe                                 ', AN0_RAW_sum))
165
    print('%s %d' % ('AN0 Mittelwert                            ', AN0_RAW_avg))
166
    print('%s %d %s' % ('AN0 Messwert umgerechnet                  ', AN0_CON_act, 'cm'))
167
    print('%s %d %s' % ('AN0 Mittelwert umgerechnet                ', AN0_CON_avg, 'cm'))
168
    print('%s %d' % ('AN1 Summe                                 ', AN1_RAW_sum))
169
    print('%s %d' % ('AN1 Mittelwert                            ', AN1_RAW_avg))
170
    print('%s %f %s' % ('AN1 Messwert umgerechnet                  ', AN1_CON_act, 'Volt'))
171
    print('%s %f %s' % ('AN1 Mittelwert umgerechnet                ', AN1_CON_avg, 'Volt'))
172
    print('%s %d' % ('AN0 Differenz                             ', AN0_RAW_Dif))
173
    print('%s %d' % ('AN1 Differenz                             ', AN1_RAW_Dif))  
174
    print('%s %f' % ('Sensoroffsetspannung                      ', Voffset_constant[u'Value']))
175
    print('%s %s' % ('Sensoroffsetspannung gesetzt am           ', str(Voffset_constant[u'Time'])))
176
    print('%s %f' % ('Schleifendurchlaufzeit [Sekunden]         ', Time_Sleep))
177
    print('%s %d' % ('Zyklen bis Umschaltfreigabe               ', Time_SleepCycleLockFor))
178
179
    print('X' * 45)                                                              #Ende der Textausgabe
180
# Send a command to FHEM (this automatically connects() in case of telnet)
181
    cmd = '%s %s %s %f' % (op, dev, usrReadPegel, AN0_CON_act)                   #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
182
    print(cmd)                                                                   #debugging
183
    fh.send_cmd(cmd,0)                                                           #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
184
    cmd1 = '%s %s %s %f' % (op, dev, usrReadVRev, AN1_CON_act)                   #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
185
    print(cmd1)                                                                  #debugging
186
    fh.send_cmd(cmd1,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
187
    cmd2 = '%s %s %s %f' % (op, dev, usrReadPegel_avg, AN0_CON_avg)              #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
188
    print(cmd2)                                                                  #debugging
189
    fh.send_cmd(cmd2,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
190
    cmd3 = '%s %s %s %f' % (op, dev, usrReadVRev_avg, AN1_CON_avg)               #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
191
    print(cmd3)                                                                  #debugging
192
    fh.send_cmd(cmd3,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
193
    cmd4 = '%s %s %s %f' % (op, dev, usrReadAN0_act, AN0_RAW_act*0.000125)       #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
194
    print(cmd4)                                                                  #debugging
195
    fh.send_cmd(cmd4,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
196
    cmd5 = '%s %s %s %f' % (op, dev, usrReadAN1_act, AN1_RAW_act*0.000125)       #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
197
    print(cmd5)                                                                  #debugging
198
    fh.send_cmd(cmd5,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
199
    cmd6 = '%s %s %s %f' % (op, dev, usrReadAN0_raw, AN0_RAW_act)                #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
200
    print(cmd6)                                                                  #debugging
201
    fh.send_cmd(cmd6,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
202
    cmd7 = '%s %s %s %f' % (op, dev, usrReadAN1_raw, AN1_RAW_act)                #Zusammenbau des ersten FHEM - Kommandos aus Befehl, Geraet, Reading, Wert, Einheit
203
    print(cmd7)                                                                  #debugging
204
    fh.send_cmd(cmd7,0)                                                          #Senden des Kommandos an FHEM durch nutzung des FHEM - Objekts
205
  #fh.send_cmd("setreading Pegel Wasserpegel 300cm")                           #debugging
206
    print('X' * 45)                                                              #Ende der Textausgabe
207
208
# Dekrementiert die Zyklussperre, falls eine Umschaltung erfolgt ist
209
    if Time_SleepCycleLockFor > 0:
210
        print('Dekrementiert die Zyklussperre, falls eine Umschaltung erfolgt ist')                                    #debugging
211
        Time_SleepCycleLockFor -= 1    
212
# Umschaltung in den schnellen Zyklus (immer moeglich, ohne Zyklussperrung). Schnelle, aufeinanderfolgende Signalaenderungen initialisieren die Zyklussperre immer wieder von neuem)
213
214
    if AN0_RAW_Dif > Time_SleepHysSlFs or AN0_RAW_Dif *(-1) > Time_SleepHysSlFs:         #Wenn der Abstand des aktuellen Analogmesswertes gross genug ist wird umgeschaltet
215
        print('AN0_RAW_Dif > Time_SleepHysSlFs or AN0_RAW_Dif *(-1) > Time_SleepHysSlFs')                                    #debugging
216
        Time_SleepCycleLockFor = Time_SleepCycleLock     #Setzten der Zyklusumschaltsperre auf Time_SleepCycleLock
217
        Time_Sleep = Time_SleepFast                      #Setzten der Zykluswartezeit auf das kurze Zeitintervall
218
    if AN1_RAW_Dif > Time_SleepHysSlFs or AN1_RAW_Dif *(-1) > Time_SleepHysSlFs:         #Wenn der Abstand des aktuellen Analogmesswertes gross genug ist wird umgeschaltet
219
        print('AN1_RAW_Dif > Time_SleepHysSlFs or AN1_RAW_Dif *(-1) > Time_SleepHysSlFs')                                    #debugging
220
        Time_SleepCycleLockFor = Time_SleepCycleLock     #Setzten der Zyklusumschaltsperre auf Time_SleepCycleLock
221
        Time_Sleep = Time_SleepFast                      #Setzten der Zykluswartezeit auf das kurze Zeitintervall  
222
  # Umschaltung in den langsamen Zyklus (Nur moeglich, wenn die Zyklussperre abgelaufen ist)
223
# Kurze Impulse fuehren deshalb zu einer sofortigen Abtatstungsumschaltung, wenn dann die Signale und Mittelwerte sich stabilisieren, beispiel bei einem
224
# Sprung, wird erst nach Time_SleepCycleLock der langsame Zyklus wieder aktiviert
225
    if Time_SleepCycleLockFor == 0 and  (AN0_RAW_Dif < Time_SleepHysFsSl or AN0_RAW_Dif *(-1) < Time_SleepHysFsSl):
226
        print('Time_SleepCycleLockFor == 0 and  (AN0_RAW_Dif < Time_SleepHysFsSl or AN0_RAW_Dif *(-1) < Time_SleepHysFsSl)')                                    #debugging
227
        Time_SleepCycleLockFor = Time_SleepCycleLock     #Setzten der Zyklusumschaltsperre auf Time_SleepCycleLock
228
        Time_Sleep = Time_SleepSlow                      #Setzten der Zykluswartezeit auf das lange Zeitintervall
229
    if Time_SleepCycleLockFor == 0 and  (AN1_RAW_Dif < Time_SleepHysFsSl or AN1_RAW_Dif *(-1) < Time_SleepHysFsSl):
230
        print('Time_SleepCycleLockFor == 0 and  (AN1_RAW_Dif < Time_SleepHysFsSl or AN1_RAW_Dif *(-1) < Time_SleepHysFsSl)')                                    #debugging
231
        Time_SleepCycleLockFor = Time_SleepCycleLock     #Setzten der Zyklusumschaltsperre auf Time_SleepCycleLock
232
        Time_Sleep = Time_SleepSlow                      #Setzten der Zykluswartezeit auf das lange Zeitintervall
233
    print(Time_Sleep)                                  #Ausgeben der Sleeptime
234
    time.sleep(2)                             #aktivieren der Wartezeit

Achim S. schrieb:
> Aber dann darf der Spannungsteiler natürlich nicht auf 2V eingestellt
> sein sondern auf den Offsetwert des Sensors (also typsich 0,12V). Wenn
> du den Teiler auf 2V einstellst verschiebt er sich natürlich um einen zu
> großen Wert, wenn sich die Versorgung ändert.

Du meinst am Ausgang des Sensors zusätzlich einen Spannungsteiler, der 
so Dimensioniert ist, dass genau der Offset des Sensors am Widerstand 
abfällt?

FYI:
Der Noise am Ausgang ist prinzipbedingt auch nicht unerheblich. Daher 
filtere ich den Sensorwert in Software zusätzlich mit einem moving 
Average mit 20 Werten.

https://www.nxp.com/files-static/sensors/doc/app_note/AN1646.pdf

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.