Temperatur berechnung ADE7758

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo,

irgendwie komme ich nicht auf die Temperatur. Was mache ich falsch?



CodeBox C
uint8_t ADE7758_readTEMP_OFFSET(void)
{
   uint8_t offset = ADE7758_read8bit(REG_TEMP);
   return offset;
}

uint16_t ADE7758_readTEMP(uint8_t offset)
{
   uint16_t temperature = 0;
   
   temperature    = (uint8_t)ADE7758_read8bit(REG_TEMP);
   temperature -= offset;
   temperature *= 3;
   temperature += 27;
   
   return (temperature);
}


DB Seite "28"

https://www.google.de/url?sa=t&rct=...QaHaiOcDRHtL9g&bvm=bv.115277099,d.ZWU&cad=rja

Berechne ich es richtig?
 
Zu eventuellen Fehlern in C kann ich nichts sagen, vom Rechenweg her sollte es passen, WENN die "ADE7758_readTEMP_OFFSET()"-Subroutine bei genau 27°C Umgebungstemperatur aufgerufen wird. (Weil dann der in uint8_t "offset" abgelegte Rohdatenwert genau den 27°C entspricht, die Du am Ende draufaddierst.

uint8_t steht doch eigentlich für unsigned integer (also eigentlich ein vorzeichenloses Byte), oder? Sollten das nicht eigentlich signed sein? Solange die Temperatur immer positiv ist, spielts wohl keine Rolle...
 
Der "offset" hat nichts mit den "27°C" zu tun. Das ist einfach eine Konstante laut Datenblatt (im Datenblatt nur 25°C)...

So wie ich das interpretiere, muss ich beim ersten Start (jedes mal beim einschalten) direkt den ersten Wert aus dem Temperaturregister abholen und diesen als "offset" nutzen.

Ja genau, uint8 oder 16 ist ein unsignierter Datentyp ohne Vorzeichen. Der Sensor sendet mir auch nur ein uint8... Brauche auch keine "-" Temperaturen.

Das ist die Formel laut Datenblatt.:



CodeBox C
Temp (°C) = [(TEMP[7:0] − Offset) × 3°C/LSB] + Ambient(°C) (4)
 
Zuletzt bearbeitet:
Hallo Janiiix,

ich habe mir das Datenblatt noch nicht angeschaut. Bei deinem C Code ist mir aufgefallen bzw. nicht ganz klar welchen Wert letztendlich "offset" hat.

Die Funktion ADE7758_readTEMP_OFFSET gibt den offset zurück. Hier liest du den Wert aus dem Register REG_TEMP.
Aus dem selben Register liest du in der Funktion ADE7758_readTEMP. Da subtrahierst du dann die Werte, das Ergebnis sollte Null sein und es sollte letztendlich immer die Ambienttemperatur (bei dir 27°C) herauskommen. Das ist dann so nicht richtig.

Dirk :ciao:

Dein Code:


CodeBox C
uint8_t ADE7758_readTEMP_OFFSET(void)
{
 uint8_t offset = ADE7758_read8bit(REG_TEMP);
 return offset;
}

uint16_t ADE7758_readTEMP(uint8_t offset)
{
 uint16_t temperature = 0;
 temperature  = (uint8_t)ADE7758_read8bit(REG_TEMP);
 temperature -= offset;
 temperature *= 3;
 temperature += 27;
 return (temperature);
}
 
Hallo Dirk,

so steht das auch im Datenblatt oder habe ich das falsch verstanden?
Es steht dort geschrieben:

For example, if the temperature register produces a code of 0x46 at ambient temperature (25°C), and the temperature register currently reads 0x50, then the temperature is 55°C :
Temp (°C) = [(0x50 – 0x46) × 3°C/LSB] + 25°C = 55°C


Also beim einmaligen einschalten, den Wert messen von dem Tempregister und diesen dann als "offset" verrechnen.

Hier die ganze Beschreibung:

TEMPERATURE MEASUREMENT
The ADE7758 also includes an on-chip temperature sensor. A temperature measurement is made every 4/CLKIN seconds. The output from the temperature sensing circuit is connected to an ADC for digitizing. The resultant code is processed and placed in the temperature register (TEMP[7:0]). This register can be read by the user and has an address of 0x11 (see the Serial Interface section). The contents of the temperature register are signed (twos complement) with a resolution of 3°C/LSB. The offset of this register may vary significantly from part to part. To calibrate this register, the nominal value should be measured, and the equation should be adjusted accordingly.
Temp (°C) = [(TEMP[7:0] − Offset) × 3°C/LSB] + Ambient(°C) (4)
For example, if the temperature register produces a code of 0x46 at ambient temperature (25°C), and the temperature register currently reads 0x50, then the temperature is 55°C :
Temp (°C) = [(0x50 – 0x46) × 3°C/LSB] + 25°C = 55°C
Depending on the nominal value of the register, some finite temperature can cause the register to roll over. This should be compensated for in the system master (MCU).
The ADE7758 temperature register varies with power supply. It is recommended to use the temperature register only in applications with a fixed, stable power supply. Typical error with respect to power supply variation is show in Table 5.
 
For example, if the temperature register produces a code of 0x46 at ambient temperature (25°C), and the temperature register currently reads 0x50, then the temperature is 55°C :
Temp (°C) = [(0x50 – 0x46) × 3°C/LSB] + 25°C = 55°C


Also beim einmaligen einschalten, den Wert messen von dem Tempregister und diesen dann als "offset" verrechnen.
Da steht: Wenn der Sensor bei einer Umgebungstemperatur von 25°C das Ergebnis 0x46 liefert, kannst Du die Temperatur wie folgt berechnen:
Ergebnis= ((gelesener Rohwert-0x46)*3)+25.
Ist der Rohwert 0x50, ergeben sich so 55°C.

The resultant code is processed and placed in the temperature register (TEMP[7:0]). This register can be read by the user and has an address of 0x11 (see the Serial Interface section). The contents of the temperature register are signed (twos complement) with a resolution of 3°C/LSB. The offset of this register may vary significantly

Der Zusammenhang zwischen Temperatur und Wert soll nahezu linear sein, ein Bit entspricht drei Kelvin. Aber über den Offset des IC (insbesondere jedes einzelnen kann nichts vorhergesagt werden - deswegen mußt Du den selbst ermitteln.
Ermittelst Du den Offsetwert bei 0°C, vereinfacht sich die spätere Berechnung zu Ergebnis = (gelesener Wert - Offsetwert)*3.
(Je weniger der Zusammenhang linear ist, desto mehr Sinn macht es, den Offset in einem Bereich zu bestimmen, wo der Sensor später genutzt werden soll)

@Dirk : das ist so eigentlich schon richtig, wenn die readOffset-Routine eben zum ermitteln des Offsets herangezogen werden soll. allerdings ist der ambient-Wert mit 27°C hier fest vorgegeben - es muß also jedesmal sichergestellt sein, daß beim ermitteln des Offset auch wircklich diese Temperatur vorliegt.
 
Zuletzt bearbeitet:
Wie bestimme ich den Offset jetzt am besten? Mit einem anderen Thermometer vergleichen und die Differenz abziehen oder drauf rechnen?
Wenn ich einfach nur die Rohdaten aus dem Sensor auslese passt es ja einigermaßen mit der aktuellen Temperatur... Nur wenn ich meinen Finger oder nen Lötkolben auf das Gehäuse halte, ändert sich nicht wirklich viel an °C...
 
@Dirk : das ist so eigentlich schon richtig, wenn die readOffset-Routine eben zum ermitteln des Offsets herangezogen werden soll. allerdings ist der ambient-Wert mit 27°C hier fest vorgegeben - es muß also jedesmal sichergestellt sein, daß beim ermitteln des Offset auch wircklich diese Temperatur vorliegt.
@LotadaC : Gut, das leuchtet mir ein :) Mir war das nur mit dem zeitlichen Ablauf nicht klar. Ich dachte: 1. Kalibrierwert lesen 2. und dann sofort die Temperatur. Man muss also zunächst den Temperaturwert bei Nenntemperatur lesen und den dann in die Rechnung einbeziehen.

Noch einmal zum Temperaturwert. Dieser liegt als Zweierkomplement vor, hier kann es zum Überlauf kommen. Höchster Wert ist 0x7F (127d), das sollte ggf. berücksichtigt werden.
 
Wie bestimme ich den Offset jetzt am besten?
Du nimmst einfach den Rohwert bei einer bekannten Temperatur (also mit einem Thermometer, ja).
Früher hat man Eiswasser oder kochendes Wasser genommen (Zweipunktekalibrierung), wobei Du den Chip sicher nicht in kochendes Wasser schmeissen willst.
Wenn sich da wirklich nicht viel ändert, solltest Du vielleicht 'ne Messreihe starten (also die Temperatur langsam erhöhen, und die ausgelesenen Rohdaten zusammen mit der tatsächlichen Temperatur aufzeichnen). Zu erwarten wäre, daß der Wert alle drei Kelvin eins raufgeht.

Wegen dem Zweierkomplement: meinte ich oben bereits - in ASM sind das alles ja nur Bytes, und man muß selbst bei der Berechnung auf sowas achten (zB ASR statt LSR nehmen), aber Ihr als Hochsprachler solltet doch genau für sowas 'n signed Datentyp haben
 
Okay. Ich habe bei einer Raumtemperatur von ca. 20°C einen Rohwert von 0xDD. So und nun?

Temperatur = (gemessene_temperatur - offset) das kann ja auch in dem gleichen Moment 0 ergeben. Sprich wenn Offset und gemessene Temperatur gleich sind.
 
für sowas 'n signed Datentyp
int,
int8_t, int16_t ...

Wird in der oben angegebenen Gleichung mit dem Datentyp uint8_t gerechnet, gibt es dann einen Überlauf, wenn die aktuell "gelesene" Temperatur kleiner ist als der Kalibrierwert bei Temperaturnennwert. ... und das ist sicher nicht ganz unwahrscheinlich.
 
Okay. Ich habe bei einer Raumtemperatur von ca. 20°C einen Rohwert von 0xDD. So und nun?
Temperatur = (gemessene_temperatur - offset) das kann ja auch in dem gleichen Moment 0 ergeben. Sprich wenn Offset und gemessene Temperatur gleich sind.

Jain, du hast vergessen die 20°C Nenntemperatur zu addieren (und zuvor die Differenz mit 3 zu multiplizieren).

So wie ich es verstehe werden ja 8 Bit 2er Komplement übergeben, mit einer Auflösung von 1/3°C ?! Die höchste positive messbare Temperatur wäre also 127d / 3 = 42,3°C, 0xDD wären was negatives ... oder ist es jetzt einfach für mich doch schon zu spät :confused:;)
 
Ich verstehe den ganzen Kram mit dem Offset nicht wirklich.
Man müsste den Chip wie schon gesagt bei einer Bekannten Temperatur kalibrieren. Sprich ich nehme mir mein "ultra genaues" zweites Thermometer und lasse den Chip etwas laufen.

Sagen wir ich habe bei einer Raumtemperatur von 24°C einen Rohwert von 260, so weiß ich welchen Wert ich für 24°C habe.

Und diesen verrechne ich jetzt mit dem einschalt Rohwert. So müsste ich doch den AD Wert für die Temperatur haben.

Natürlich müsste ich dafür auch einen Datentyp von int16 nehmen.

0b00000001 wären dann 1*3 °C.
0b00000010 wären dann 2*3°C.

Oder sehe ich das falsch?
 
mit einer Auflösung von 1/3°C
Nein, andersrum...
with a resolution of 3°C/LSB
Höchstes Ergebnis (ohne Offset) wäre 381°C
bei einer Raumtemperatur von ca. 20°C einen Rohwert von 0xDD
0xDD ist vorzeichenbehaftet dezimal "-35". Es wären also -35 als Offset zu wählen, bei der Ambient-Temperatur von (ca.) 20 (da, wo Du die 27 in der Formel hattest)

Temperatur(gelesener Wert)=((gelesener Wert-(-35))*3)+20°C
 
Wie kommst du da drauf das es negativ ist?
 
Sagen wir ich habe bei einer Raumtemperatur von 24°C einen Rohwert von 260, so weiß ich welchen Wert ich für 24°C habe.
Das geht nicht (also der Sensor kann als Rohwert nie 260 liefern), da der Sensor Dir nur eine vorzeichenbehaftete 8bit-Zahl gibt, also von -128 bis 127.

warum negativ: weil das Byte, was der Sensor liefert eine vorzeichenbehaftete Zahl ist (laut Datenblatt). Also ist 0xDD=11011101binär als vorzeichenbehaftete Zahl zu verwenden (= -35), alles "größer" 01111111binär (=127dezimal) ist negativ.
10000000bin= -128dez
 
Zuletzt bearbeitet:
Also gibt mir das MSB an ob positiv oder negativ?
 
Ja... aber 11111111bin ist nicht -127, sondern -1
Du mußt Dir erstmal die vorzeichenlosen binären Zahlen als Kreis vorstellen, oben 00000000, dann im Uhrzeigersinn hochzählen. Rechts ist dann die 01000000(64), unten die 10000000(128), links die 11000000(192), und die letzte vor der 0 ist die 11111111 (255).
Die bits bleiben dieselben, aber wenn man das als vorzeichenbehaftet interpretiert, ist die linke hälfte negativ. indem du von oben gegen den Uhrzeigersinn die negativen zählst.
Also 11111111=-1
11111110=-2
usw
10000000 ist die -128 die rechte Seite sind die positiven.

Deine ReadTemp arbeitet ja bereits mit 16bit, aber Du darfst nicht mit unsigned arbeiten
 
Okay. Werde es morgen nochmal direkt versuchen.

Klingt jetzt alles ein bisschen einleuchtendender. Muss ich jedesmal den Offset neu messen oder macht es Sinn diesen im eeprom abzulegen?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)