Forum: Mikrocontroller und Digitale Elektronik SHT11 mit code aus Codesammlung zeigt zu wenig


von Thorsten S. (whitejack)


Lesenswert?

Hi,

ich habe hier schon einige Threads durchgearbeitet, aber wenn der Sensor 
schon stabil läuft, dann gibts hier nur Leute die zu viel auf dem 
Display haben, ich habe zu wenig, aber auch nur unter bestimmten 
Voraussetzungen:

Beitrag "Sensirion SHT11 Code"

Die Lib bietet die Möglichkeiten die Bitzahlen umzuschalten, wenn ich 
sie so nehme wie sie ist, habe ich 7 Grad zu wenig, wenn ich in config.h 
SHT11_LOWRES auf 0 setzte, scheint es zu passen...warum?

Gruß,
Thorsten

von Rainer M. (excogitator)


Lesenswert?

Hallo Thorsten,

hast du im Statusregister des SHT11 das Bit0 auf "1" gesetzt. Wenn nein, 
wundert es mich nicht das dein Ergebnis nicht stimmt, denn der SHT11 ist 
nach dem Start auf high Resolution (12Bit/14Bit) eingestellt.

Gruß
Rainer

von Thorsten (Gast)


Lesenswert?

Hallo Rainer,

im Init wird dies ausgeführt:

    start();
    send(SHT11_CMD_RESET);
    _delay_ms(11);

    start();
    send(SHT11_CMD_WSTAT);
    send(SHT11_LOWRES);

SHT11_CMD_RESET  0x1E
SHT11_CMD_WSTAT  0x06
SHT11_LOWRES  1   // 0: 12/14bit (SHT11), 1: 8/12bit (SHT11+FOST02)

wenn SHT11_LOWERS auf 1 ist stimmt die Temperatur nicht, die Feuchte 
schon
wenn SGT11_LOWERS auf 0 ist stimmt beides

SGT11_LOWERS hat jedoch auch Einfluss auf die Berechung für Temp:

    int16_t v = result();
    if (sht11_valid(v)) {
#if SHT11_LOWRES
  v = v * 4 - 4000;
#else
  v -= 4000;
#endif
    }
    return v;


und für Feuchte:

    int16_t v = result();
    if (sht11_valid(v)) {
#if SHT11_LOWRES
  // inspired by Werner Hoch, modified for low resolution mode
  const int32_t C1 = (int32_t)(-4.0 * 100);
  const int32_t C2 = (int32_t)(0.648  100  (1L<<24));
  const int32_t C3 = (int32_t)(-7.2e-4  100  (1L<<24));
  v = (int16_t)((((C3 * v + C2) >> 7) * v + (1L<<16)) >> 17) + C1;
#else
  // inspired by Werner Hoch
  const int32_t C1 = (int32_t)(-4.0 * 100);
  const int32_t C2 = (int32_t)(0.0405  100  (1L<<28));
  const int32_t C3 = (int32_t)(-2.8e-6  100  (1L<<30));
  v = (int16_t)((((((C3 * v) >> 2) + C2) >> 11) * v + (1L<<16)) >> 17) + 
C1;
#endif
    }
    return v;


Vielen Dank für den Tip bis hierhin.

Gruß,
Thorsten

von Thorsten (Gast)


Lesenswert?

...kann es sein das der Autor für die Berechnung mit SHT11_LOWERS auf 1 
den Faktor 16 in die Multiplikation hätte aufnehmen müssen, sind doch 
schließlich 4 Bit unterschied...

Thorsten

von Thorsten (Gast)


Lesenswert?

...so ich habe mich jetzt mal daran gemacht die Formel zurück zu 
rechnen, ich hatte 1720 also 17,20 Grad auf dem Display. Wenn ich die 
oben genannte Formel als Grundlage nehme, und den einganswert durch x 
ersetze und danach auflöse muss:

v = x * 4 - 4000

v+4000 = x * 4

(v+4000)/4 = x

x=1430

der Wert vom Sensor also 1430 betragen haben, im 12 Bit mode -> Maximum 
256!?

Wenn ich nun aber diesen Wert (1430) in die Formel von Sensirions 
Beispielcode einsetze, frisch direkt von sensirion:

 const float C1=-4.0;              // for 12 Bit
  const float C2=+0.0405;           // for 12 Bit
  const float C3=-0.0000028;        // for 12 Bit
  const float T1=+0.01;             // for 14 Bit @ 5V
  const float T2=+0.00008;           // for 14 Bit @ 5V

  float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit
  float t=*p_temperature;           // t:       Temperature [Ticks] 14 
Bit
  float rh_lin;                     // rh_lin:  Humidity linear
  float rh_true;                    // rh_true: Temperature compensated 
humidity
  float t_C;                        // t_C   :  Temperature [°C]

  t_C=t*0.01 - 40;                  //calc. temperature from ticks to 
[°C]
  rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated 
humidity [%RH]
  if(rh_true>100)rh_true=100;       //cut if the value is outside of
  if(rh_true<0.1)rh_true=0.1;       //the physical possible range

  *p_temperature=t_C;               //return temperature [°C]
  *p_humidity=rh_true;              //return humidity[%RH]
}

  t_C=t*0.01 - 40;                  //calc. temperature from ticks to 
[°C]


Also: t_C=1430*0.01 -40

dann ist t_C=25,7 Grad nur negativ, dies würde dann aber richtig sein.

Gruß,
Thorsten

von Thorsten (Gast)


Lesenswert?

-> Maximum
256!?
 bitte wegdenken ist reingerutscht..

von (prx) A. K. (prx)


Lesenswert?

Welche Originalwerte liefert der Sensor in den beiden Modi? Ist ja nicht 
schwer, sich die ohne Umrechnung liefern zu lassen.

Zur Klarstellung, weil's grad ziemlich durcheinander geht:

Lores Modus: Hum 8 Bits, Temp 12 Bits.
Hires Modus: Hum 12 Bits, Temp 14 Bits.

Es ergibt wenig Sinn, den Wert mit der Lowres Formel für die Temperatur 
zurück zu rechnen um ihn dann in die Sensirion Hires Formel für die 
Feuchte einzusetzen.

von Thorsten (Gast)


Lesenswert?

so nun habe ich nochmal die Formelherleitung zerlegt:

für 14bit

t_C=t*0.01 - 40;

dann für 12 bit

t_C=t*0.01*4 - 40;

mit Multiplikator 100


für 14bit

t_C*100=t*0.01*100 - 40*100;

dann für 12 bit

t_C*100=t*0.01*4*100 - 40*100;


gekürzt

für 14bit

t_C*100=t - 4000;

dann für 12 bit

t_C*100=t*4 - 4000;



Aus meiner Sicht deutet alles darauf hin, das der Controller im Modus 
8/12Bit richtig rechnet, aber der Sensor nicht mt umschaltet...

Wie ist Eure Meinung?

Gruß,
Thorsten

von Thorsten (Gast)


Lesenswert?

Hallo A.K.

Welche Originalwerte liefert der Sensor in den beiden Modi? Ist ja nicht
schwer, sich die ohne Umrechnung liefern zu lassen.
-Ich habe den Sensor gerade nicht zur Hand, erst morgen wieder...

Zur Klarstellung, weil's grad ziemlich durcheinander geht:

Lores Modus: Hum 8 Bits, Temp 12 Bits.
Hires Modus: Hum 12 Bits, Temp 14 Bits.
-Ist klar.

Es ergibt wenig Sinn, den Wert mit der Lowres Formel für die Temperatur
zurück zu rechnen um ihn dann in die Sensirion Hires Formel für die
Feuchte einzusetzen.Beitrag melden |
-Entschuldige, aber dies habe ich ja auch nicht gemacht :-),dies ist 
doch die Formel für Temp:
t_C=t*0.01 - 40

ALso im Mode SHT11_LOWRES 1 bekam ich heute mittag (referenz rund 
25-25,5Grad auch SHT mit eval Board von Sensirion) einen Wert von 17,20 
Grad.

Da ich Ihn nicht zur hand habe, habe ich nun zurück gerechnet, der 
Sensirion muss 1430 zurückgegeben haben. Kann ich aber morgen mehr zu 
sagen :-)

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> -Entschuldige, aber dies habe ich ja auch nicht gemacht :-),

Rückgerechnet hast du auf Lowres Basis, aber danach hast du diesen Wert 
durch Sensirions Beispielcode für Hires gejagt (sorry, ich hatte 
übersehen dass der Temp und Hum rechnet). Dass dabei was Negatives 
rauskommt überrascht mich weniger.

von Thorsten (Gast)


Lesenswert?

:-) warum? ich krame gerad im Datenblatt... aach ich dachte es bleibt 
mir in dem Ausmaß erspart... :-)

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich hab hier:
Beitrag "Re: SHT11, Abweichung bei Temperatur"
meinen Code gepostet. Ganz ohne Float.

Im Datenblatt ist eine Kurve mit Counts/Wert drin. Wenn ich damit 
vergleiche passt meine Rechnung.
Dennoch stimmt meine Temp nicht.

von Thorsten (Gast)


Lesenswert?

Hallo AK,

ich habe meinen Fehler gefunden, ich habe es nicht ganz richtig gsteuert 
und somit start_humid() aufgerufen und result_temp() abgefragt. man.

Referenz 1: Eval Kit 1 mit SHT75 calib zeigt:

H 32,65
T 25,24

Referenz 2:Außentermometer

T 25,2

Ich habe meine Ausgaben mal erweitert.
Ergebnis:

Lowers     0       1
       12/14    8/12

H      35,30   35,08
Hraw    1047      66
T      25,13   25,12
Traw    6517    1628

Nun stimmen die Werte, ich habe da nur noch eine Rückfrage:

Die Feuchte ist immer noch um 3Prozent zu hoch. Aus dem oben geposteten 
Code von Sensirion ist zu erkennen das eine Temp. Kompensierung 
stattfindet. Dies ist in deinem Code nicht berücksichtigt - oder habe 
ich das falsch erkannt...

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> Code von Sensirion ist zu erkennen das eine Temp. Kompensierung
> stattfindet. Dies ist in deinem Code nicht berücksichtigt - oder habe
> ich das falsch erkannt...

Korrekt erkannt. Liegt ein bischen am Prinzip, denn wenn man Temperatur 
und Feuchte getrennt abfragt, kriegt man das natürlich nicht gleich 
zusammengerechnet. Es fehlt also eine Funktion, die mit linearisierter 
Feuchte und Temperatur als Parameter den korrigierten Wert für die 
Feuchte auswirft. Ist nicht sonderlich schwierig, war bei mir aber nicht 
nötig.

von (prx) A. K. (prx)


Lesenswert?

Es ist auch keine Kompensation der Versorgungsspannung drin.

von Thorsten (Gast)


Lesenswert?

Hallo AK,

ich würde die Kompensierung gern noch nachrüsten :-). Das ist dann diese 
Formel:

     const float T1=+0.01;             // for 14 Bit @ 5V
     const float T2=+0.00008;           // for 14 Bit @ 5V
[A]  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature 
compensated

wobei die lineare Feuchte, die sich wie folgt errechnet:

     const float C1=-4.0;              // for 12 Bit
     const float C2=+0.0405;           // for 12 Bit
     const float C3=-0.0000028;        // for 12 Bit
[C]  rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to 
[%RH]

und der RAW wert rh bei der Berechnung der Temp. kompensierten eine 
Rolle spielen.

Kann man sagen das deine Formel die Rechnung der linearen erfüllt [A]? 
Dann bleibt noch schritt [C] für die weiterberechnung. Die genutzen 
Werte sind alle auf die 12Bit Werte ausgelegt.

Mein Plan wäre es in einem dritten schritt, die Messergebnisse aus Temp 
und Hum zusammenzuführen um Temp Komp Hum auszurechnen. Dann habe ich 
aber die mit 100 mal genommenen 16Bit werte aus deiner Formel mit im 
Spiel...

Wie würdest du das am schnellsten und einfachsten machen?

Gruß,
Thorsten

von Thorsten (Gast)


Lesenswert?

...ich betreibe Ihn nur an 5V. erzeugt mit 7805.

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Apropos Kompensation: Bei deinen 25°C Temperatur gibt es effektiv keine 
Temperaturkompensation. Das ist es also nicht.

+/-3%RH Abweichung sind beim SHT11 sowieso drin und +/-2%RH beim SHT15. 
Summarum dürfen beim Vergleich SHT11 mit SHT15 also bis 5%RH Abweichung 
auftreten.

von Thorsten (Gast)


Lesenswert?

[A] und [C] verdreht!!!

von Thorsten (Gast)


Lesenswert?

ja, habe ich gesehen, ich hatt nur noch nicht ergründet wieviel das 
ausmacht.... :-)

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> Wie würdest du das am schnellsten und einfachsten machen?

Ich sehe grad, dass in der Kompensationsformel der Rohwert drinsteht. 
Wenn du das so durchziehen willst, dann geht das nicht so wie grad 
erwähnt, denn der steht da nicht zur Verfügung. Um im Schema zu bleiben 
sollte man also sht11_result_humid um einen Temperaturparameter 
ergänzen:
  int16_t sht11_result_humid(int16_t temp);

Zur Übung darfst du nun die Sensirion-Formel in Festkommarechnung 
überführen ;-). Oder musst so lange warten, bis ich oder sonst jemand 
Lust darauf verspürt. Denn Fliesskommarechnung sollte da nicht rein.

Es wäre sinnvoll, wenn das dann im Originalthread landet.

von Thorsten (Gast)


Lesenswert?

Hallo AK,

das wäre eh mein Ziel gewesen. Das der Originalwert einfließt habe ich 
versucht zuvor zu verdeutlichen.

1)Für mich wäre es ganz gut, wenn ich erfahren könnte welchen Teil der 
Formel Du bereits ersetzt hast, dazu diente eigentlich die Auflistung 
weiter oben.
>>
ich würde die Kompensierung gern noch nachrüsten :-). Das ist dann diese
Formel:

     const float T1=+0.01;             // for 14 Bit @ 5V
     const float T2=+0.00008;           // for 14 Bit @ 5V
[A]  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature
compensated

wobei die lineare Feuchte, die sich wie folgt errechnet:

     const float C1=-4.0;              // for 12 Bit
     const float C2=+0.0405;           // for 12 Bit
     const float C3=-0.0000028;        // for 12 Bit
[C]  rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to
[%RH]

und der RAW wert rh bei der Berechnung der Temp. kompensierten eine
Rolle spielen.
<<

2)Mal sehen ob ich mir das so aus dem Ärmel schütteln kann.


Zu [A]:

     const float T1=+0.01;             // for 14 Bit @ 5V
     const float T2=+0.00008;           // for 14 Bit @ 5V
[A]  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature
compensated

in rh der raw wert.
in rh_lin ist dann der Wert x 100 enthalten,
T1 und T2 sind nur für 14bit berechung,
t_C enthält ebenfalls dann eine Temp x100

da deine Formeln diesen Werte so zurückgeben.

Im Beispiel sind diese Variablen alle float (rh_lin/t_C) und auch das 
Ergebnis.

Sehe ich das richtig?

Thorsten

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> wobei die lineare Feuchte, die sich wie folgt errechnet:

Klar, aber rh_lin wird ja schon berechnet, das ist das bisherige
Ergebnis. Nur eben nicht mit Fliesskommarechnung, sondern als
Festkommarechnung.

> T1 und T2 sind nur für 14bit berechung,

Yep, da ist dann eine Unterscheidung lo/hires notwendig.

von (prx) A. K. (prx)


Lesenswert?

Und wenn du schon dabei bist, dann kannst du vielleicht auch noch eine 
Spannungskompensation nachrüsten:
  int16_t sht11_result_temp(uint8_t vcc); // VCC in Volt*10

von Thorsten (Gast)


Lesenswert?

@AK,

welchen Teil der Formel hast du bereits ersetzt?


Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Frage unklar. rh_lin ist fertig, in den bekannten 100ern, die 
Temperaturkompensation rh_lin => rh_true fehlt noch.

von Thorsten (Gast)


Lesenswert?

..ich wollte nur sicher gehen, das das auch wirklich so ist...

sennoch muss ich mal sehen wieviel Zeit ich hier investieren muss..

Thorsten

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Ich bin vom SHT11 sehr enttaeuscht. Wirklich akkurate Werte bei 
Temperatur konnt ich dem nie entlocken, egal mit welchen Tricks. Scheint 
halt mehr auf Feuchte optimiert zu sein. Im Winter hat er immer viel zu 
warm gemessen (teilweise 5-6 Grad, und nein, keine Heizung und nur ein 
Wert alle 10 Sekunden oder sowas) waehrend er im Sommer schon sehr nah 
an einem DS1621 war. Ich nehme an dass da auch nicht-lineare 
Verzerrungen eine Rolle spielen, wofuer die zwar eine Formel zum 
Ausgleichen angeben (die ich auch verwendet habe in dem Treiber), das 
scheint aber auch nicht das Gelbe vom Ei zu sein. Und zur Kroenung ist 
das Ding dann nach ein paar Monaten Dauereinsatz einfach gestorben.

Die Quintessenz: Das Ding ist einfach ungenau. Das kann man jetzt 
drehen, wenden, zwirbeln. Es wird nichts aendern, vor allem bei kalten 
Temperaturen um und unter 0 wird er wirklich sehr ungenau. Und von 
Zuverlaessigkeit moecht ich auch nicht wirklich sprechen.

Michael

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Noch was: Diese Korrekturrechnung haengt auch von der verwendeten 
Spannung ab, was sich allerdings auch nur minimal auswirkt wenn man 
jetzt mit 3.3V rechnet obwohl man 5V verwendet. Und man sollte max. 
einen Messwert pro 30 Sekunden holen. Hat bei mir allerdings auch keine 
wirkliche Verbesserung gezeigt (minimal).

von (prx) A. K. (prx)


Lesenswert?

Michael G. schrieb:

> halt mehr auf Feuchte optimiert zu sein. Im Winter hat er immer viel zu
> warm gemessen (teilweise 5-6 Grad, und nein, keine Heizung und nur ein
> Wert alle 10 Sekunden oder sowas)

Kann ich nicht nachvollziehen. Zu den Feuchtewerten fehlt mir der 
Vergleich, aber bei der Temperatur haben die Werte bisher gestimmt.

Hast du das mit mehreren versucht, oder kann es sein, dass dein Exemplar 
eine Macke hatte?

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Ich habe einen zweiten, der komplett nen Schuss weg hat und eine 
vollkommen falsche Temperatur liefert (waehrend die Feuchtewerte 
plausibel sind). Ich hab halt mit dem DS1621 verglichen. Also nur beste 
Erfahrungen ;) ich sag ja auch: Diese starken Abweichungen hatte er nur 
im negativen Bereich. Im positiven war er quasi auf 0.5Grad immer mit 
dem DS1621 konform, was ja dessen Messgenauigkeit ist.

von (prx) A. K. (prx)


Lesenswert?

Ok, negativ habe ich nicht probiert.

von Thorsten (Gast)


Lesenswert?

Hi,

also Spannungscompensation ist drin.

Ich habe deine gesamte Software noch einmal eingeschalt und mit einer 
Statemühle versehen.

Die Geschichte mit den abweichenden Temperaturwerten kann ich nicht 
bestätigen. Ich habe hier mehrere Sensoren am Start, und evrzeichne zur 
Zeit eine Henauifkeit von +/- 0,07Grad maximal. Ich mache alle 2 
Sekunden eine Messung.

So, nun bin ich gerade dabei die Temperaturabhängigkeit in die feuchte 
mit zu überführen.

Was ist 1L in der Festpunktrechnerei?

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

1L = (long)1

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> Ich mache alle 2 Sekunden eine Messung.

Obacht: Sensirion empfiehlt, den Sensor nicht mehr als 10% der Zeit 
aktiv zu halten und eine 14bit Messung dauert ~320ms. Sonst droht 
Verfälschung durch Selbstaufheizung.

von Thorsten (Gast)


Lesenswert?

danke für den Tip.

ich habe nun die Kompensierung eingebaut um es auszuprobieren. Ich habe 
nun eine Feuchte Abweichung von rund 1% +/- anstatt 3, das passt.

Ich habe sie nun quick und dirty in float eingebaut, werde das nun 
umsetzen in festkomma.

v= humid_lin (in der Formel) (int16_t)
sht11_tmp= temperatur spannungskompensiert (int16_t)
sht11_hum_raw= ausgelesener Feuchterwawert (uint16_t)


    return (int16_t)(  ( ((float)sht11_tmp/100-25)  * 
(0.00008f+0.01f*((float)(sht11_hum_raw)))  +   (((float)v/100))  ) 
*100.0f );


Gruß,
Thorsten

von Thorsten (Gast)


Lesenswert?

ergo, macht dieser Ausdruck aus einer 1 eine 1 mit 16 nullen?

(1L<<16)

Gruß,
Thorsten

von (prx) A. K. (prx)


Lesenswert?

Thorsten schrieb:

> ergo, macht dieser Ausdruck aus einer 1 eine 1 mit 16 nullen?
> (1L<<16)

Binär gesehen ja. Ein C Handbuch wäre aber sicherlich keine Fehler.

von Thorsten S. (whitejack)


Angehängte Dateien:

Lesenswert?

Hi,

so das Problem ist gelöst, der Code ist nun um eine 
Temperaturkompensierung der Luftfeuchte reicher.

Gruß,
Thorsten

von Clyde H. (clyde)


Lesenswert?

Hallo,

ich verwende die Whitejack3 Version für einen SHT11.
Ich würde gerne wissen, was ich tun muss um Negative Temperaturen 
korrekt auf einem LCD anzeigen zu lassen.
Im Momend ist es so, das ich -03,-05°C angezeigtn bekomme.
Aber ich möchte es natürlich als -03,05°C anzeigen lassen.
Bei meines DS18S20 Sensor erreiche ich das mit temp *= -1, aber temp 
lasse ich dann mit temp/10,temp%10 anzeigen.
Mein C ist alles aber nicht gut und die  Minusgrade halten noch nicht 
lang genug damit ich in der Freizeit experimentieren kann.

Die Plusgrade sind relaitv conform mit dem DS18S20, +/-1°C Differenz und 
auch die Negativen werte passen.
Nur das - hinter dem Komma stört total...

Ausserdem würde ich gerne wissen, was ich machen/beachten muss, wenn ich 
ca. 6-10m Kabel zwischen Sensor und MC benutzen möchte.

Würde mich über Tipps und Hinweise freuen, nur bitte keine 
herablassenden Kommentare weil die bringend keinem was.

Gruß
Clyde

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.