Mapping CS pin on MAX31865 with MuxShield II

Mapping CS pin on MAX31865 with MuxShield II

Im trying to use a Adafruit MAX31865 (PT100 version, if that matters) with a Mayhew Labs MuxShield II. The end project would use multiple RTDs with other I/O, so the Multiplexer is required.

After a bunch of testing, I have found that I cannot get the RTD code to read where the CS pin is. The MuxShield library passes a "void" value to express where the pin is, and the Adafruit_MAX21865 library expects an "int" value. I've tried casting the void value into an integer, but that was like handing the keys of a battleship to a 7-year-old.

How do I get this to work? Am I missing something very obvious? My code is below:

#include <MuxShield.h> //Initialize the Mux Shield
#include <Adafruit_MAX31865.h> // Initialize the MAX31865
#define RREF      430.0 // The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RNOMINAL  100.0 // The 'nominal' 0-degrees-C resistance of the sensor (100.0 for PT100)

MuxShield muxShield; //start the muxsheild
int CSint;
int DIpin = 5;
int DOpin = 9;
int CLKpin = 13;
float tempNow;
const int setTemp = 30;

void setup() {
  Serial.begin(115200);
  Serial.println("Setup Started.");
  
  muxShield.setMode(1,DIGITAL_OUT);        //set I/O 1 as digital output
  muxShield.setMode(2,DIGITAL_IN_PULLUP);  //set I/O 2 as digital in with pullup (not used, from example code)
  muxShield.setMode(3,ANALOG_IN);          //set I/O 3 as analog input (not used, from example code)

  Serial.println("Setup Complete");
  delay(1000);
}


void loop() {
  CSint = (int8_t)(muxShield.digitalWriteMS (1,0,HIGH)); //My attempt at casting a "void" to an "int", which fails completely
  tempNow = (CurTemp(CSint, DIpin, DOpin, CLKpin)); //Calling the function below
  Serial.println("T1 = ");
  Serial.println(tempNow);
  

if ( (tempNow > (setTemp)) ) { //this part seems to work just fine, if the RTD is directly wired in to the arduino
    // turn LED on:
    muxShield.digitalWriteMS(1,15,HIGH);
    Serial.println("LED on");
  } else {
    // turn LED off:
    muxShield.digitalWriteMS(1,15,LOW);
    Serial.println("LED Off");
  }
   Serial.println("\r\n");
   delay(5000);

}


float CurTemp(int CS, int DI, int DO, int CLK){ //This function works when the RTD is wired into the Arduino directly.

  Adafruit_MAX31865 thermo1 = Adafruit_MAX31865(CS, DI, DO, CLK);// Use software SPI: CS, DI, DO, CLK
  thermo1.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary

  return thermo1.temperature(RNOMINAL, RREF); //returns a float
}

Apologies for the lack of proper terminology. I only know enough coding to get me trouble, and not enough to get me out of it.

void means "no return value", so casting don't help, no value stays no value.

You cannot use this library unmodified with your mux shield as it expects a simple pin number for the CS signal. As the library doesn't handle the SPI library directly but by an Adafruit abstraction of it you have to modify at least these two libraries. I would rewrite the MAX31865 library to not use the Adafruit_SPIDevice library anymore but SPI directly and provide a function pointer for switching the CS signal. That way you can still use the library generally but you're able to use it with your mux too.

Thank you for the reply! I was worried about trying casting out, and am glad I didn't pursue it further.

As I understand it, I have to modify the following section of code from the Adafruit_Max31865.h file. Is that correct?


/*! Interface class for the MAX31865 RTD Sensor reader */
class Adafruit_MAX31865 {
public:
  Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso,
                    int8_t spi_clk);
  Adafruit_MAX31865(int8_t spi_cs, SPIClass *theSPI = &SPI);

  bool begin(max31865_numwires_t x = MAX31865_2WIRE);

  uint8_t readFault(max31865_fault_cycle_t fault_cycle = MAX31865_FAULT_AUTO);
  void clearFault(void);
  uint16_t readRTD();

  void setThresholds(uint16_t lower, uint16_t upper);
  uint16_t getLowerThreshold(void);
  uint16_t getUpperThreshold(void);

  void setWires(max31865_numwires_t wires);
  void autoConvert(bool b);
  void enable50Hz(bool b);
  void enableBias(bool b);

  float temperature(float RTDnominal, float refResistor);
  float calculateTemperature(uint16_t RTDraw, float RTDnominal,
                             float refResistor);

private:
  Adafruit_SPIDevice spi_dev;

  void readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n);

  uint8_t readRegister8(uint8_t addr);
  uint16_t readRegister16(uint8_t addr);

  void writeRegister8(uint8_t addr, uint8_t reg);

In the .h file it's probably just these lines:

  Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso,
                    int8_t spi_clk);
  Adafruit_MAX31865(int8_t spi_cs, SPIClass *theSPI = &SPI);
  Adafruit_SPIDevice spi_dev;

but that depends on how you want to implement it. The majority of changes will be in the .cpp file.

Okay, I looked into editing the Adafruit_MAX31865 library files (both .h and .cpp) and its a bit beyond my understanding.

Do you know of any good resource into learning how to modify these files?

After looking at it a bit, I think I'd have to change the following code, but I don't understand the syntax. Does the colon in the following bit of code correlate the code on either side?

/**************************************************************************/
/*!
    @brief Create the interface object using software (bitbang) SPI
    @param spi_cs the SPI CS pin to use
    @param spi_mosi the SPI MOSI pin to use
    @param spi_miso the SPI MISO pin to use
    @param spi_clk the SPI clock pin to use
*/
/**************************************************************************/
//
Adafruit_MAX31865::Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi,
                                     int8_t spi_miso, int8_t spi_clk)
    : spi_dev(spi_cs, spi_clk, spi_miso, spi_mosi, 1000000,
              SPI_BITORDER_MSBFIRST, SPI_MODE1) {}

Thanks for helping me out.

I would start with a C++ tutorial (there are many on the Web). Once you got familiar to the language you learn a lot by studying the libraries available from Arduino and some other companies (p.e. Sparkfun). The SPI using libraries from Adafruit aren't good examples to start because they abstracted the SPI library using their Adafruit_SPIDevcie implementation.

That calls the constructor of member variable spi_dev before executing the rest of the constructor code (which is empty in this case).

If you do it the way I proposed you'll have to modify the constructor (to provide the CS changing function), the begin(), readRegisterN() and writeRegister8() methods.

Pylon, Thank you for your help. I haven't yet solved the actual problem yet, but I'm working around the issue like a true capitalist.

I just bought a Mega and called it good.

I did learn a bunch from this exercise, and I'll pursue it at a later date.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.