Go Down

Topic: Weird conflict between nRF24L01 and MAX31865 (Read 78 times) previous topic - next topic

LRAT

Dear enthusiasts,

Yesterday I wrote code to have an array transmitted from an UNO board to a MEGA board via nRF24L01.
I transmitted an array which contained values of two floating pins and one readout from a potentiometer on A0. The code worked perfect!

Today, I left the code on the transmitter side as is and tried to integrate a PT100 connected to a MAX31865 board which is sharing the same SPI pins as the nRF24L01. So, MISO, MOSI and CLK are on port 50, 51 and 52 respectively.
I use pin 8 to select the nRF24L01 and pin 4 to select the MAX31865.
I bring the signal LOW before the reading and the HIGH at the end of the function.
Each code works as expected. I mean The RX code without the integration of the MAX31865 works great and vice versa.

Now the weird thing is as follows:
When I leave the MISO connection of the MAX31865 disconnected than the nRF24L01 receives the correct values but than I can't see the temperature reading.
When I connect the MISO wire to pin 50 than the temperature reading is spot on but the values transmitted by the UNO board seem to be halved!
Say, when the nRF24L01 is the only one connected than I can see a value of 1023 generated by the potentiometer. But when I connect the MAX31865 than that reading goes from 1023 to 511. The floating values also seems to be less than half. How bizarre!

Here is the TX-code on the UNO:

Code: [Select]

/*nRF24L01 Transmitter code, 22-04-2018. Works great!
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

const int pinCE = 7;
const int pinCSN = 8;
int Array[3];         //Setup of array

RF24 transmitMessage(pinCE, pinCSN); //Create your nRF24L01 object or wireless SPI connection
const byte address[6] = "Node1";


void setup() {
  Serial.begin(9600);
      transmitMessage.begin();
      transmitMessage.openWritingPipe(address);
      transmitMessage.setPALevel(RF24_PA_MIN); //RF24_PA_MAX is max power
      transmitMessage.setDataRate(RF24_250KBPS);
      transmitMessage.setChannel(115); //Set frequency to channel 115
      transmitMessage.stopListening();
      pinMode(LDR, INPUT);
}
   
void loop() {
      Array[0] = analogRead(A0);
      Array[1] = analogRead(A1);
      Array[2] = analogRead(A2);
      transmitMessage.write(&Array, sizeof(Array));
      Serial.print("Array 0 = "); Serial.println(Array[0]);
      Serial.print("Array 1 = "); Serial.println(Array[1]);
      Serial.print("Array 2 = "); Serial.println(Array[2]);
      Serial.println("");
      delay(1000); //To be removed or replaced by millis later on
}


And here is the RX code with the integration of the MAX31865:

Code: [Select]

/*nRF24L01 Receiver code, 22-04-2018.
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
MAX31865 amplifier for PT100 temperature sensors
  This is a basic code for the Adafruit PT100/P1000 RTD Sensor with a MAX31865 breakout board
Power Pins:
    Vin - this is the power pin. Since the chip uses 3 VDC, we have included a voltage regulator on board
    that will take 3-5VDC and safely convert it down.
    To power the board, give it the same power as the logic level of your microcontroller - e.g. for a 5V micro like Arduino, use 5V
    3Vo - this is the 3.3V output from the voltage regulator, you can grab up to 100mA from this if you like
    GND - common ground for power and logic
SPI Logic pins:
All pins going into the breakout have level shifting circuitry to make them 3-5V logic level safe. Use whatever logic level is on Vin!
    SCK - This is the SPI Clock pin, its an input to the chip
    SDO - this is the Serial Data Out / Master In Slave Out pin, for data sent from the MAX31865 to your processor
    SDI - this is the Serial Data In / Master Out Slave In pin, for data sent from your processor to the MAX31865
    CS - this is the Chip Select pin, drop it low to start an SPI transaction. Its an input to the chip
If you want to connect multiple MAX31865's to one microcontroller, have them share the SDI, SDO and SCK pins.
Then assign each one a unique CS pin.
    RDY (Ready) - is a data-ready indicator pin,  you can use this pin to speed up your reads if you are writing your own driver.
    Our Arduino driver doesn't use it to save a pin
    https://learn.adafruit.com/adafruit-max31865-rtd-pt100-amplifier/pinouts*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>  //For LCD-display. Included in Arduino IDE
#include <LiquidCrystal_I2C.h> //For LCD-display
#include <Adafruit_MAX31865.h>

const int pinCE = 7;  //Chip enable activates Rx or Tx mode
const int pinCSN = 8; //SPI Chip Select
const int pinMAX = 4;
int gotArray[3];

//Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13); //Software SPI: CS, DI, DO, CLK, any pin can be used. Not limited to board
Adafruit_MAX31865 max = Adafruit_MAX31865(pinMAX); //Hardware SPI, CLK, MISO, MOSI are fixed according to board, CS can be any pin

RF24 receiveMessage(pinCE, pinCSN); // CE, CSN
const byte address[6] = "Node1";

/*-----( Declare objects )-----*/
//                                   addr, en,rw,rs,d4,d5,d6,d7,bl,blpol       // Set the pins on the I2C chip used for LCD connections:
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address to 0x20 or 0x27, determined by A0, A1 and A2

void setup() {
      Serial.begin(9600);
      max.begin(MAX31865_4WIRE);  // set to 2WIRE, 3WIRE or 4WIRE as necessary
      receiveMessage.begin();
      receiveMessage.openReadingPipe(1, address);
      receiveMessage.setPALevel(RF24_PA_MIN);
      receiveMessage.setDataRate(RF24_250KBPS);
      receiveMessage.setChannel(115); //Set frequency to channel 115
      receiveMessage.startListening();

      lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines
      lcd.backlight(); //Switch the backlight on
      lcd.clear();     //Clear all information from LCD-screen
}
   
void loop() {
  nRF24L01Function();
  MAX31865Function();
  delay(1000);
}

void nRF24L01Function(){
  digitalWrite(pinCSN,LOW);
      if (receiveMessage.available()) {
        lcd.clear();
        receiveMessage.read(&gotArray, sizeof(gotArray));
        Serial.print("Array 0 = "); Serial.println(gotArray[0]);
        Serial.print("Array 1 = "); Serial.println(gotArray[1]);
        Serial.print("Array 2 = "); Serial.println(gotArray[2]);
        Serial.println("");
        lcd.setCursor(0,0);
        lcd.print("Array 0 = "); lcd.print(gotArray[0]);
        lcd.setCursor(0,1);
        lcd.print("Array 1 = "); lcd.print(gotArray[1]);
        lcd.setCursor(0,2);
        lcd.print("Array 2 = "); lcd.print(gotArray[2]);
        digitalWrite(pinCSN,HIGH);       
      }
}

void MAX31865Function(){
  digitalWrite(pinMAX,LOW);
      uint16_t rtd = max.readRTD();
      //Serial.print("RTD value: "); Serial.println(rtd);
      float ratio = rtd;
      ratio /= 32768;
      //Serial.print("Ratio = "); Serial.println(ratio,8);
      Serial.print("Resistance = "); Serial.print(430*ratio,2); Serial.print(" Ohm");
      Serial.print(", Temperature = "); Serial.println(max.temperature(100, 430));
      digitalWrite(pinMAX,HIGH);
}



I hope somebody can give me a nudge in the right direction.
Later on I want to integrate an SD-card which uses the SPI bus as well.
I will post the correct working code on the forum as it seems there are lots of cases of conflicts whilst sharing an SPI-bus.
As always thank you very much in advance!
Cheers,

Luc





pylon

Put the following lines in front of the max.begin() call:

Code: [Select]
pinMode(pinCSN, OUTPUT);
digitalWrite(pinCSN, HIGH);


and try again.

LRAT

Thank you very much Pylon for the suggestion! Much appreciated!
I'm at work at the moment but will try it out tomorrow.
Once it's working I will publish the code.
Cheers (And karma added),

Luc

LRAT

Hi Pylon,

Unfortunately that didn't work.
The MAX 31865 with PT100 works but the variables transmitted by the Tx-board show the following:

Array 0 = 0
Array 1 = 0
Array 2 = 0

I have tried to reboot both boards but to no avail. When I disconnect the MISO pin of the PT100 than everything works again and I can see the values transmitted by the Tx board.

Here is the updated code:

Code: [Select]

/*nRF24L01 Receiver code, 22-04-2018. Works great!
http://forum.arduino.cc/index.php?topic=557447.0
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
MAX31865 amplifier for PT100 temperature sensors
  This is a basic code for the Adafruit PT100/P1000 RTD Sensor with a MAX31865 breakout board
Power Pins:
    Vin - this is the power pin. Since the chip uses 3 VDC, we have included a voltage regulator on board
    that will take 3-5VDC and safely convert it down.
    To power the board, give it the same power as the logic level of your microcontroller - e.g. for a 5V micro like Arduino, use 5V
    3Vo - this is the 3.3V output from the voltage regulator, you can grab up to 100mA from this if you like
    GND - common ground for power and logic
SPI Logic pins:
All pins going into the breakout have level shifting circuitry to make them 3-5V logic level safe. Use whatever logic level is on Vin!
    SCK - This is the SPI Clock pin, its an input to the chip
    SDO - this is the Serial Data Out / Master In Slave Out pin, for data sent from the MAX31865 to your processor
    SDI - this is the Serial Data In / Master Out Slave In pin, for data sent from your processor to the MAX31865
    CS - this is the Chip Select pin, drop it low to start an SPI transaction. Its an input to the chip
If you want to connect multiple MAX31865's to one microcontroller, have them share the SDI, SDO and SCK pins.
Then assign each one a unique CS pin.
    RDY (Ready) - is a data-ready indicator pin,  you can use this pin to speed up your reads if you are writing your own driver.
    Our Arduino driver doesn't use it to save a pin
    https://learn.adafruit.com/adafruit-max31865-rtd-pt100-amplifier/pinouts*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>  //For LCD-display. Included in Arduino IDE
#include <LiquidCrystal_I2C.h> //For LCD-display
#include <Adafruit_MAX31865.h>

const int pinCE = 7;  //Chip enable activates Rx or Tx mode
const int pinCSN = 8; //SPI Chip Select
const int pinMAX = 4;
int gotArray[3];

//Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13); //Software SPI: CS, DI, DO, CLK, any pin can be used. Not limited to board
Adafruit_MAX31865 max = Adafruit_MAX31865(pinMAX); //Hardware SPI, CLK, MISO, MOSI are fixed according to board, CS can be any pin

RF24 receiveMessage(pinCE, pinCSN); // CE, CSN
const byte address[6] = "Node1";

/*-----( Declare objects )-----*/
//                                   addr, en,rw,rs,d4,d5,d6,d7,bl,blpol       // Set the pins on the I2C chip used for LCD connections:
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address to 0x20 or 0x27, determined by A0, A1 and A2

void setup() {
      Serial.begin(9600);
      pinMode(pinCSN, OUTPUT);
      digitalWrite(pinCSN, HIGH);
      max.begin(MAX31865_4WIRE);  // set to 2WIRE, 3WIRE or 4WIRE as necessary
      receiveMessage.begin();
      receiveMessage.openReadingPipe(1, address);
      receiveMessage.setPALevel(RF24_PA_MIN);
      receiveMessage.setDataRate(RF24_250KBPS);
      receiveMessage.setChannel(115); //Set frequency to channel 115
      receiveMessage.startListening();

      lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines
      lcd.backlight(); //Switch the backlight on
      lcd.clear();     //Clear all information from LCD-screen
}
   
void loop() {
  nRF24L01Function();
  MAX31865Function();
  delay(1000);
}

void nRF24L01Function(){
  digitalWrite(pinCSN,LOW);
      if (receiveMessage.available()) {
        lcd.clear();
        receiveMessage.read(&gotArray, sizeof(gotArray));
        Serial.print("Array 0 = "); Serial.println(gotArray[0]);
        Serial.print("Array 1 = "); Serial.println(gotArray[1]);
        Serial.print("Array 2 = "); Serial.println(gotArray[2]);
        Serial.println("");
        lcd.setCursor(0,0);
        lcd.print("Array 0 = "); lcd.print(gotArray[0]);
        lcd.setCursor(0,1);
        lcd.print("Array 1 = "); lcd.print(gotArray[1]);
        lcd.setCursor(0,2);
        lcd.print("Array 2 = "); lcd.print(gotArray[2]);
        digitalWrite(pinCSN,HIGH);       
      }
}

void MAX31865Function(){
  digitalWrite(pinMAX,LOW);
      uint16_t rtd = max.readRTD();
      //Serial.print("RTD value: "); Serial.println(rtd);
      float ratio = rtd;
      ratio /= 32768;
      //Serial.print("Ratio = "); Serial.println(ratio,8);
      Serial.print("Resistance = "); Serial.print(430*ratio,2); Serial.print(" Ohm");
      Serial.print(", Temperature = "); Serial.println(max.temperature(100, 430));
      digitalWrite(pinMAX,HIGH);
}

Whandall

You could use a TXS0108E based 8-bit bidectional level shifter (CJMCU) which has an OE to isolate both sections.

It is specified for 1.2 V to 3.6 V on A Port and 1.65V to 5.5 V on B Port (VCCA≤VCCB).
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up