SPI Communication between BLE nano 33 and MAX31856

Currently working on a project to collect temperature data from thermocouples and transmit that data over the BLE. I have managed to get the MAX31856 to communicate by SPI with an arduino uno however when connecting the pins to the Nano the communication seems to fail. The values reported are all zero instead of the actual temperatures. The error does not seem to trigger any of the error detection in the code, but when connected with the Nano I am able to remove the MISO wire with no error. leading me to believe the MAX31856 isn't properly pulling the MISO line on the nano but is on the uno. I have seen other posts regarding SPI com issues with the Nano any help would be appreciated. Note: the spi.h is not orange in my code like normal when adding a library.

#include <ArduinoBLE.h>
#include "PlayingWithFusion_MAX31856.h"
#include "PlayingWithFusion_MAX31856_STRUCT.h"
#include <SPI.h>

uint8_t TC0_CS  = 10;
uint8_t TC1_CS  =  9;

PWF_MAX31856  thermocouple0(TC0_CS);
PWF_MAX31856  thermocouple1(TC1_CS);
const int BLE_LED_PIN = LED_BUILTIN;
BLEService testService("1853");
BLEFloatCharacteristic ThermoCh0("1999-00", BLERead | BLENotify);
BLEFloatCharacteristic ThermoCh1("1999-01", BLERead | BLENotify);
void setup() {
  // put your setup code here, to run once: 
  SPI.begin();                            // begin SPI
  SPI.beginTransaction(SPISettings(1000000,MSBFIRST, SPI_MODE1));
  
 thermocouple0.MAX31856_config(J_TYPE, CUTOFF_60HZ, AVG_SEL_4SAMP, CMODE_AUTO);
  thermocouple1.MAX31856_config(J_TYPE, CUTOFF_60HZ, AVG_SEL_4SAMP, CMODE_AUTO);

  pinMode( BLE_LED_PIN, OUTPUT );
  

 

  if( setupBleMode() )
  {
    digitalWrite( BLE_LED_PIN, HIGH );
  }
}

void loop() {
  
  // put your main code here, to run repeatedly:
   BLEDevice central = BLE.central();

 delay(1000);                                   // 500ms delay... can be as fast as ~100ms in continuous mode, 1 samp avg
  
  static struct var_max31856 TC_CH0, TC_CH1;
  double tmp;
  
  struct var_max31856 *tc_ptr;
  
  // Read CH 0
  tc_ptr = &TC_CH0;                             // set pointer
  thermocouple0.MAX31856_update(tc_ptr);        // Update MAX31856 channel 0
  // Read CH 1
  tc_ptr = &TC_CH1;                             // set pointer
  thermocouple1.MAX31856_update(tc_ptr);        // Update MAX31856 channel 1
  
  
  // ##### Print information to serial port ####
  
  // Thermocouple channel 0
  Serial.print("Thermocouple 0: ");            // Print TC0 header
  if(TC_CH0.status)
  {
    // lots of faults possible at once, technically... handle all 8 of them
    // Faults detected can be masked, please refer to library file to enable faults you want represented
    Serial.println("fault(s) detected");
    Serial.print("Fault List: ");
    if(0x01 & TC_CH0.status){Serial.print("OPEN  ");}
    if(0x02 & TC_CH0.status){Serial.print("Overvolt/Undervolt  ");}
    if(0x04 & TC_CH0.status){Serial.print("TC Low  ");}
    if(0x08 & TC_CH0.status){Serial.print("TC High  ");}
    if(0x10 & TC_CH0.status){Serial.print("CJ Low  ");}
    if(0x20 & TC_CH0.status){Serial.print("CJ High  ");}
    if(0x40 & TC_CH0.status){Serial.print("TC Range  ");}
    if(0x80 & TC_CH0.status){Serial.print("CJ Range  ");}
    Serial.println(" ");
  }
  else  // no fault, print temperature data
  {
    Serial.println("no faults detected");
    // MAX31856 Internal Temp
    tmp = (double)TC_CH0.ref_jcn_temp * 0.015625;  // convert fixed pt # to double
    Serial.print("Tint = ");                      // print internal temp heading
    if((-100 > tmp) || (150 < tmp)){Serial.println("unknown fault");}
    else{Serial.println(tmp);}
    
    // MAX31856 External (thermocouple) Temp
    tmp = (double)TC_CH0.lin_tc_temp * 0.0078125;           // convert fixed pt # to double
    Serial.print("TC Temp = ");                   // print TC temp heading
    Serial.println(tmp);
    ThermoCh0.writeValue(tmp);
  }
  
  // Thermocouple channel 1
  Serial.print("Thermocouple 1: ");            // Print TC0 header
  if(TC_CH1.status)
  {
    // lots of faults possible at once, technically... handle all 8 of them
    // Faults detected can be masked, please refer to library file to enable faults you want represented
    Serial.println("fault(s) detected");
    Serial.print("Fault List: ");
    if(0x01 & TC_CH1.status){Serial.print("OPEN  ");}
    if(0x02 & TC_CH1.status){Serial.print("Overvolt/Undervolt  ");}
    if(0x04 & TC_CH1.status){Serial.print("TC Low  ");}
    if(0x08 & TC_CH1.status){Serial.print("TC High  ");}
    if(0x10 & TC_CH1.status){Serial.print("CJ Low  ");}
    if(0x20 & TC_CH1.status){Serial.print("CJ High  ");}
    if(0x40 & TC_CH1.status){Serial.print("TC Range  ");}
    if(0x80 & TC_CH1.status){Serial.print("CJ Range  ");}
    Serial.println(" ");
  }
  else  // no fault, print temperature data
  {
    Serial.println("no faults detected");
    // MAX31856 Internal Temp
    tmp = (double)TC_CH1.ref_jcn_temp * 0.015625;  // convert fixed pt # to double
    Serial.print("Tint = ");                      // print internal temp heading
    if((-100 > tmp) || (150 < tmp)){Serial.println("unknown fault");}
    else{Serial.println(tmp);}
    
    // MAX31856 External (thermocouple) Temp
    tmp = (double)TC_CH1.lin_tc_temp * 0.0078125;           // convert fixed pt # to double
    Serial.print("TC Temp = ");                   // print TC temp heading
    Serial.println(tmp);
    ThermoCh1.writeValue(tmp); 
  }


  }

bool setupBleMode()
{
  if ( !BLE.begin() )
  {
    return false;
  }

  // set advertised local name and service UUID:
  BLE.setDeviceName( "Arduino Nano 33 BLE" );
  BLE.setLocalName( "Arduino Nano 33 BLE" );
  BLE.setAdvertisedService( testService );
testService.addCharacteristic(ThermoCh0);
testService.addCharacteristic(ThermoCh1);
 
BLE.addService( testService );
  // start advertising
  BLE.advertise();

  return true;
}

capstonetest.ino (5.13 KB)

The MAX31856 comes in a TSSOP case so I strongly assume you don't use it directly but on some breakout board. Unfortunately you failed to tell us which board you're using and what schematics it has. As you told us that this board is working with the UNO I guess it contains a voltage regulator and level converters to adapt from the MAX's 3.3V to the 5V of the UNO.

You also failed to provide a wiring diagram so I guess you did the wiring wrongly, probably the same as the UNO (which is wrong).

As you're trying to use two of the chips (according ot the code) the level converters used are relevant as many don't do the MISO line correctly (tri-state on CS high).

I have seen other posts regarding SPI com issues with the Nano any help would be appreciated.

You don't have a Nano, you have a Nano 33 BLE which is a completely different board and has nothing in common with the Nano except the name.

Here I've attached both an image of my wiring as well as the data sheet for the exact chip I am using it is a single chip with dual channels. I know the wiring was done correctly unless the pinout diagram on the arduino website is incorrect. I am confident that the sensor only reporting 0 is something to do with the MISO line because the code I've written has error detection and when connected to the UNO board if I disconnected any of the SPI related wires I would immediately have an error reported. However on the BLE when the MISO line was disconnected no error was given indicating to me that the arduino believes it is still getting some communication on that line regardless of if I have a wire connected.

sen-30006_datasheet_r01.pdf (680 KB)

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