Forum: Mikrocontroller und Digitale Elektronik Anfänger: Matrix mit Werten benutzen - Feuchtesensor


von Paul (Gast)


Lesenswert?

Hallo Forengemeinde,

ich stümper gerade eine Zweipunktregelung als Hygrostat zusammen. Dafür 
benutze ich folgenden Feuchtesensor, der Spannungswerte ausgibt, die ich 
mit dem ADC eines Mega48 einlese:

http://www.produktinfo.conrad.com/datenblaetter/1100000-1199999/001170518-da-01-en-FEUCHTIGKEITS_SENSOR_HMZ_333A1.pdf

Zusätzlich hängt noch ein DS18S20 Temperatursensor und ein LCD-Display 
mit dran.

Auf S.3 in dem Pdf ist eine Tabelle mit den Spannungswerten und den bei 
den entsprechenden Temperaturen erhaltenen relativen Luftfeuchtigkeiten.

Aber wie wertet man so eine Tabelle ordentlich aus? Da ich eher Anfänger 
bin würde ich jetzt ganz furchtbare "if" Konstruktionen bauen (oder eine 
switch-case):

if Temperatur >= 10°C && <15°C
  if Spannung >= 0.76 && <0.73
     print "20%RH"
...

Das ist natürlich zum einen mit einem bösen Fehler behaftet und zum 
anderen ist das so ungenau, dass ich gleich auf das Messen verzichten 
kann.

Bitte helft mir mit einem für einen Anfänger geeigneten Rat wie ich das 
ordentlicher machen.

Danke!

Paul

von foo (Gast)


Lesenswert?

Paul schrieb:
> Bitte helft mir mit einem für einen Anfänger geeigneten Rat wie ich das
> ordentlicher machen.

Auf S.2 gibts doch eine Kurve, welche Luftfeuchte zu welcher Spannung 
führt, bei einer gegebenen Temperatur. Die Punkte wie sie in der Tabelle 
sind, sind eingezeichnet (wenn auch nur schwach sichtbar) und dann durch 
gerade Linien verbunden.

Liegt nun die Spannung zwischen zwei Punkten, liegt die Luftfeuchte auch 
im selben Maße zwischen 20 und 30 bzw. 30 und 40 usw. Du musst also 
interpolieren.

Da die Kurve von der Temperatur abhängt, nimmst du für eine gegebene 
Temperatur die Spannungswerte aus der entsprechenden Spalte.

Liegt die Spannung z.B. zwischen 0.76 und 1.06 V, dann weißt du, dass RH 
zwischen 20 und 30% liegt...

0.76 a + b = 20
1.06 a + b = 30
-> 0.3 a = 10 => a = 33.3333...
-> b = -5.3333....

nun kannst du den gemessenen Spannungswert U in U*33.33333 - 5.3333 
einsetzen und erhältst einen Wert zwischen 20 und 30.

Wenn ich das in Code umwandeln würde, würde ich die Zahlen a und b für 
jedes Intervall $RH0...$RH0+10 bei $Temperatur vorher berechnen und in 
eine Tabelle legen, die ins Flash packen, und die dann nur noch abrufen 
und daraus RH berechnen. Spart Rechenzeit aufm AVR.

Kommst du damit schon weiter?

von Paul (Gast)


Lesenswert?

Danke, das war richtig hilfreich!

Interpolieren war das wonach ich gesucht habe.
Ich erstelle gerade eine Tabelle mit den interpolierten Werten in Excel. 
Diese Werte würde ich dann versuchen in einer Tabelle in C zu speichern 
und darauf zuzugreifen. Mal sehen wie weit ich heute komme und wann es 
wieder klemmt.

von R. Rebentrost (Gast)


Lesenswert?

Paul schrieb:
> Ich erstelle gerade eine Tabelle mit den interpolierten Werten in Excel.
> Diese Werte würde ich dann versuchen in einer Tabelle in C zu speichern
> und darauf zuzugreifen.

Vielleicht hast du es nur etwas unglücklich ausgedrückt, aber du 
solltest eigentlich die Stützpunkte bzw. Intervalle speichern und dann 
auf dem Mikrocontroller interpolieren, nicht die interpolierten Werte 
selbst irgendwo ablegen.

von foo (Gast)


Lesenswert?

R. Rebentrost schrieb:
> Paul schrieb:
>> Ich erstelle gerade eine Tabelle mit den interpolierten Werten in Excel.
>> Diese Werte würde ich dann versuchen in einer Tabelle in C zu speichern
>> und darauf zuzugreifen.
>
> Vielleicht hast du es nur etwas unglücklich ausgedrückt, aber du
> solltest eigentlich die Stützpunkte bzw. Intervalle speichern und dann
> auf dem Mikrocontroller interpolieren, nicht die interpolierten Werte
> selbst irgendwo ablegen.

von foo (Gast)


Lesenswert?

R. Rebentrost schrieb:
> Paul schrieb:
>> Ich erstelle gerade eine Tabelle mit den interpolierten Werten in Excel.
>> Diese Werte würde ich dann versuchen in einer Tabelle in C zu speichern
>> und darauf zuzugreifen.
>
> Vielleicht hast du es nur etwas unglücklich ausgedrückt, aber du
> solltest eigentlich die Stützpunkte bzw. Intervalle speichern und dann
> auf dem Mikrocontroller interpolieren, nicht die interpolierten Werte
> selbst irgendwo ablegen.

(Oben versagt.)

Ich glaube auch dass er die Werte meint, mit denen er interpoliert.

Die interpolierten Werte sind ja die, die auf dem Messwert vom ADC 
beruhen, und den kennt Excel auf dem Hostsystem natürlich nicht :-)

Wobei da natürlich auch nichts gegen spricht, in Excel mal zu testen, ob 
die Formel, die man dann in C gießt, so stimmt.

von R. Rebentrost (Gast)


Lesenswert?

War das jetzt Zustimmung, Widerspruch oder ein Unglück?

von R. Rebentrost (Gast)


Lesenswert?

Ok, Antwort war beim Absenden wohl schon da.

von Paul (Gast)


Lesenswert?

Hmpf...
Zum Glück habe ich nochmal einen Blick ins Forum geworfen bevor ich seit 
3 Stunden an der Tabelle sitze :-O

Ich habe jetzt alle a's und b's bzw. alle Geradengleichungen bestimmt.

Das sind nun für jede Temperatur 7 Geradengleichungen. Macht bei 7 
Temperaturen 49 Geradengleichungen und entsprechend genau so viele a's 
und b's.

Allerdings bekomme ich gerade wieder einen kleinen Hirnknoten wenn ich 
das versuche nun in Code umzusetzen, zumal ich auch gern die 
Zwischentemperaturen mit auswerten möchte. Dafür habe ich also auch 
wieder die Möglichkeit des Interpolierens genutzt.

Ein Bsp: Temp ist 10°C, ADC_Val ist zwischen 0.76 und 1.06
Da kommt erst mal das von foo raus: m=33.3333, n=-5.3333
Die Gleichung für die Feuchte ist dann RH=33.3333*ADC_Val-5.3333

ob der ADC_Val zwischen 0.76 und 1.06 liegt würde ich mit "if" prüfen.

Aber was wenn ich nun RH bei 11°C wissen möchte? Dort gilt doch nicht 
mehr die selbe Geradengleichung?!

Tut mir leid das es bei mir so hängt, aber bis zu den komplexen 
Denkvorgängen eines geübten Programmierers brauch ich einfach noch ein 
gutes Stück mehr Übung.

von Klaus (Gast)


Lesenswert?

Paul schrieb:
> Hmpf...

> Aber was wenn ich nun RH bei 11°C wissen möchte? Dort gilt doch nicht
> mehr die selbe Geradengleichung?!

Naja. Es gibt nicht nur die Regression bei einer abhängigen sondern auch 
die für mehrere. Nennt sich multivariate Regression. Leider kann Excel 
die, glaube ich, nicht. Ich habe eben mal geschaut, aber eine "einfache" 
Darstellung davon finde ich auf die Schnelle nicht. Vielleicht suchst Du 
selbst einmal. Falls Du dazu Fragen hast, kannst Du hier ja nochmal 
posten.

von Klaus (Gast)


Lesenswert?

Ich denke das naheliegendste, was man noch aus dem Schulbetrieb kennen 
könnte, wäre das Lösen eines linearen Gleichungssystems mittels Gauss - 
allg. lineare Algebra. Das lässt sich dann auch auf nicht-lineare 
Gleichungen erweitern. Aber etwas Hirnschmalz muss man dann doch schon 
reinlegen.

von foo (Gast)


Lesenswert?

Paul schrieb:
> Aber was wenn ich nun RH bei 11°C wissen möchte? Dort gilt doch nicht
> mehr die selbe Geradengleichung?!

Theoretisch liegst du da richtig.

Aber guck doch mal, wie wenig die Spannungen für eine gegebene RH 
zwischen den Temperaturen abweichen. Und dann guck mal unter die Tabelle 
wie genau der Sensor ist: +- 5%. Drunter steht auch für einen bestimmten 
Wertebereich um wie viel die Spannung dabei abweichen kann, in dem Fall 
+- 0.15V.

Die maximal +- 0.02V die von der "falschen" Geradengleichung kommen 
machen da wohl auch keinen großen Unterschied mehr...

Mir wär es jedenfalls zu kompliziert auch in die andere Richtung zu 
interpolieren (also zwischen den Referenzspannungswerten für die zwei 
Temperaturen, zwischen denen deine richtige Temperatur liegt), der 
Gewinn dürfte minimal sein. Ich würde einfach bis 12,5 Grad die erste 
Spalte nehmen, bis 17,5 Grad die zweite usw.

von Karl H. (kbuchegg)


Lesenswert?

Paul schrieb:

> Allerdings bekomme ich gerade wieder einen kleinen Hirnknoten wenn ich
> das versuche nun in Code umzusetzen, zumal ich auch gern die
> Zwischentemperaturen mit auswerten möchte.

Dann machst du meiner Meinung nach den Fehler, zu viel auf einmal zu 
wollen.

> Dafür habe ich also auch
> wieder die Möglichkeit des Interpolierens genutzt.
>
> Ein Bsp: Temp ist 10°C, ADC_Val ist zwischen 0.76 und 1.06
> Da kommt erst mal das von foo raus: m=33.3333, n=-5.3333
> Die Gleichung für die Feuchte ist dann RH=33.3333*ADC_Val-5.3333
>
> ob der ADC_Val zwischen 0.76 und 1.06 liegt würde ich mit "if" prüfen.

Ja. Aber die Grenzen legst du sinnigerweise ebenfalls in die Tabelle 
rein. D.h. du wirst da nicht eine lange Latte von if's haben, sondern 
eine Schleife, in der du nacheinander alle Tabellenzeilen durchgehst und 
nachsiehst, ob der aktuelle Wert vom ADC in den Grenzen genau dieser 
Tabellenzeile liegt. Wenn ja, dann hast du die richtige Zeile gefunden. 
Wenn nein, dann eben (in der Schleife) die nächste Zeile.

Du möchtest ALLE Zahlenwerte in der Tabelle haben! Organisier dir 
deine Tabelle als Tabellenzeile mit einem bestimmten Aufbau und denk 
weniger darüber nach, dass du da eine 2 dimensionalen Matrix mit 
Zahlenwerten an den Schnittpunkten hast.
Was, genau, benötigst du in jeder einzelnen Zeile an Werten, so dass 
dort alles an Information gesammelt ist. Genau hier ist normalerweise 
der Punkt erreicht, an dem die Stunde einer Struktur ('struct' in C) 
schlägt.

> Aber was wenn ich nun RH bei 11°C wissen möchte? Dort gilt doch nicht
> mehr die selbe Geradengleichung?!

Wie schon angesprochen: Man kann sich natürlich aus den Koeffizienten 
bei 10° und bei 15° auch die entsprechenden Koeffizienten bei 11° durch 
Interpolation der Koeffizienten ermitteln. Aber du solltest dir wirklich 
ansehen, inwiefern das das Ergebnis tatsächlich verbessert.
Auf der anderen Seite: Wenn du das Programm sauber aufbaust und in 
Einzelteile zerlegst, dann ist auch die Interpolation von Koeffizienten 
kein Problem (Hinweis: man muss die Interpolationskoeffizienten nicht 
vorausberechnen. Die Abfrage eines Feuchtesensors ist sehr 
wahrscheinlich jetzt nicht so zeitkritisch, dass es dich gross juckt, 
wenn der µC 2 Millisekunden mehr braucht).

> Tut mir leid das es bei mir so hängt, aber bis zu den komplexen
> Denkvorgängen eines geübten Programmierers brauch ich einfach noch ein
> gutes Stück mehr Übung.

Der Schlüssel besteht darin, komplexe Dinge in einen Haufen einfachere 
Dinge zu zerlegen und sich dann jeden einfacheren Teil für sich alleine 
vorzunehmen. Kein geübter Programmierer löst komplexe Probleme in einem 
Zug, sondern immer schrittweise. Der Trick besteht darin, sich selbst 
aus Funktionen einen "Baukasten" zu machen, der einzelne Teile kapselt.

Und ein weiterer Trick besteht darin, genau die Aufgabenstellung erst 
mal selbst mit Papier und Bleistift zu lösen. Dabei kommt es darauf an, 
sich selbst auf die Finger zu sehen und zu registrieren, was man da 
eigentlich macht. Wie alle können intuitiv viel mehr, als uns bewusst 
ist und wir alle lösen viele Problemstellungen mit Hilfe dieser 
Intuition. Was einem Programmierer bewusst ist, das ist, das er erst mal 
rauskriegen muss, wie er eigentlich dieses Problem löst und welche 
Schritte er (mglw. aufgrund welcher Vorbedingungen) dazu macht. Wenn das 
erst mal klar ist, dann kann man sich auch hinsetzen und ein Programm 
dafür schreiben. Aber gleichzeitig rauskriegen was man tut UND 
gleichzeitig das Programm dazu schreiben, das geht oft schief und man 
verläuft sich sinnlos in Details, die einem nicht zum Ziel führen. Erst 
mal muss die (mehr oder weniger) grobe Richtung stehen. Und genau dazu 
ist es hilfreich, einfach mal mit angenommenen Werten selbst auf Papier 
die Rechnung durchzuexerzieren.

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

Paul schrieb:
> Aber was wenn ich nun RH bei 11°C wissen möchte?

bilinear Interpolation
1
                       Temp
2
         10   15   20   25   30   35   40
3
     0.5 +----+----+----+----+----+----+
4
         |    |    |    |    |    |    |
5
         |    |    |    |    |    |    |
6
     1.0 +----+----+----+----+----+----+
7
         |    |    |    |    |    |    |
8
         |    |    |    |    |    |    |
9
     1.5 +----+----+----+----+----+----+
10
ADC-val  |    |    |    |    |    |    |
11
         |    |    |    |    |    |    |
12
     2.0 +----+----+----+----+----+----+
13
         |    |    |    |    |    |    |
14
         |    |    |    |    |    |    |
15
     2.5 +----+----+----+----+----+----+
16
         |    |    |    |    |    |    |
17
         |    |    |    |    |    |    |
18
     3.0 +----+----+----+----+----+----+  <- die Werte an + sind die RH
Du siehst die ---- Geradenstücken von + zu + ?
Deine relativer Feuchtewert liegt in einem der Quadrate.
An den Ecken der Quadrate sind die RH-Werte für Temp&ADC-Val
i der Tabelle gespeichert.
Um den RH-Wert an Punkt o auszurechnen, bestimmst du erst die
RH-Werte an den Punkten x und y in den querlaufenden Geraden,
die von Höhe A nach Höhe B laufen und von Höhe C nach Höhe D.
Dann hast du die Anfangs- und Endpunkte der hochlaufenden
Gerade von x nach y auf der o liegt.
1
         A---------x----B
2
         |         |    |
3
         |         o    |
4
         |         |    |
5
         |         |    |
6
         |         |    |
7
         |         |    |
8
         C---------y----D
Du siehst also, du musst die Tabelle umrechnen auf ein anderes
Gitternetz.
Du speicherst nicht die 4 Geradenwerte, sondern bloss die RH
Werte an den Eckpunkten. Die Geradengleichung rechnest du aus.

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.