Microchip 9808 Temperatursensor - Falsches Berechnungsergebnis

Ich verwende einen Microchip MCP9808 I2C Temperatursensor ( https://learn.adafruit.com/adafruit-mcp9808-precision-i2c-temperature-sensor-guide/overview ).

Ich habe Probleme, die Temperatur anhand der Werte zu berechnen, die ich vom Sensor ablese.

Die Temperatur ist 13 Bit breit. Laut Datenblatt muss ich zwei Lesebefehle senden, das erste Lesen, um das obere Byte zurückzugeben, und das zweite Lesen, um das untere Byte zurückzugeben. 3 der verbleibenden Bits werden verwendet, um Temperaturalarme anzuzeigen, und 1 Bit wird verwendet, um das Vorzeichen des Messwerts anzuzeigen (positiv oder negativ).

Ich kann die beiden Bytes lesen, indem ich den Beispielcode aus dem Datenblatt als Ausgangspunkt verwende. Die Werte, die ich daraus bekomme, sind jedoch falsch. Ich kann auch keine negativen Temperaturen bekommen, also denke ich, dass mein Code etwas falsch macht.

Ich verwende einen USB->I2C-Adapter und habe eine C#-Implementierung des Datenblatt-Beispielcodes geschrieben, um die Temperatur zu berechnen.

Geben Sie hier die Bildbeschreibung ein

Und dann ist mein Code (der abgesehen von einigen zusätzlichen notwendigen Castings aufgrund der Art und Weise, wie C# Datentypen verarbeitet) meiner Meinung nach identisch ist.

    public static double CalculateAmbientTemperature(byte upperByte, byte lowerByte)
    {
        const byte ALERT_MASK_VALUE = 0x1F;
        const byte CLEAR_SIGN_MASK = 0x0F;

        double temperature = 0.00;

        upperByte = (byte)(upperByte & ALERT_MASK_VALUE);

        // Ambient temperature less than 0 degrees
        if((upperByte & (byte)(upperByte & 0x10)) == 0x10)
        {
            upperByte = (byte)(upperByte & CLEAR_SIGN_MASK);
            temperature = 256.0 - ((double)upperByte * 16.0 + (double)lowerByte / 16.0);
        }
        else
        {
            temperature = ((double)upperByte * 16.0 + (double)lowerByte / 16.0);
        }

        return temperature;
    }

Um den Code zu testen, habe ich die Bytes gesendet: START_BIT 0x3E (the address) 0x05 (the address of the temperature register)Dies weist den Sensor an, den Registerzeiger auf das Temperaturregister zu zeigen, so dass, wenn ich die beiden Lesebefehle sende, er aus diesem Register liest.

Und wenn ich die Daten zurücklese, bekomme ich 0xC1 0x24. Wenn ich diese Werte an die Funktion übergebe, erhalte ich 17,0625 Grad C. Bedenke, dass ich einen Eiswürfel auf den Sensor halte. (Habe derzeit keinen genaueren Weg). Im Grunde genommen ist meine Berechnung fehlerhaft, aber ich weiß nicht, wo ich anfangen soll, sie zu beheben.

Jede Hilfe wäre willkommen.

(BEARBEITEN: Um zu überprüfen, ob ich den Chip richtig lesen kann, lese ich das Hersteller-ID-Register und erhalte die erwarteten 0x54)

Dein CLEAR_SIGN_MASKAussehen ist falsch. Es sollte sein0x1F
Ach komm schon. Es gibt immer einen besseren Weg. Zerkleinern Sie etwas Eis, machen Sie eine Eis/Wasser-Aufschlämmung in einer Schüssel, stecken Sie Ihren Sensor in eine Plastiktüte, tauchen Sie ihn in die Eis/Wasser-Mischung und geben Sie ihm Zeit, sich auszugleichen. Sie werden sehr nahe bei Null sein.
@EugenSch. Wie so? Das Datenblatt sagt 0x0F?
@ user9993 Entschuldigung, ein bisschen verpasst. Außer Acht lassen :)
Ich berechne diese Werte manuell als 18,25 Grad. Aber dann habe ich die Rangfolge in meiner Berechnung richtig hinbekommen. Tipp: Erst ganz zum Schluss doppelt arbeiten. Halten Sie es als ganze Zahlen.
@Majenko Können Sie erklären, wie ich mit meinem Code die richtige Rangfolge verwenden kann?
Bauen Sie zunächst eine 16-Bit-Ganzzahl aus Ihren zwei Bytes auf. Maskieren Sie dann die nicht gewünschten Bits aus, und erst dann sollten Sie es durch 16 teilen. Sie arbeiten also mit 0xC124, dann 0x0124, dann 0x012.4
Sind Sie sicher, dass Sie die richtigen Daten lesen? Versuchen Sie, die Register zu lesen, die bekannte Werte enthalten, und vergewissern Sie sich, dass Sie sie richtig erhalten.
17.0625 wäre das Ergebnis von 0xC1 0x11 und nicht 0xC1 0x24. Da Byte in C# unsigniert ist, sieht dies in Ordnung aus, aber die Umwandlungen könnten in C/C++ ein Problem darstellen, wenn Byte signiert wäre.
Wo hast du den Chip gekauft? Irgendein Händler oder einfach aus China? Ich kaufte einige Stücke von MCP9808 von Mouser und einige von Aliexpress. Die von Mouser lesen die Temperatur genau wie im Beispiel im Datenblatt ab. Aber alle von Ali geben sehr zufällige Temperaturen an. Also hielt ich diese Porzellanchips für fehlerhaft. Jetzt sehe ich, dass es wahrscheinlich durch einen anderen Algorithmus verursacht werden könnte?
Ich habe meine in den Adafruit-Boards bekommen, ich habe sie noch nicht als IC gekauft, nur noch. Die aus China klingen wie 100% Fälschungen, das hat nichts mit Algorithmen zu tun. Sind Sie zu 100 % in der Lage, die Probleme jedes Mal zu reproduzieren? Ich persönlich würde niemals ICs oder andere Komponenten von Aliexpress kaufen. Gefälschte ICs/Komponenten sind ein sehr bekanntes Problem, das Jahrzehnte zurückreicht. adafruit.com/product/1782
Ja, meine ursprünglichen Chips messen die Temperatur mit ziemlich guter Konsistenz (z. B. 26 ° C). Aber diese Chips von Ali sind Müll. Einer gibt ungefähr 10 ° C an, ein anderer ungefähr 20 ° C, ein anderer ungefähr 28 ° C usw. Sie sind weit davon entfernt. Es scheint, dass der Preis zu gut war, um wahr zu sein. Jetzt sehe ich die Antwort von @freshness, es geht um falsche Berechnung.

Antworten (1)

Ich bin kürzlich selbst auf dieses Problem gestoßen. Der Fehler stammt aus dem Datenblatt des Herstellers. Wenn das 'Negativ'-Flag gesetzt ist, lautet die richtige Berechnung:

temp -= 256;  // correct!

anstatt

temp = 256 - temp;  // incorrect! But this is the example in the datasheet!

Hier sind ein paar Beispiele für Steuercode für den MCP9808 auf Github:

lexruee/mcp9808

adafruit/Adafruit_MCP9808_Library

Danke für die Änderungen. Außerdem: Ich habe einen Dokumentationsfehlerbericht an Microchip gesendet. Wir werden sehen, wie sie reagieren.
Haben sie jemals geantwortet? @Frische
Nein, das taten sie nicht. Ich habe ungefähr ein Jahr später eine Umfrageanfrage gestellt und sie ziemlich niedrig bewertet, aber keine Bestätigung und keine Änderung der Dokumentation.
Wie nervig! @Frische
Ich habe die Berechnung aus dem Datenblatt verwendet und es gibt korrekte Werte. Ihre modifizierte Gleichung liefert falsche Ergebnisse.
Vielleicht war ich nicht klar genug: Das Datenblatt ist korrekt, aber der Beispielimplementierungscode im Datenblatt ist falsch. Kopieren Sie also nicht einfach den C-Code aus dem Datenblatt.