SPI Bus wont work on Nucleo

All about boards manufactured by ST
Post Reply
geocheats2
Posts: 6
Joined: Sat Aug 28, 2021 8:52 pm

SPI Bus wont work on Nucleo

Post by geocheats2 »

I have a problem, i am guessing at the framework level.

I got a Nucleo-144 (H743ZI2) and some RTD readers featuring MAX31865 over SPI.

I spend 2 days trying to debug why the SPI-DO whouldn't transmit any data.

If i am correct MISO(DO) should be kept low and rise on data transmition?

Datasheet Flow Bellow
max31865-spi-dataflow.png
max31865-spi-dataflow.png (35.19 KiB) Viewed 3718 times

In my case the DO pin stays high and i can't receive anything ( i guess based on my limited experience with an oscilloscope)

I tried using a blue pill and the same exact code (included below) i even kept the pins the same because HW SPI is on A4-A8 on both MCUs

The only difference it that the blue-pill uses the unofficial rogers core while the Nucleo uses the "official" Arduino for STM32 core.

On the blue-pill the SPI bus worked perfectly (HW-SPI) but on the Nucleo i couldn't get it to work (HW+SW-SPI).

Does anyone have any recommendations on what to look into?


I believe that the problem lies somewhere at the use of API https://github.com/stm32duino/wiki/wiki/API#spi of the official core from the Adafruit library.

Should i just try to copy all the needed parts from the library and avoid using it all-together? so i can use the provided API of the official core?

Looking forward to your reply
George

Code

Code: Select all


#include <Wire.h>

#include <SPI.h>

/*************************************************** 
  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 <Adafruit_MAX31865.h>

//#define DEBUG_SERIAL Serial

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(PA4, PB8, PA7, PA5);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(PA4);

// 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

void setup()
{
  //pinMode(PA5, OUTPUT);
  //pinMode(PA7, INPUT);
  //pinMode(PA6, OUTPUT);
  pinMode(PA4, OUTPUT);
  
	Serial.begin(9600);
	Serial.println("MAX31865 PT100 Sensor Test using NIST resistance table.");
  //SPI.setSCLK(PA5);
  //SPI.setMOSI(PB8);
  //SPI.setMISO(PA6);
  //SPI.setSSEL(PB8);
  //SPI.begin();
	//max.begin(MAX31865_2WIRE);  // set to 2WIRE or 4WIRE as necessary
	//max.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary
  thermo.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary

}


void loop() {
  uint16_t rtd = thermo.readRTD();

  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.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();
  }
  Serial.println();
  delay(7500);
}
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: SPI Bus wont work on Nucleo

Post by fpiSTM »

We found an issue using Adafruit libraries. it uses int8_t as type for pin but STM32 can have pin higher than 127 or alias pin PYn higher than 127.
This is the case here. Try with Dx or x number instead of PYn.

PA4 is defined as PIN_A22 as it has analog capabilities so higher than 127. It's digital value is 24.
PB8 is 15 so no issue.
PA7 is PIN_A12 as it has analog capabilities so higher than 127. It's digital value is 85.
PA5 is PIN_A21 as it has analog capabilities so higher than 127. It's digital value is 13.

So try this:

Code: Select all

-Adafruit_MAX31865 thermo = Adafruit_MAX31865(PA4, PB8, PA7, PA5);
+Adafruit_MAX31865 thermo = Adafruit_MAX31865(24, PB8, 85, 13);
Moreover I would use the HW SPI instead of SW:

Code: Select all

Adafruit_MAX31865 thermo = Adafruit_MAX31865(24);
By default it uses the default SPI instance using PB5 (MOSI), PA6 (MISO) and PA5 (SCLK).
You can change the default pin using the SPI.setMOSI() SPI.setMISO() SPI.setSCLK().
So the code should be something like this:

Code: Select all

SPI.setMOSI(xx);
SPI.setMISO(xx);
SPI.setSCLK(xx);
Adafruit_MAX31865 thermo = Adafruit_MAX31865(24);
Where xx is the new SPI pins of the same SPIx peripheral.
geocheats2
Posts: 6
Joined: Sat Aug 28, 2021 8:52 pm

Re: SPI Bus wont work on Nucleo

Post by geocheats2 »

fpiSTM wrote: Mon Aug 30, 2021 7:45 am We found an issue using Adafruit libraries. it uses int8_t as type for pin but STM32 can have pin higher than 127 or alias pin PYn higher than 127.
This is the case here. Try with Dx or x number instead of PYn.

PA4 is defined as PIN_A22 as it has analog capabilities so higher than 127. It's digital value is 24.
PB8 is 15 so no issue.
PA7 is PIN_A12 as it has analog capabilities so higher than 127. It's digital value is 85.
PA5 is PIN_A21 as it has analog capabilities so higher than 127. It's digital value is 13.

So try this:

Code: Select all

-Adafruit_MAX31865 thermo = Adafruit_MAX31865(PA4, PB8, PA7, PA5);
+Adafruit_MAX31865 thermo = Adafruit_MAX31865(24, PB8, 85, 13);
Moreover I would use the HW SPI instead of SW:

Code: Select all

Adafruit_MAX31865 thermo = Adafruit_MAX31865(24);
By default it uses the default SPI instance using PB5 (MOSI), PA6 (MISO) and PA5 (SCLK).
You can change the default pin using the SPI.setMOSI() SPI.setMISO() SPI.setSCLK().
So the code should be something like this:

Code: Select all

SPI.setMOSI(xx);
SPI.setMISO(xx);
SPI.setSCLK(xx);
Adafruit_MAX31865 thermo = Adafruit_MAX31865(24);
Where xx is the new SPI pins of the same SPIx peripheral.

Code: Select all

RTD value: 8609
Ratio = 0.26272583
Resistance = 112.97210693
Temperature = 33.36
Fault 0x43
RTD Low Threshold
For some reason i got a temperature close to the ambient, i believe but i still have a fault, i will try with a different module to see if that persists


For future reference where the pin # are mentioned on
geocheats2
Posts: 6
Joined: Sat Aug 28, 2021 8:52 pm

Re: SPI Bus wont work on Nucleo

Post by geocheats2 »

Code: Select all

Ratio = 0.51989746
Resistance = 223.55590820
Temperature = 332.47
Fault 0x1
It still has some fault but at least i have data out of the SDO pin
geocheats2
Posts: 6
Joined: Sat Aug 28, 2021 8:52 pm

Re: SPI Bus wont work on Nucleo

Post by geocheats2 »

Code: Select all

RTD value: 8545
Ratio = 0.26077271
Resistance = 112.13226318
Temperature = 31.15
It worked correctly over SW-SPI, i will try to fix HW-SPI but for now its not critical

THANKS for all the information

Code: Select all

/*************************************************** 
  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 <Wire.h>
#include <Adafruit_MAX31865.h>

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(24, 51, 12, 13);
// use hardware SPI, just pass in the CS pin
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(24);

// 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

void setup()
{

  Serial.begin(9600);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  //SPI.setMOSI(51);
  //SPI.setMISO(12);
  //SPI.setSCLK(13);
  thermo.begin(MAX31865_3WIRE); // set to 2WIRE or 4WIRE as necessary
  
  
}

void loop()
{
  uint16_t rtd = thermo.readRTD();

  Serial.print("RTD value: ");
  Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = ");
  Serial.println(ratio, 8);
  Serial.print("Resistance = ");
  Serial.println(RREF * ratio, 8);
  Serial.print("Temperature = ");
  Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.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();
  }
  Serial.println();
  delay(1000);
}
Post Reply

Return to “STM boards (Discovery, Eval, Nucleo, ...)”