Temperaturmessung mit PT100 und MAX31865

Antwort erstellen


Um automatische Eingaben zu unterbinden, musst du die nachfolgende Aufgabe lösen.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :| :mrgreen: :geek: :ugeek:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[flash] ist ausgeschaltet
[url] ist eingeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas
   

Wenn du eine Datei oder mehrere Dateien anhängen möchtest, gib die Details unten ein.

Ansicht erweitern Die letzten Beiträge des Themas: Temperaturmessung mit PT100 und MAX31865

Re: Temperaturmessung mit PT100 und MAX31865

#61

von Nico » 30. Apr 2019, 14:50

Du brauchst doch zur Kommunikation nicht mehrmals die SPI Routine implementieren. Mach dir das Leben doch etwas einfacher ;-) Deine schöne spi_transfer() Funktion kannst du doch auch zum Senden/Empfangen für andere Teilnehmer am Bus nutzen. Und wenn diese auch im selben SPI Mode arbeiten, sogar mit super wenig Aufwand.

Ich denke das hier war dein letzter Stand?

Code: Alles auswählen

void spi_transfer (uint8_t *pBuf, uint8_t len)
    {
        int8_t i;
        
        SCLK = 1;
        CS_MAX = 0;
        
        if(pBuf == 0) return;
        
        while(len) {
            for (i=7; i>=0; i--) {
                __delay32(100);
                SCLK ^= 1;
                
                SDO = ((*pBuf) & (1<<i)) ? 1 : 0;
                __delay32(100);
                SCLK ^= 1;
                
                if (SDI) {
                    *pBuf |= (1<<i);[c][/c]
                }
                else {
                    *pBuf &= ~(1<<i);
                }
                
            }
            pBuf++;
            len--;
        }
        CS_MAX = 1;
    }
Ich bin mir einigermaßen sicher, dass die Zeile SCLK = 1; am Anfang der Funktion nicht notwendig ist (vorrausgesetzt du fummelst nirgends anders an diesem GPIO rum). Also weg damit .. somit ist das Aktivieren bzw. Deaktivieren vom CS die erste und letzte Anweisung innerhalb der Funktion.

Das heißt, du kannst diese beiden Anweisungen auch problemlos auslagern, sprich vor/nach dem Funktionsaufruf erledigen. Und dann wiederum kannst du spi_transfer() auch für weitere SPI Teilnehmer nutzen und einfach immer entsprechend das zugehörige CS nutzen :-) Klar, das setzt natürlich in der aktuellen Form erstmal voraus, dass deine anderen SPI Teilnehmer den selben SPI Modus auch unterstützen.

Des Weiteren:
  • In maxRTD_read_MSB und maxRTD_read_LSB reicht eine Länge von 2 für buf.
  • Denk mehr dynamisch! Warum willst du trans_send() auf das Senden von lediglich zwei Bytes beschränken? Klar jetzt reicht dir das aus aber vielleicht hast du irgendwann mal andere Anforderungen? Du solltest es mittlerweile mit Arrays/Pointern selber hinbekommen, die Funktion dynamisch zu gestalten ;-)
Viele Grüße
Nico

Re: Temperaturmessung mit PT100 und MAX31865

#60

von emy » 29. Apr 2019, 11:45

Ich habe das Programm jetzt ein wenig umgeschrieben, damit die Daten dem Transceiver übergeben werden. Vielleicht magst du da noch einmal kurz drüber gucken. Die Temperaturmessung funktioniert auch damit einwandfrei (ganzzahlige Werte reichen aus).

Zum Auslesen des MAX31865 und zum anschließenden Senden an den Transceiver, lese ich MSB und LSB einzeln aus mit:

Code: Alles auswählen

//  MSB Register auslesen
    uint8_t maxRTD_read_MSB(void)
    {
        uint8_t buf[3];
        
        buf[0] = 0x01;  // Lese-Adresse des MSB-Registers
        buf[1] = 0x00;  // nicht zwingend notwendig aber sauberer zum Messen
          
        spi_transfer(buf, 2);   // Schreiben und gleichzeitiges Auslesen
        
        return (buf[1]);    // 8 Bit (MSB) Register als Rückgabewert
    }

// LSB Register auslesen
      uint8_t maxRTD_read_LSB(void)
    {
        uint8_t buf[3];
        
        buf[0] = 0x02;  // Lese-Adresse des MSB-Registers
        buf[1] = 0x00;  // nicht zwingend notwendig aber sauberer zum Messen
          
        spi_transfer(buf, 2);   // Schreiben und gleichzeitiges Auslesen
        
        return (buf[1]);    // 8 Bit (LSB) Register als Rückgabewert
    }
Die Funktion für die Schnittstelle mit dem Transceiver ist gleich der für den MAX31865:

Code: Alles auswählen

void spi_transceiver (uint8_t *tBuf, uint8_t len)  // *pBuf = Pointer
    {
        int8_t t;   // Laufvariable
        
        SCLK = 0;
        CS_TRANS = 0; // 0 oder 1?
        
        if(tBuf == 0) return;
        
        while(len) {    // len = Anzahl zu übertragenden Bytes
            for (t=7; t>=0; t--) {  // Durchlauf von i=0 bis i=7
                __delay32(100); // Wartezeit
                SCLK ^= 1;
                
                // Schreiben
                SDO = ((*tBuf) & (1<<t));   // bitweise *pBuf auf 1 prüfen, dann SDO setzen 
                __delay32(100); 
                SCLK ^= 1;
                
//                // Einlesen
//                if (SDI) {
//                    *tBuf |= (1<<t);    // bitweises ODER: setzt i-tes Bit, auf das pBuf zeigt
//                }
//                else {
//                    *tBuf &= ~(1<<t);   // Löschung des i-ten Bits, auf das pBuf zeigt
//                }
                
            }
            tBuf++;
            len--;
        }
        __delay32(100);
        CS_TRANS = 1; // 0 oder 1?
    }
Für den Transceiver und dem MAX31865 nutze ich die gleichen Leitungen für Clock, SDO und SDI. CS ist natürlich verschieden.

Für das Senden an den Transceiver nutze ich:

Code: Alles auswählen

void trans_send (uint8_t MSB_data_max, uint8_t LSB_data_max)
    {
        uint8_t buf[3];
        
        buf[0] = 0x66; // FW Command
        buf[1] = MSB_data_max;
        buf[2] = LSB_data_max;
        
        spi_transceiver (buf, 3);  
    }
Und in der main-Funktion wird das dann so verwendet:

Code: Alles auswählen

MSB_data = maxRTD_read_MSB();
LSB_data = maxRTD_read_LSB();
trans_send(MSB_data, LSB_data); 

Am Empfänger soll dann erst das Ergebnis um einen nach rechts geshiftet werden und die Temperatur berechnet werden.

Re: Temperaturmessung mit PT100 und MAX31865

#59

von emy » 27. Apr 2019, 11:46

Aber dann schreib bitte auch noch einmal für alle anderen, die hier irgendwann mal lesen, was denn jetzt noch an Fehlern vorlag ;-)
ich hatte leider einen Kurzschluss genau unterhalb des Chips. Dieser hat eine Groundplane, die sich mit einem Pin verbunden hatte...
vielleicht hilft dieser Link weiter. Seite 6
Danke! Das wird jetzt meine Wochenendlektüre :)

Re: Temperaturmessung mit PT100 und MAX31865

#58

von pic18 » 27. Apr 2019, 10:52

vielleicht hilft dieser Link weiter. Seite 6
http://d1.amobbs.com/bbs_upload782111/f ... UMAFBO.pdf

Re: Temperaturmessung mit PT100 und MAX31865

#57

von Nico » 27. Apr 2019, 10:41

emy hat geschrieben:
27. Apr 2019, 10:05
Alle Probleme behoben und was soll ich sagen, es funktioniert endlich :) :) :)
Vielen Dank, dass du so geduldig warst und immer eine Ferndiagnose gestellt hast!
Freut mich. Aber dann schreib bitte auch noch einmal für alle anderen, die hier irgendwann mal lesen, was denn jetzt noch an Fehlern vorlag ;-)

Re: Temperaturmessung mit PT100 und MAX31865

#56

von emy » 27. Apr 2019, 10:05

Alle Probleme behoben und was soll ich sagen, es funktioniert endlich :) :) :)
Vielen Dank, dass du so geduldig warst und immer eine Ferndiagnose gestellt hast!

Ich werde, wie du auch vorgeschlagen hast, den ADC Code an den Transceiver übergeben, um dann später am Empfänger die Temperatur zu bestimmen. Dafür soll der Si4467 als Transceiver genutzt werden. Weißt du, ob der Transceiver automatisch im Sende- oder Empfangsmodus ist, wenn der jeweile Pin angesprchen wird? Und weist du was mit dem "FW Command" gemeint ist (siehe Bild)?
Dateianhänge
transspi.jpg

Re: Temperaturmessung mit PT100 und MAX31865

#55

von emy » 24. Apr 2019, 15:15

Es gibt tatsächlich ein Problem mit dem Sensor. Ich habe die Spannungsversorgung und die PT100 Anschlüsse in der gleichen Schraubklemme. Wenn keine Spannung anliegt, messe ich, wie du schon gesagt hast, 110 Ohm. Sobald Spannung anliegt, sind es nur noch 52 Ohm. Ich befürchte jetzt, dass etwas beim Löten schief gegangen ist. Ich werde das alles nochmal genau kontrollieren.

Re: Temperaturmessung mit PT100 und MAX31865

#54

von Nico » 24. Apr 2019, 14:05

Ich würde ganz im Gegenteil sagen, das passt so, denn:
  • Einen Wert von 0x0000 als Default Low Threshold hätte ich auch erwartet. Genauso 0xFFFF als High Threshold. Wenn man andere Grenzen möchte, muss man es halt einstellen. Insofern passen diese Werte.
  • Die zurück gelesene 0xC0 aus dem Config Register macht ebenfalls Sinn, denn siehe:
    The fault status clear bit D1, self-clears to 0.
Zu deinem angehängten Bild: SDI liegt wohl eher auf Kanal 4 und SDO auf Kanal 3, oder war das jetzt aus Sicht des PIC? Okay also du hast jetzt den SPI Mode gewechselt. Die Übertragung sieht für mich fehlerfrei aus. Jetzt muss also (nur) noch der Grund gefunden werden, weshalb keine vernünftige Messung zustande kommt.

Als nächstes würde ich den Sensor einfach mal mit einem Ohmmeter messen. Bei Raumtemperatur sollte der Wert irgendwo bei ~110 Ohm liegen.

Wenn mit dem was nicht stimmt, kann man auch einfach mal einen Festwiderstand anklemmen um ein Problem mir dem Sensor auszuschließen.

Re: Temperaturmessung mit PT100 und MAX31865

#53

von emy » 24. Apr 2019, 13:33

Oh ja das Bild habe ich vergessen.

beim Auslesen von 2 Bytes beginnend mit 0x05 erhalte ich wieder nur Nullen …. spaßeshalber von 0x03 und 0x04 nur Einsen.

Beim Auslesen des Konfigurationsregisters 0x00 erhalte ich statt 0xC2 leider nur 0xC0. Also irgendetwas stimmt da noch nicht so ganz.
Dateianhänge
aktuell.jpg

Re: Temperaturmessung mit PT100 und MAX31865

#52

von Nico » 24. Apr 2019, 12:52

Jawoll, sieht also so aus, als wäre der RTD Wert unterhalb der RTD Low Threshold gefallen. Dann ließ doch mal diese eingestellte Grenze aus (Register 0x05 + 0x06) :-)

PS: Du hast wohl vergessen die neue Messung anzuhängen?!

Re: Temperaturmessung mit PT100 und MAX31865

#51

von emy » 24. Apr 2019, 12:37

Ich hab jetzt das Fault Status Register ausgelesen mit 0x07 als Adresse. Wenn ich da buf[1] auslese, ergibt sich 01000000.

Code: Alles auswählen

uint8_t maxRTD_read_res(void)
    {
        uint8_t buf[3];
        
        buf[0] = 0x07;
        buf[1] = 0x00;
        buf[2] = 0x00;
        
        spi_transfer(buf, 3);
        
//        return ((buf[1] << 8) | buf[2]);
        return (buf[1]);
    }
    

Re: Temperaturmessung mit PT100 und MAX31865

#50

von emy » 24. Apr 2019, 12:18

Spannungsversorgung passt. Das Bild ist nun der aktuelle Stand:
  • Kanal 0: Chip Select
  • Kanal 1: Clock
  • Kanal 3: SDI
  • Kanal 4: SDO
  • Kanal 6: DRDY
Mit:

Code: Alles auswählen

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    
    uint16_t adccode;
    int i = 0;
    double temp;
    
    maxRTD_set_config();

    while (1)
    {
//        maxRTD_set_config();
        while(DRDY);
        adccode = maxRTD_read_res();
        
        i++;
        
        temp = (double) (adccode / 32.0) - 256;
    }

    return 1;
}
Nun ist das Ergebnis aus MSB und LSB 00000000 00000001, also ist das Fault Bit gesetzt. Demnach macht er ja jetzt etwas. Immerhin ...

Re: Temperaturmessung mit PT100 und MAX31865

#49

von Nico » 24. Apr 2019, 07:19

Mir fehlt in dem Shop (dein Link zum Sensor) die Angabe, welchen Typ ich da tatsächlich ausgewählt habe. Dort steht zwar:
Temperatursensor Frei wählbar in obenstehender Auswahlliste: PT100, PT1000, PT500, Ni1000
Aber ein Auswahlfeld dafür habe ich nicht gefunden. Naja wie dem auch sei. Da du die RTD und FORCE Leitungen offenbar direkt auf der Platine miteinander verbindest, arbeitest du wohl im 2-Leiter Modus. Dementsprechend sollten deine Leitungen zum Messwiderstand möglichst kurz sein! Besser wäre es natürlich, die FORCE Leitungen als zusätzliches Adernpaar so weit wie möglich bis zum Sensor zu führen. Aber das wird hier nicht dein Problem sein.

Mich wundert vielmehr, dass der MAX offenbar so gar kein Lebenszeichen von sich gibt (siehe dauerhaftes low auf SDI bzw. Kanal 3 auf deinen Messungen). Ich würde zumindest erwarten, dass er beim Auslesen einer Messung (selbst wenn er mit DRDY kein neues signalisiert) das Fault Bit setzt, da ja offenbar irgendwas nicht passt.

Du hast ja noch ein paar Kanäle frei, leg doch DRDY auch mal mit auf. Und ich würde mal die Spannungsversorgung des MAX überprüfen.

Gruß Nico

Re: Temperaturmessung mit PT100 und MAX31865

#48

von emy » 23. Apr 2019, 20:52

Stimmt, das hatte ich nicht mehr vor Augen.
So wie der Code aktuell ist, machen CS, Clock und SDO genau das, was sie sollen. Ich habe schon überlegt, ob ich den MAX31... einmal auswechseln soll, da er durch die unzähligen Versuche schon ein bisschen was aushalten musste. Das Löten war auch nicht ganz einfach, vielleicht hat er da etwas abbekommen.

Oder könnte es doch an dem PT100 liegen, den ich verwende?

Re: Temperaturmessung mit PT100 und MAX31865

#47

von Nico » 23. Apr 2019, 14:57

Dann sind lediglich Chip Select und Clock durchgehend auf 1, der Rest 0.
Das legt also nahe, dass DRDY offenbar nie auf low zu gehen scheint, sprich der MAX keine neuen Messergebnisse generiert.
Mir ist jetzt aufgefallen, dass jedes Bit mit einer fallenden Flanke von Clock zeitgleich angezeigt wurde, da nach Abbildung 7 des Datenblatts ein Bit mit jeder positiven Flanke von Clock gesendet wird, habe ich das jetzt noch einmal umgedreht.
Das ist genau was ich zuvor schon mal angesprochen habe. Der Chip unterstützt die SPI Modi 1 (CPOL=0, CPHA=1) und 3 (CPOL=1, CPHA=1), auf der folgenden Grafik sehr schön zu sehen:

Bild
Quelle: https://www.corelis.com/education/tutor ... -tutorial/

Welcher Mode aktiv ist, detektiert der Chip indem er den Pegel vom Clock misst, kurz nachdem du Chip Select aktivierst. Dies ist dann der idle Zustand des Clocks (also CPOL=0 beim SPI Mode 1 oder CPOL=1 beim Mode 3). Die spi_transfer die ich so vorgeschlagen habe, arbeitet im Mode 3.
Mir ist auch aufgefallen, dass die positive Flanke von Clock und das Bit auf SDO um ca 8us versetzt ist (Clock ist 8us vor SDO), kann das auch schon zu Fehlern führen?
Hier auch wieder der Verweis auf die Abbildung (siehe oben). Ich spreche weiterhin vom SPI Mode 3: Bei fallender Taktflanke schreibt der Master den Zustand auf SDO, der bei der folgenden steigenden Flanke stabil ist und dann vom Slave eingelesen wird.

Nach oben