adafruit / Adafruit_MAX31865

Arduino Library for Adafruit MAX31865 RTD Sensor
77 stars 80 forks source link

Problem with more than 3 thermo.begin(MAX31865_2WIRE) function #45

Open festobit opened 8 months ago

festobit commented 8 months ago

In the original Adafruit_MAX31865 library, the library works well with a single MAX31865. I am trying to read up to 10 MAX31865 using an Arduino Mega, however, at the setup thermo.begin(MAX31865_2WIRE); allows modification of the bool line only up to three, any modification after the third returns a null value for the MAX31865. Have tried the multiple sensor code by @sylvanoMTL and others but there is still no reading after the third modification.

Can you provide a working library with example for reading multiple MAX31865 sensors of up to 10 with an arduino sketch. It is my belief that the arduino.h code is limited somehow to just three instances preventing additional instances.

I have attached a sample code for 5 MAX31865 to aid troubleshooting. Note: when thermo3.begin(MAX31865_2WIRE); and thermo4.begin(MAX31865_2WIRE); are commented out, I get stable readings from the MAX31865 for the first three, however when they are uncommented, only the first gives a reading, while the others is driven to the 5V HIGH.

I have commented out all others and was able to find that the problem is from the setup function and it has something to do with the bool begin function as explained above.

/*** This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865

Designed specifically to work with the Adafruit RTD Sensor ----> https://www.adafruit.com/products/3328

This sensor uses SPI to communicate, 4 pins are required to
interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution ****/

include

// Use software SPI: CS, DI, DO, CLK 54213 // for uno and nano SPI pins are 11(DI), 12(DO), 13(CLK) // for mega the SPI pins are: 51(DI), 50(DO), 52(CLK) /Adafruit_MAX31865 thermo = Adafruit_MAX31865(46,51,50,52); // for 1st max31865 Adafruit_MAX31865 thermo1 = Adafruit_MAX31865(44,51,50,52); //for 2nd max31865, only CS is changing Adafruit_MAX31865 thermo2 = Adafruit_MAX31865(42,51,50,52); //for 3rd max31865, only CS is changing Adafruit_MAX31865 thermo3 = Adafruit_MAX31865(40,51,50,52); //for 4th max31865, only CS is changing Adafruit_MAX31865 thermo4 = Adafruit_MAX31865(38,51,50,52); //for 5th max31865, only CS is changing /

// use hardware SPI, just pass in the CS pin Adafruit_MAX31865 thermo = Adafruit_MAX31865(46); Adafruit_MAX31865 thermo1 = Adafruit_MAX31865(44); Adafruit_MAX31865 thermo2 = Adafruit_MAX31865(42); Adafruit_MAX31865 thermo3 = Adafruit_MAX31865(40); Adafruit_MAX31865 thermo4 = Adafruit_MAX31865(38);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000

define RREF 430.0

// The 'nominal' 0-degrees-C resistance of the sensor // 100.0 for PT100, 1000.0 for PT1000

define RNOMINAL 100.0

float ratio, ratio1, ratio2, ratio3, ratio4;

void setup() { Serial.begin(115200); Serial.println("Adafruit MAX31865 PT100 Sensor Test!");

thermo.begin(MAX31865_2WIRE); //delay(50);// set to 2WIRE or 4WIRE as necessary thermo1.begin(MAX31865_2WIRE); //delay(50); // set to 2WIRE or 4WIRE thermo2.begin(MAX31865_2WIRE); //delay(150);// set to 2WIRE or 4WIRE thermo3.begin(MAX31865_2WIRE); //delay(150);// set to 2WIRE or 4WIRE thermo4.begin(MAX31865_2WIRE); //delay(150);

}

void loop() { uint16_t rtd = thermo.readRTD(); //delay(50); uint16_t rtd1 = thermo1.readRTD(); //delay (50); uint16_t rtd2 = thermo2.readRTD(); //delay (50); uint16_t rtd3 = thermo3.readRTD(); uint16_t rtd4 = thermo4.readRTD();

Serial.print("RTD value 1: "); Serial.println(rtd); Serial.print("RTD value 2: "); Serial.println(rtd1); Serial.print("RTD value 3: "); Serial.println(rtd2); Serial.print("RTD value 4: "); Serial.println(rtd3); Serial.print("RTD value 5: "); Serial.println(rtd4);

ratio = rtd; ratio1 = rtd1; ratio2 = rtd2; ratio3 = rtd3; ratio4 = rtd4;

ratio /= 32768; ratio1 /= 32768; ratio2 /= 32768; ratio3 /= 32768; ratio4 /= 32768;

Serial.print("Ratio 1 = "); Serial.println(ratio,8); Serial.print("Resistance 1 = "); Serial.println(RREFratio,8); Serial.print("Ratio 2 = "); Serial.println(ratio1,8); Serial.print("Resistance 3 = "); Serial.println(RREFratio1,8); Serial.print("Ratio 4 = "); Serial.println(ratio2,8); Serial.print("Resistance 4 = "); Serial.println(RREFratio2,8); Serial.print("Ratio 5 = "); Serial.println(ratio3,8); Serial.print("Resistance 5 = "); Serial.println(RREFratio3,8); Serial.print("Ratio 5 = "); Serial.println(ratio4,8); Serial.print("Resistance 5 = "); Serial.println(RREF*ratio4,8);

Serial.print("Temperature 1 = "); Serial.println(thermo.temperature(RNOMINAL, RREF)); Serial.print("Temperature 2 = "); Serial.println(thermo1.temperature(RNOMINAL, RREF)); Serial.print("Temperature 3 = "); Serial.println(thermo2.temperature(RNOMINAL, RREF)); Serial.print("Temperature 4 = "); Serial.println(thermo3.temperature(RNOMINAL, RREF)); Serial.print("Temperature 5 = "); Serial.println(thermo4.temperature(RNOMINAL, RREF)); //*/ // Check and print any faults uint8_t fault = thermo.readFault(); uint8_t fault1 = thermo1.readFault(); uint8_t fault2 = thermo2.readFault(); uint8_t fault3 = thermo3.readFault(); uint8_t fault4 = thermo4.readFault();

if (fault) { Serial.print("Fault 0x"); Serial.println(fault, HEX); if (fault & MAX31865_FAULT_HIGHTHRESH) { Serial.println("RTD High Threshold"); } if (fault & MAX31865_FAULT_LOWTHRESH) { Serial.println("RTD Low Threshold"); } if (fault & MAX31865_FAULT_REFINLOW) { Serial.println("REFIN- > 0.85 x Bias"); } if (fault & MAX31865_FAULT_REFINHIGH) { Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); } if (fault & MAX31865_FAULT_RTDINLOW) { Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); } if (fault & MAX31865_FAULT_OVUV) { Serial.println("Under/Over voltage"); } thermo.clearFault(); thermo1.clearFault(); thermo2.clearFault(); thermo3.clearFault(); thermo4.clearFault(); } Serial.println(); delay(1000); }

sylvanoMTL commented 8 months ago

HI, based on my library, here is a code snippet: based on a working code, but I have removed some of parts that are not needed. It is using a mix of 3 wires and 4 wires PT100. you can activate 3 different modes, depending on the accuracy (self-heating when you are using continuous mode) . I recommend the asynchronous mode, but you may want to use also a higher spec chip such as the LTC2986. I have a library I will post at some point for that chip.

I don't have access anymore to the MAX31865 so I cannot test the things below, you might do some minor corrections. Hope this help. (don't forget to uncomment the #define SERIAL_OUTPUT and #SERIAL_DEBUG


#include <Arduino.h>
#include <Adafruit_MAX31865.h>

//#define ONE_SHOT_MODE //Allow to read all rtds in t = 76ms x n rtds
//#define ASYNCHRONOUS_MODE //Allow to read all RTDs within 76ms
#define CONTINUOUS_MODE   //  conversion rate = 20ms per RTDs, but will cause self-heating 

#define FILTER_50HZ

//#define SERIAL_DEBUG //Serial would block the program on arduino micro, until the serial is available
//#define SERIAL_OUTPUT

#define THERMO_0_CS_PIN 9  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 10 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 11 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 12 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
#define THERMO_4_CS_PIN 5  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_6_CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires

const byte thermo_arrayLen = 8;
Adafruit_MAX31865 thermo_array[thermo_arrayLen] ={  
                                      Adafruit_MAX31865(THERMO_0_CS_PIN),
                                      Adafruit_MAX31865(THERMO_1_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_2_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_3_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_4_CS_PIN),
                                      Adafruit_MAX31865(THERMO_5_CS_PIN),
                                      Adafruit_MAX31865(THERMO_6_CS_PIN),
                                      Adafruit_MAX31865(THERMO_7_CS_PIN)};

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

uint16_t rtd[thermo_arrayLen];
bool condition[thermo_arrayLen]={0};
bool condition_temp[thermo_arrayLen]={0};
float temperature[thermo_arrayLen];

float time0; //for loop timing
long delta_t = 0; //for loop timing

//--------------- prototypes -------------
void getRTDStemp(void);
void getRTDtemp(byte rtd_id);
void getFault(byte rtd_id);

void setup() {
  #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)  
    Serial.begin(9600);
    #if defined(SERIAL_DEBUG)
      while(!Serial); // ! This is block the programm for debugging purpose
    #endif
    Serial.println("Start...");
  #endif

  //configure the RTDs
  thermo_array[0].begin(MAX31865_4WIRE);
  thermo_array[1].begin(MAX31865_4WIRE);
  thermo_array[2].begin(MAX31865_4WIRE);
  thermo_array[3].begin(MAX31865_4WIRE);
  thermo_array[4].begin(MAX31865_3WIRE);  //Air RTD 3-wires
  thermo_array[5].begin(MAX31865_4WIRE);  //Air RTD 4-wires
    thermo_array[6].begin(MAX31865_3WIRE); //alternative RTD 4-wires
    thermo_array[7].begin(MAX31865_4WIRE); //alternative RTD 4-wires

  #ifdef FILTER_50HZ
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].enable50Hz(true);
    }
  #endif

  #ifdef CONTINUOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].autoConvert(true);
          delay(20); //Note 5 
      thermo_array[i].enableBias(true); //must be enabled for continuous measurements
           delay(10); //Note 4
    }
  #endif
}

void loop() {
  #ifdef ONE_SHOT_MODE
    //ORIGINAL COMPUTATION
      float temperature = thermo_array[i].temperature(RNOMINAL,RREF);
      }
     #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print(temperature,4);Serial.print("\t");
    #endif   

    #ifdef SERIAL_DEBUG
      //timer for debug
      delta_t = millis()-time0;
      Serial.print("loop time:");Serial.println(delta_t);
      time0=millis();
     #endif
  #endif

  #ifdef ASYNCHRONOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
        condition[i]=thermo_array[i].readRTDAsync(rtd[i]);
        if(condition[i]) { //to be replaced by if(thermo_array[i].readRTDAsync(rtd[i])){}
          //Serial.print("THERMO ");Serial.print(i);Serial.println(" ready ");

          temperature[i]=thermo_array[i].temperatureAsync(rtd[i],RNOMINAL,RREF);

          }
             #ifdef SERIAL_DEBUG
              //timer for debug
              delta_t = millis()-time0;
              time0=millis();
            #endif
        }

        #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
          Serial.print(temperature[i],4);Serial.print("\t");
        #endif  

    #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print("loop time:");Serial.println(delta_t);
      Serial.println();
    #endif 
  #endif

  #ifdef CONTINUOUS_MODE
      temperature[i] = thermo_array[i].temperature(RNOMINAL,RREF);
      #ifdef SERIAL_DEBUG
        if(temperature[i]>900){Serial.print(0,4);Serial.print("\t");}
        else{Serial.print(temperature[i],4);Serial.print("\t");}
      #endif
    #ifdef SERIAL_DEBUG
      delta_t = millis()-time0;
      time0=millis();    
      //Serial.print("loop time:");
      Serial.println(delta_t);
    #endif
  #endif
festobit commented 8 months ago

Thanks for your response, but can you adjust the code to 2WIRES rather than 4WIRES and 3WIRES or just include a line for 2WIRES. But I think I can reset that at configure RTD end.

However, I dont understand the need for this section you included:

#define THERMO_0_CS_PIN 9  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 10 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 11 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 12 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
#define THERMO_4_CS_PIN 5  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_6_CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires

Are these predefined to the different wiring types? And by adjusting the configure RTD section, can these settings be overwritten?

festobit commented 8 months ago

HI, based on my library, here is a code snippet: based on a working code, but I have removed some of parts that are not needed. It is using a mix of 3 wires and 4 wires PT100. you can activate 3 different modes, depending on the accuracy (self-heating when you are using continuous mode) . I recommend the asynchronous mode, but you may want to use also a higher spec chip such as the LTC2986. I have a library I will post at some point for that chip.

I don't have access anymore to the MAX31865 so I cannot test the things below, you might do some minor corrections. Hope this help. (don't forget to uncomment the #define SERIAL_OUTPUT and #SERIAL_DEBUG


#include <Arduino.h>
#include <Adafruit_MAX31865.h>

//#define ONE_SHOT_MODE //Allow to read all rtds in t = 76ms x n rtds
//#define ASYNCHRONOUS_MODE //Allow to read all RTDs within 76ms
#define CONTINUOUS_MODE   //  conversion rate = 20ms per RTDs, but will cause self-heating 

#define FILTER_50HZ

//#define SERIAL_DEBUG //Serial would block the program on arduino micro, until the serial is available
//#define SERIAL_OUTPUT

#define THERMO_0_CS_PIN 9  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 10 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 11 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 12 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
#define THERMO_4_CS_PIN 5  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_6_CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires

const byte thermo_arrayLen = 8;
Adafruit_MAX31865 thermo_array[thermo_arrayLen] ={  
                                      Adafruit_MAX31865(THERMO_0_CS_PIN),
                                      Adafruit_MAX31865(THERMO_1_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_2_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_3_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_4_CS_PIN),
                                      Adafruit_MAX31865(THERMO_5_CS_PIN),
                                      Adafruit_MAX31865(THERMO_6_CS_PIN),
                                      Adafruit_MAX31865(THERMO_7_CS_PIN)};

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

uint16_t rtd[thermo_arrayLen];
bool condition[thermo_arrayLen]={0};
bool condition_temp[thermo_arrayLen]={0};
float temperature[thermo_arrayLen];

float time0; //for loop timing
long delta_t = 0; //for loop timing

//--------------- prototypes -------------
void getRTDStemp(void);
void getRTDtemp(byte rtd_id);
void getFault(byte rtd_id);

void setup() {
  #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)  
    Serial.begin(9600);
    #if defined(SERIAL_DEBUG)
      while(!Serial); // ! This is block the programm for debugging purpose
    #endif
    Serial.println("Start...");
  #endif

  //configure the RTDs
  thermo_array[0].begin(MAX31865_4WIRE);
  thermo_array[1].begin(MAX31865_4WIRE);
  thermo_array[2].begin(MAX31865_4WIRE);
  thermo_array[3].begin(MAX31865_4WIRE);
  thermo_array[4].begin(MAX31865_3WIRE);  //Air RTD 3-wires
  thermo_array[5].begin(MAX31865_4WIRE);  //Air RTD 4-wires
    thermo_array[6].begin(MAX31865_3WIRE); //alternative RTD 4-wires
    thermo_array[7].begin(MAX31865_4WIRE); //alternative RTD 4-wires

  #ifdef FILTER_50HZ
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].enable50Hz(true);
    }
  #endif

  #ifdef CONTINUOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].autoConvert(true);
          delay(20); //Note 5 
      thermo_array[i].enableBias(true); //must be enabled for continuous measurements
           delay(10); //Note 4
    }
  #endif
}

void loop() {
  #ifdef ONE_SHOT_MODE
    //ORIGINAL COMPUTATION
      float temperature = thermo_array[i].temperature(RNOMINAL,RREF);
      }
     #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print(temperature,4);Serial.print("\t");
    #endif   

    #ifdef SERIAL_DEBUG
      //timer for debug
      delta_t = millis()-time0;
      Serial.print("loop time:");Serial.println(delta_t);
      time0=millis();
     #endif
  #endif

  #ifdef ASYNCHRONOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
        condition[i]=thermo_array[i].readRTDAsync(rtd[i]);
        if(condition[i]) { //to be replaced by if(thermo_array[i].readRTDAsync(rtd[i])){}
          //Serial.print("THERMO ");Serial.print(i);Serial.println(" ready ");

          temperature[i]=thermo_array[i].temperatureAsync(rtd[i],RNOMINAL,RREF);

          }
             #ifdef SERIAL_DEBUG
              //timer for debug
              delta_t = millis()-time0;
              time0=millis();
            #endif
        }

        #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
          Serial.print(temperature[i],4);Serial.print("\t");
        #endif  

    #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print("loop time:");Serial.println(delta_t);
      Serial.println();
    #endif 
  #endif

  #ifdef CONTINUOUS_MODE
      temperature[i] = thermo_array[i].temperature(RNOMINAL,RREF);
      #ifdef SERIAL_DEBUG
        if(temperature[i]>900){Serial.print(0,4);Serial.print("\t");}
        else{Serial.print(temperature[i],4);Serial.print("\t");}
      #endif
    #ifdef SERIAL_DEBUG
      delta_t = millis()-time0;
      time0=millis();    
      //Serial.print("loop time:");
      Serial.println(delta_t);
    #endif
  #endif

Please recheck the code, it appears you have deleted some vital codes and notations. There are syntax errors such as:
temperature[i] = thermo_array[i].temperature(RNOMINAL,RREF); i is not defined

#ifdef ONE_SHOT_MODE //ORIGINAL COMPUTATION float temperature = thermo_array[i].temperature(RNOMINAL,RREF); } missing an opening tag.

void loop closing tag is also missing

festobit commented 8 months ago

From the serial monitor using the Asynchronous mode, I am getting readings but it is difficult to be sure if the readings are for the different thermocouples or the same

` 33.2200 loop time:0

33.2200 loop time:1

33.2200 loop time:0

33.2200 loop time:2

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2539 loop time:1

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:1

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2200 loop time:1

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2200 loop time:0

33.2539 loop time:0

33.2539 loop time:1

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

33.2539 loop time:0

`

sylvanoMTL commented 8 months ago

I have not much time to go through it. Typically the asynchronous mode is a state machine.

first you define your wiring config. you can see mine.

in the setup:

//configure the RTDs
  thermo_array[0].begin(MAX31865_4WIRE);
  thermo_array[1].begin(MAX31865_4WIRE);
  thermo_array[2].begin(MAX31865_4WIRE);
  thermo_array[3].begin(MAX31865_4WIRE);
  thermo_array[4].begin(MAX31865_3WIRE);  //Air RTD 3-wires
  thermo_array[5].begin(MAX31865_4WIRE);  //Air RTD 4-wires
    thermo_array[6].begin(MAX31865_3WIRE); //alternative RTD 4-wires
    thermo_array[7].begin(MAX31865_4WIRE); //alternative RTD 4-wires`

change everything from MAX31865_4WIRE to MAX31865_2WIRE

in the loop, using the asynchronous mode, you need to have the Serial output in the FOR loop. this is where the variable i is defined

Sorry while erasing some code, I may have removed some {, but I let you correct me. If you could post your modifications, this would help the community.

Thanks for your response, but can you adjust the code to 2WIRES rather than 4WIRES and 3WIRES or just include a line for 2WIRES. But I think I can reset that at configure RTD end.

However, I dont understand the need for this section you included:

#define THERMO_0_CS_PIN 9  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 10 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 11 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 12 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
#define THERMO_4_CS_PIN 5  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_6_CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires

Are these predefined to the different wiring types? And by adjusting the configure RTD section, can these settings be overwritten?

festobit commented 8 months ago

HI, based on my library, here is a code snippet: based on a working code, but I have removed some of parts that are not needed. It is using a mix of 3 wires and 4 wires PT100. you can activate 3 different modes, depending on the accuracy (self-heating when you are using continuous mode) . I recommend the asynchronous mode, but you may want to use also a higher spec chip such as the LTC2986. I have a library I will post at some point for that chip.

I don't have access anymore to the MAX31865 so I cannot test the things below, you might do some minor corrections. Hope this help. (don't forget to uncomment the #define SERIAL_OUTPUT and #SERIAL_DEBUG


#include <Arduino.h>
#include <Adafruit_MAX31865.h>

//#define ONE_SHOT_MODE //Allow to read all rtds in t = 76ms x n rtds
//#define ASYNCHRONOUS_MODE //Allow to read all RTDs within 76ms
#define CONTINUOUS_MODE   //  conversion rate = 20ms per RTDs, but will cause self-heating 

#define FILTER_50HZ

//#define SERIAL_DEBUG //Serial would block the program on arduino micro, until the serial is available
//#define SERIAL_OUTPUT

#define THERMO_0_CS_PIN 9  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 10 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 11 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 12 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
#define THERMO_4_CS_PIN 5  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_6_CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires

const byte thermo_arrayLen = 8;
Adafruit_MAX31865 thermo_array[thermo_arrayLen] ={  
                                      Adafruit_MAX31865(THERMO_0_CS_PIN),
                                      Adafruit_MAX31865(THERMO_1_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_2_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_3_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_4_CS_PIN),
                                      Adafruit_MAX31865(THERMO_5_CS_PIN),
                                      Adafruit_MAX31865(THERMO_6_CS_PIN),
                                      Adafruit_MAX31865(THERMO_7_CS_PIN)};

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

uint16_t rtd[thermo_arrayLen];
bool condition[thermo_arrayLen]={0};
bool condition_temp[thermo_arrayLen]={0};
float temperature[thermo_arrayLen];

float time0; //for loop timing
long delta_t = 0; //for loop timing

//--------------- prototypes -------------
void getRTDStemp(void);
void getRTDtemp(byte rtd_id);
void getFault(byte rtd_id);

void setup() {
  #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)  
    Serial.begin(9600);
    #if defined(SERIAL_DEBUG)
      while(!Serial); // ! This is block the programm for debugging purpose
    #endif
    Serial.println("Start...");
  #endif

  //configure the RTDs
  thermo_array[0].begin(MAX31865_4WIRE);
  thermo_array[1].begin(MAX31865_4WIRE);
  thermo_array[2].begin(MAX31865_4WIRE);
  thermo_array[3].begin(MAX31865_4WIRE);
  thermo_array[4].begin(MAX31865_3WIRE);  //Air RTD 3-wires
  thermo_array[5].begin(MAX31865_4WIRE);  //Air RTD 4-wires
    thermo_array[6].begin(MAX31865_3WIRE); //alternative RTD 4-wires
    thermo_array[7].begin(MAX31865_4WIRE); //alternative RTD 4-wires

  #ifdef FILTER_50HZ
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].enable50Hz(true);
    }
  #endif

  #ifdef CONTINUOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].autoConvert(true);
          delay(20); //Note 5 
      thermo_array[i].enableBias(true); //must be enabled for continuous measurements
           delay(10); //Note 4
    }
  #endif
}

void loop() {
  #ifdef ONE_SHOT_MODE
    //ORIGINAL COMPUTATION
      float temperature = thermo_array[i].temperature(RNOMINAL,RREF);
      }
     #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print(temperature,4);Serial.print("\t");
    #endif   

    #ifdef SERIAL_DEBUG
      //timer for debug
      delta_t = millis()-time0;
      Serial.print("loop time:");Serial.println(delta_t);
      time0=millis();
     #endif
  #endif

  #ifdef ASYNCHRONOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
        condition[i]=thermo_array[i].readRTDAsync(rtd[i]);
        if(condition[i]) { //to be replaced by if(thermo_array[i].readRTDAsync(rtd[i])){}
          //Serial.print("THERMO ");Serial.print(i);Serial.println(" ready ");

          temperature[i]=thermo_array[i].temperatureAsync(rtd[i],RNOMINAL,RREF);

          }
             #ifdef SERIAL_DEBUG
              //timer for debug
              delta_t = millis()-time0;
              time0=millis();
            #endif
        }

        #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
          Serial.print(temperature[i],4);Serial.print("\t");
        #endif  

    #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print("loop time:");Serial.println(delta_t);
      Serial.println();
    #endif 
  #endif

  #ifdef CONTINUOUS_MODE
      temperature[i] = thermo_array[i].temperature(RNOMINAL,RREF);
      #ifdef SERIAL_DEBUG
        if(temperature[i]>900){Serial.print(0,4);Serial.print("\t");}
        else{Serial.print(temperature[i],4);Serial.print("\t");}
      #endif
    #ifdef SERIAL_DEBUG
      delta_t = millis()-time0;
      time0=millis();    
      //Serial.print("loop time:");
      Serial.println(delta_t);
    #endif
  #endif

Cleaned up your code but the MAX31865 still not responding other than the first two lines:

#include <Arduino.h>
#include <Adafruit_MAX31865.h>

//#define ONE_SHOT_MODE //Allow to read all rtds in t = 76ms x n rtds
//#define ASYNCHRONOUS_MODE //Allow to read all RTDs within 76ms
#define CONTINUOUS_MODE   //  conversion rate = 20ms per RTDs, but will cause self-heating 

#define FILTER_50HZ

#define SERIAL_DEBUG //Serial would block the program on arduino micro, until the serial is available
#define SERIAL_OUTPUT
byte i;

#define THERMO_0_CS_PIN 46  //TEC 1 RTD PT100: 4-wires
#define THERMO_1_CS_PIN 44 //LIQUID COLD PLATE 1 RTD PT100: 4-wires
#define THERMO_2_CS_PIN 40 //TEC 2 RTD PT100: 4-wires 
#define THERMO_3_CS_PIN 42 //LIQUID COLD PLATE 2 RTD PT100: 4-wires
/*
#define THERMO_4_CS_PIN 38  //AIR RTD FAN INLET RTD PT100: 3-wires
#define THERMO_5_CS_PIN 6  //AIR RTD COOLING AGGREGATE OUTLET RTD PT100: 4-wires

#define THERMO_64CS_PIN 7  //other: 3-wires 
#define THERMO_7_CS_PIN 8  //other: 4-wires
//*/

const byte thermo_arrayLen = 4;
Adafruit_MAX31865 thermo_array[thermo_arrayLen] ={  
                                      Adafruit_MAX31865(THERMO_0_CS_PIN),
                                      Adafruit_MAX31865(THERMO_1_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_2_CS_PIN), 
                                      Adafruit_MAX31865(THERMO_3_CS_PIN) 
                                      //Adafruit_MAX31865(THERMO_4_CS_PIN),
                                      //Adafruit_MAX31865(THERMO_5_CS_PIN),
                                      //Adafruit_MAX31865(THERMO_6_CS_PIN),
                                      //Adafruit_MAX31865(THERMO_7_CS_PIN)
                                      };

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

uint16_t rtd[thermo_arrayLen];
bool condition[thermo_arrayLen]={0};
bool condition_temp[thermo_arrayLen]={0};
float temperature[thermo_arrayLen];

float time0; //for loop timing
long delta_t = 0; //for loop timing

//--------------- prototypes -------------
void getRTDStemp(void);
void getRTDtemp(byte rtd_id);
void getFault(byte rtd_id);

void setup() {
  #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)  
    Serial.begin(9600);
    #if defined(SERIAL_DEBUG)
      while(!Serial); // ! This is block the programm for debugging purpose
    #endif
    Serial.println("Start...");
  #endif

  //configure the RTDs
  thermo_array[0].begin(MAX31865_2WIRE);
  thermo_array[1].begin(MAX31865_2WIRE);
  thermo_array[2].begin(MAX31865_2WIRE);
  thermo_array[3].begin(MAX31865_2WIRE);
  /*
  thermo_array[4].begin(MAX31865_2WIRE);  //Air RTD 3-wires
  thermo_array[5].begin(MAX31865_2WIRE);  //Air RTD 4-wires
    thermo_array[6].begin(MAX31865_2WIRE); //alternative RTD 4-wires
    thermo_array[7].begin(MAX31865_2WIRE); //alternative RTD 4-wires
//*/

  #ifdef FILTER_50HZ
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].enable50Hz(true);
    }
  #endif

  #ifdef CONTINUOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
      thermo_array[i].autoConvert(true);
          delay(20); //Note 5 
      thermo_array[i].enableBias(true); //must be enabled for continuous measurements
           delay(10); //Note 4
    }
  #endif
}

void loop() {
  #ifdef ONE_SHOT_MODE
    //ORIGINAL COMPUTATION
    for(byte i=0;i<thermo_arrayLen;i++){
      float temperature = thermo_array[i].temperature(RNOMINAL,RREF);
      }
     #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print(temperature,4);Serial.print("\t");
    #endif   

    #ifdef SERIAL_DEBUG
      //timer for debug
      delta_t = millis()-time0;
      Serial.print("loop time:");Serial.println(delta_t);
      time0=millis();
     #endif
  #endif

  #ifdef ASYNCHRONOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
        condition[i]=thermo_array[i].readRTDAsync(rtd[i]);
        if(condition[i]) { //to be replaced by if(thermo_array[i].readRTDAsync(rtd[i])){}
          //Serial.print("THERMO ");Serial.print(i);Serial.println(" ready ");

          temperature[i]=thermo_array[i].temperatureAsync(rtd[i],RNOMINAL,RREF);

          }
             #ifdef SERIAL_DEBUG
              //timer for debug
              delta_t = millis()-time0;
              time0=millis();
            #endif
        }

        #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
          Serial.print(temperature[i],4);Serial.print("\t");
        #endif  

    #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print("loop time:");Serial.println(delta_t);
      Serial.println();
    #endif 
  #endif

  #ifdef CONTINUOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
      temperature[i] = thermo_array[i].temperature(RNOMINAL,RREF);
      Serial.print(temperature[i],4);Serial.print("\t");
    }
     #ifdef SERIAL_DEBUG
        if(temperature[i]>900){Serial.print(0,4);Serial.print("\t");}
        else{Serial.print(temperature[i],4);Serial.print("\t");}
      #endif

    #ifdef SERIAL_DEBUG
      delta_t = millis()-time0;
      time0=millis();    
      Serial.print("looping time:");
      Serial.println(delta_t);
    #endif
  #endif
}

See output result below: 33.8981 33.4573 -128.3162 -120.1291 33.8981 looping time:63 33.9320 33.4573 -128.3162 -187.4395 33.9320 looping time:63 33.8981 33.4573 -128.3162 988.7923 33.8981 looping time:63 33.8981 33.4573 988.7923 -120.1291 33.8981 looping time:62 33.9320 33.4573 -186.4578 -180.5516 33.9320 looping time:64 33.9320 33.4234 988.7923 -130.4209 33.9320 looping time:62 33.9320 33.4573 -128.3162 -242.0200 33.9320 looping time:64 33.8981 33.4573 -128.3162 308.2525 33.8981 looping time:62 33.9320 33.4573 -177.0322 988.7923 33.9320 looping time:63 33.9320 33.4573 -194.2899 -194.3204 33.9320 looping time:63 33.8981 33.4573 988.7923 19.2108 33.8981 looping time:60 33.9320 33.4573 308.2525 -178.6387 33.9320 looping time:63 33.9320 33.4573 -195.3569 988.7923 33.9320 looping time:62 33.9320 33.4234 19.2108 -128.3162 33.9320 looping time:62 33.8981 33.4573 -241.6699 988.7923 33.8981 looping time:62 33.9320 33.4234 -226.5556 988.7923 33.9320 looping time:63

sylvanoMTL commented 8 months ago

OK, good progress, can you interchange your breakout boards? Did you use pull up resistors for the CS ?

You might need to do a code for 5 RTD, not 8. at the moment you are using the continuous mode.:

festobit commented 8 months ago

No I did not use pull up resistors. If I try reading the CS individually, they are all fine, but if i try doing the multiple, only the first two gets read. I have commented out the other RTDs not required.

The ASYNCHRONOUS_MODE also returns similar results as the continuous mode: 33.9999 33.2877 -242.0200 1.9661 reading rate:10

33.9999 33.2877 -242.0200 1.9661 reading rate:10

33.9999 33.2877 -242.0200 1.9661 reading rate:10

33.9999 33.2877 -242.0200 1.9661 reading rate:10

33.9661 33.2877 -242.0200 -242.0200 reading rate:10

33.9661 33.2877 -242.0200 -242.0200 reading rate:10

33.9661 33.2877 -242.0200 -242.0200 reading rate:10

33.9661 33.2877 -242.0200 -242.0200 reading rate:10

33.9661 33.2877 -241.9908 -242.0200 reading rate:11

33.9661 33.2877 -241.9908 -242.0200 reading rate:11

33.9661 33.2877 -241.9908 -242.0200 reading rate:11

festobit commented 8 months ago

Further modifications of the asynchronous:

  #ifdef ASYNCHRONOUS_MODE
    for(byte i=0;i<thermo_arrayLen;i++){
        condition[i]=thermo_array[i].readRTDAsync(rtd[i]);
        if(condition[i]) { //to be replaced by if(thermo_array[i].readRTDAsync(rtd[i])){}
          Serial.print("THERMO ");Serial.print(i);Serial.println(" ready ");

          temperature[i]=thermo_array[i].temperatureAsync(rtd[i],RNOMINAL,RREF);
          //Serial.print(temperature[i],4);Serial.print("\t");
          }

             #ifdef SERIAL_DEBUG
              //timer for debug
              delta_t = millis()-time0;
              time0=millis();
            #endif

            //Serial.print(temperature[i],4);Serial.print("\t");
        }

        #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
          Serial.print(temperature[i],4);Serial.print("\t");
        #endif  

    #if defined(SERIAL_DEBUG) || defined(SERIAL_OUTPUT)
      Serial.print("loop time:");Serial.println(delta_t);
      Serial.println();
    #endif 
  #endif

Yield

THERMO 0 ready THERMO 1 ready THERMO 2 ready THERMO 3 ready THERMO 4 ready 33.9320 loop time:18

33.9320 loop time:1

33.9320 loop time:0

33.9320 loop time:0

33.9320 loop time:0

33.9320 loop time:0

Now it claims the thermo cs pins are set but returns only a single value from the loop as shown by the loop time result. It is not reading the other thermo cs pins