Connnet a SPI device (MAX31865)


#1

Hi,
I’m trying to connect a SPI device, MAX31865, to blend and I have an address conflict between this device and the BLE.

I appreciate some help.
Best regards,
Joao Rocha


#2

Hi @joao-rocha, There is no address conflict regarding the SPI devices. SPI device is activated by the chip select pin, instead of address. If the MAX31865 and BLE both using the same SPI interface, just make sure that the the REQN pin of BLE and the chip select pin of MAX31865 is not the same pin. And before the operation to MAX31865, check if the BLE is occupying the SPI interface like this:

if( !ble_busy()) {
  // Do MAX31865 work
}

#3

Hi guohui,
I thank you for your help.
I already have checked the REQN and /CS pins.
I’ll try to implement the instruction (!ble_busy) and I’ll let you know if I succeed.

Best regards,
Joao Rocha


#4

Hi again,
I’m using BLEPeripheral.h libraries, instead the nRF8001 libraries.
So I’m not be able to use ble_busy function, and I can’t find some similar function on <BLEPeripheral.h>.
I’m almost run out of Blend memory that´s I’m trying not add more libraries to the sketch.
Do you have any ideia to help me. I thank you in advance.
Best regards,
João Rocha


#5

You are using the Sandeep BLE library? In that case, you can implement the ble_busy() like this:

uint8_t reqn_pin = D9; // For example

unsigned char ble_busy()
{
    if(digitalRead(reqn_pin) == HIGH)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

Cheers!


#6

Thank you for your help.

I’ll try to implement the ble_busy() function.
However I think it will be hard to work.
What I’m experiencing is as far I connect the SPI wires the BLE stops to work.

Thank you again.


#7

I’m stuck in my project!
I can´t put my temperature reader (MAX31865) and BLEND working together.
The code for MAX is working properly, alone.
Here is my code.

#include <TimerOne.h>
#include <SPI.h>
#include <BLEPeripheral.h>

// define pins (varies per shield/board)
#define BLE_REQ   9
#define BLE_RDY   8
#define BLE_RST   5 // Nao esta a ser usado

#define Rref 400       // Rfef = 400 if PT100 used, Rref = 4000 if PT1000 used
#define CS 6
BLEPeripheral blePeripheral = BLEPeripheral(BLE_REQ, BLE_RDY, BLE_RST);

BLEService tempService = BLEService("CCC0");
BLEDoubleCharacteristic tempCharacteristic = BLEDoubleCharacteristic("CCC1", BLERead | BLENotify);
BLEDescriptor tempDescriptor = BLEDescriptor("2901", "Temp Celsius");
BLEDoubleCharacteristic tempCharacteristicCalOrigin = BLEDoubleCharacteristic("CCC2", BLERead | BLEWrite | BLENotify);
BLEDescriptor tempCharacteristicCalOriginDescriptor = BLEDescriptor("2901", "offset");
BLEDoubleCharacteristic tempCharacteristicCalSlope = BLEDoubleCharacteristic("CCC3", BLERead | BLEWrite);
BLEDescriptor tempCharacteristicCalSlopeDescriptor = BLEDescriptor("2901", "slope");

volatile bool readFromSensor = false;

float lastTempReading;

void setup() {
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV128);     //Para o Blend e outros
  SPI.setDataMode(SPI_MODE3);
  delay(100);
  configureMAX31865();
    
  blePeripheral.setLocalName("FlexSensorMAX");
  blePeripheral.setAdvertisedServiceUuid(tempService.uuid());
  blePeripheral.addAttribute(tempService);
  blePeripheral.addAttribute(tempCharacteristic);
  blePeripheral.addAttribute(tempDescriptor);

  blePeripheral.addAttribute(tempCharacteristicCalOrigin);
  blePeripheral.addAttribute(tempCharacteristicCalOriginDescriptor);
  blePeripheral.addAttribute(tempCharacteristicCalSlope);
  blePeripheral.addAttribute(tempCharacteristicCalSlopeDescriptor);  

  tempCharacteristicCalOrigin.setValue(0.0);
  tempCharacteristicCalSlope.setValue(1.0);
  blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  blePeripheral.begin();
 
  Timer1.initialize(1 * 1000000); // in milliseconds
  Timer1.attachInterrupt(timerHandler);

  Serial.println(F("BLE Temperature Sensor Peripheral"));
}

void loop() {
  blePeripheral.poll();
  
  if (readFromSensor) {
       if(digitalRead(BLE_REQ) == HIGH){        //same as ble_busy
          
          setTempCharacteristicValue(); 
       }
    readFromSensor = false;
  }
}

void timerHandler() {
  readFromSensor = true;
}

void setTempCharacteristicValue() {
   float reading = readMax();
     Serial.println(reading);

  if (!isnan(reading)) {
    tempCharacteristic.setValue(reading);
    lastTempReading = reading;
  }
}

void blePeripheralConnectHandler(BLECentral& central) {
  Serial.print(F("Connected event, central: "));
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLECentral& central) {
  Serial.print(F("Disconnected event, central: "));
  Serial.println(central.address());
}
void configureMAX31865(){
   digitalWrite(CS, LOW);
   SPI.transfer(0x80);
   SPI.transfer (0xC2);   //Para 4 fios
   digitalWrite(CS, HIGH);
   delay(50);
}
double CallendarVanDusen(double R){
   double a = 3.9083E-03;
   double b = -5.7750E-07;
   signed long R0=Rref/4;
   return (-R0*a+sqrt(R0*R0*a*a-4*R0*b*(R0-R)))/(2*R0*b);
}
float readMax(){
  unsigned char reg[8];          // array for all the 8 registers
   unsigned int i;
   unsigned int RTDdata;          // 16 bit value of RTD MSB & RTD LSB, reg[1] & reg[2]
   unsigned int ADCcode;          // 15 bit value of ADC, RTDdata >> 1, 0th bit of RTDdata is RTD connection fault detection bit
   double R;                      // actual resistance of PT100 sensor
   float tempMax;                 // devolve a temperatura

   digitalWrite(CS, LOW);
   delay(10);
   SPI.transfer(0);                                     // start reading from address=0
   for (i=0; i<8; i++) reg[i]=SPI.transfer(0);            // read all the 8 registers
   delay(10);
   digitalWrite(CS, HIGH);
   RTDdata = reg[1] << 8 | reg[2];
   if (RTDdata & 1) {
     Serial.println("PT100 sensor connenction fault!");
     Serial.println();
     configureMAX31865();
   }
   else{
     ADCcode=RTDdata>>1; 
     R=(double)ADCcode*Rref/32768;   
     tempMax = CallendarVanDusen(R);
     }
    return(tempMax);
  }

Can you give me some idea?
Thank you in advance

Joao rocha


#8

I was thinking you are using the nRF8001 library from RedBear. That library handles the SPI configuration carefully. See here. But the library you are actually using may not deal with the conflict SPI configuration, which definitely cause either of the BLE or MAX31865 works only. I would suggest you try the nRF8001 library, otherwise, you have to save and restore the SPI configuration as the nRF8001 library.


#9

Hi,
Thank for your help.
I’ll change my libraries…


#10

Hi,
I have changed libraries and MAX31865 does not work with BLEND.
The problem is the same as Sandeep BLE library.

If someone could help, with an example, it would be great.
Otherwise I have 5 BLENDs to sell!

João Rocha


#11

Hi @joao-rocha, Did BLE work independently? And please post your code if using nRF8001 library.


#12

Hi,
here is the code I’m trying with the RBL_nRF8001.h library

If I try to read the sensor MAX31865 without testing the use of BLE the results are always wrong…

//"RBL_nRF8001.h/spi.h/boards.h" is needed in every new project
#include <SPI.h>
#include <EEPROM.h>
#include <boards.h>
#include <RBL_nRF8001.h>
#define Rref 400       // Rfef = 400 if PT100 used, Rref = 4000 if PT1000 used
#define CS 6

void setup()
{
  ble_set_pins(9, 8);
  ble_set_name("FlexSeRF");
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV8);     //Para o Blend e outros
  SPI.setDataMode(SPI_MODE1);
  delay(100);
  configureMAX31865();
  
  delay(1000);
  ble_begin();
}
unsigned char buf[16] = {0};
unsigned char len = 0;

void loop()
{
  if (!ble_busy()) Serial.println("busy");
  if (!ble_busy()){Serial.println(" NOT busy");
  float valorMax = readMax();
     Serial.print("do MAX ");Serial.println(valorMax);
  }
  if ( ble_connected() )
  {
    ble_write('4');     // teste to write to BLE  
  }
  ble_do_events();
  
  if ( ble_available() )
  {
    while ( ble_available() )
    {
      Serial.write(ble_read());     //read from BLE
    }
    Serial.println();
  }
  delay(1000);    
}

void configureMAX31865(){
   digitalWrite(CS, LOW);
   SPI.transfer(0x80);
   SPI.transfer (0xC2);   //Para 4 fios
   digitalWrite(CS, HIGH);
   delay(50);
}

double CallendarVanDusen(double R){
   double a = 3.9083E-03;
   double b = -5.7750E-07;
   signed long R0=Rref/4;
   return (-R0*a+sqrt(R0*R0*a*a-4*R0*b*(R0-R)))/(2*R0*b);
}
float readMax(){
   unsigned char reg[8];       // array for all the 8 registers
   unsigned int i;
   unsigned int RTDdata;          // 16 bit value of RTD MSB & RTD LSB, reg[1] & reg[2]
   unsigned int ADCcode;          // 15 bit value of ADC, RTDdata >> 1, 0th bit of RTDdata is RTD connection fault detection bit
   double R;                      // actual resistance of PT100(0) sensor
   float temp;
   digitalWrite(CS, LOW);
   delay(1);
   SPI.transfer(0);                                     // start reading from address=0
   for (i=0; i<8; i++) {reg[i]=SPI.transfer(0); Serial.println(reg[i]);}            // read all the 8 registers
   delay(1);
   digitalWrite(CS, HIGH);
   RTDdata = reg[1] << 8 | reg[2];
     if (RTDdata & 1) {
     Serial.println("PT100 sensor connenction fault!");
     Serial.println();
     configureMAX31865();
   }
   else{
     
     ADCcode=RTDdata>>1; 
     R=(double)ADCcode*Rref/32768;   
     temp = CallendarVanDusen(R);
     }
    delay(3000);
    return (temp);
  }

thanks for helping me.
joão Rocha


#13

I believe that the MAX31865 should work well with Blend. Next I would suggest you to test the BLE independently. If both of them work well independently, then integrate the code together and make sure that deal with the MAX31865 when BLE is not busy.


#14

Hi,

I did it, already!
The BLEND works fine alone and with others shields.
I’m having problems only when I connect the BLE and the MAX31865. I read the values form MAX with no problems.
Now I’m working a new solution. I found it works with the code if I change some lines of code. But with the BLEPeripheral libraries I still found some troubles.
Here I copy the code that is working:

//"RBL_nRF8001.h/spi.h/boards.h" is needed in every new project
#include <SPI.h>
//#include <EEPROM.h>
#include <boards.h>
#include <RBL_nRF8001.h>
#define Rref 400       // Rfef = 400 if PT100 used, Rref = 4000 if PT1000 used
#define CS 6
int teste=1;
void setup()
{
  ble_set_pins(9, 8);
  ble_set_name("FlexSeRF");
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  SPI.begin();
  //SPI.setClockDivider(SPI_CLOCK_DIV8);     //Para o Blend e outros
  //SPI.setDataMode(SPI_MODE1);
  delay(100);
  //configureMAX31865();
  
  delay(1000);
  ble_begin();
}
unsigned char buf[16] = {0};
unsigned char len = 0;

void loop()
{
  if (!ble_busy()){
    Serial.println(" NOT busy");
    float valorMax = readMax();
    Serial.print("do MAX ");Serial.println(valorMax);
  }
  else {
    Serial.println("busy"); 
  }

  if ( ble_connected() )
  {
    ble_write('4');     // teste to write to BLE  
  }
  ble_do_events();
  
  if ( ble_available() )
  {
    while ( ble_available() )
    {
      Serial.write(ble_read());     //read from BLE
    }
    Serial.println();
  }
  delay(1000);    
}

void configureMAX31865(){
   digitalWrite(CS, LOW); 
   SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV128, MSBFIRST, SPI_MODE3));
   SPI.transfer(0x80);
   SPI.transfer (0xC0);   //Para 4 fios
   digitalWrite(CS, HIGH);
   SPI.endTransaction();
   
   delay(150);
}

double CallendarVanDusen(double R){
   double a = 3.9083E-03;
   double b = -5.7750E-07;
   signed long R0=Rref/4;
   return (-R0*a+sqrt(R0*R0*a*a-4*R0*b*(R0-R)))/(2*R0*b);
}
float readMax(){
   unsigned char reg[8];       // array for all the 8 registers
   unsigned int i;
   unsigned int RTDdata;          // 16 bit value of RTD MSB & RTD LSB, reg[1] & reg[2]
   unsigned int ADCcode;          // 15 bit value of ADC, RTDdata >> 1, 0th bit of RTDdata is RTD connection fault detection bit
   double R;                      // actual resistance of PT100(0) sensor
   float temp;
   configureMAX31865();
   digitalWrite(CS, LOW);
   SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV128, MSBFIRST, SPI_MODE3));
   delay(1);
   SPI.transfer(0);                                     // start reading from address=0
   for (i=0; i<8; i++) {reg[i]=SPI.transfer(0); Serial.println(reg[i]);}            // read all the 8 registers
   delay(1);
   digitalWrite(CS, HIGH);
   SPI.endTransaction();
   RTDdata = reg[1] << 8 | reg[2];
   if (RTDdata & 1) {
     Serial.println("PT100 sensor connenction fault!");
     Serial.println();
     configureMAX31865();
   }
   else{
     
     ADCcode=RTDdata>>1; 
     R=(double)ADCcode*Rref/32768;   
     temp = CallendarVanDusen(R);
  }
  //delay(3000);
  return (temp);
}

Thank you for your help.

I need to work with the BLEPeripheral libraries because I have some APPs that interact with it.

I’ll let you know any progress,
joao rocha


#15

Much glad to hear you’ve solved the problem. When using Sandeep’s BLE library, keep in mind that the SPI interface can be accessed by only one instance at any time and the SPI configuration should dedicate to that instance.