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?
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.