CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MAX31865 what am I doing wrong??
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

MAX31865 what am I doing wrong??
PostPosted: Wed Aug 25, 2021 5:38 am     Reply with quote

What I have:
MAX31865 connected as on page 24 from the datasheet.. the 2-wire sensor connection.
What I get is that the rtd value I read from the MAX31865 is alway 0x8087.
What ever I do with the PT100 I have connected.. when I freeze him I get this and when I heat him I also get this..
It seems like the communication is going good but what have I done wrong to get the same value always???

Thanks for all your help!!!!

Best regards,
Jody

I use this code MAX31865_test.c:
Code:

#include <MAX31865_test.h>
#include <math.h>
#include "MAX31865_SPI.c"

void main()
{
   double   Rref    = 470;
   int16   result    = 0;
   float   Temperature_vriezer;
   int16   vriezer;
   double   Resistance;

   MAX31865_init(); //Iniatilize the MAX31865 RTD temperature sensors...

   while(1)
   {
      result = MAX31865_read_data();
      if(result == 0x7fff) result = 0;
      Resistance = ((double)result*Rref)/32768;
      Temperature_vriezer = CallendarVanDusen(Resistance);
      vriezer = (int16) Temperature_vriezer;
      delay_us(1);
   }
}


and this MAX31865_SPI.c:

Code:

//---------------------------------------
// Call this function to read the 16-bit A/D result
// from the MAX31865.
int16 MAX31865_read_data(void)
{
   int16 rtd;
   int8 msb,lsb;

   output_low(MAX31865_CS);
   delay_us(10);
   spi_write(MAX31856_RTDMSB_REG);
   msb = spi_read(0);  // Data comes out MSB first
   spi_write(MAX31856_RTDLSB_REG);
   lsb = spi_read(0);
   delay_us(10);
   output_high(MAX31865_CS);
   
   // Convert the data bytes into a 16-bit value.
   rtd = make16(msb,lsb);
   rtd >>= 1;//remove fault

   return(rtd);
}


//---------------------------------------
// Call this function to write a 8-bit value
// to the MAX31865 register.
void MAX31865_write_register(int8 address,int8 config)
{
   output_low(MAX31865_CS);
   delay_us(10);
   spi_write(address);
   delay_us(10);
   spi_write(config);
   delay_us(10);
   output_high(MAX31865_CS);
}


//Resistance to degrees celcius
double CallendarVanDusen(double r)
{
   
   double a     = 3.9083E-03;
   double b     = -5.7750E-07;
   double R0    = 100;//bij 0C
   double deel1 = -R0*a;
   double deel2 = ((R0*a)*(R0*a));
   double deel3 = 4*(R0*b*(R0-r));
   double deel4 = 2*R0*b;
   double deel5 = sqrt(deel2 - deel3);   

   double temp = (deel1+deel5)/deel4;
   if(r == 0) temp =0;
delay_us(1);
   return (temp); 
}

//---------------------------------------
// Setup the hardware SPI module in the PIC.
// The MAX31865 uses SPI mode 3.  The maximum SPI clock
// rate is 5 MHz.  For a 10 MHz PIC, the closest
// clock divisor that will work is 4, giving 147kHz.
// Initialize the chip select pin to the inactive state.
void MAX31865_init(void)
{
   setup_spi(SPI_MASTER | SPI_MODE_3 | SPI_CLK_DIV_16);
   MAX31865_write_register(MAX31856_CONFIG_REG_WRITE,0xC3);//BIAS, AUTO, 50Hz
}


and the MAX31865_test.h:
Code:

#include <18F87J50.h>
//#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOIESO


#use delay(crystal=8MHz)

/***************************************************************************************/
// SPI chip select pin
#define MAX31865_CS  PIN_D1

// SPI mode definitions (for 16F and 18F PICs).
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_H_TO_L)


#define MAX31856_CONFIG_REG_READ       0x00
#define MAX31856_CONFIG_REG_WRITE      0x80
#define MAX31856_CONFIG_BIAS           0x80
#define MAX31856_CONFIG_MODEAUTO       0x40
#define MAX31856_CONFIG_MODEOFF        0x00
#define MAX31856_CONFIG_1SHOT          0x20
#define MAX31856_CONFIG_3WIRE          0x10
#define MAX31856_CONFIG_24WIRE         0x00
#define MAX31856_CONFIG_FAULTSTAT      0x02
#define MAX31856_CONFIG_FILT50HZ       0x01
#define MAX31856_CONFIG_FILT60HZ       0x00

#define MAX31856_RTDMSB_REG           0x01
#define MAX31856_RTDLSB_REG           0x02
#define MAX31856_HFAULTMSB_REG        0x03
#define MAX31856_HFAULTLSB_REG        0x04
#define MAX31856_LFAULTMSB_REG        0x05
#define MAX31856_LFAULTLSB_REG        0x06
#define MAX31856_FAULTSTAT_REG        0x07

#define MAX31865_FAULT_HIGHTHRESH     0x80
#define MAX31865_FAULT_LOWTHRESH      0x40
#define MAX31865_FAULT_REFINLOW       0x20
#define MAX31865_FAULT_REFINHIGH      0x10
#define MAX31865_FAULT_RTDINLOW       0x08
#define MAX31865_FAULT_OVUV           0x04
/***************************************************************************************/
temtronic



Joined: 01 Jul 2010
Posts: 9247
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 25, 2021 6:28 am     Reply with quote

I'd edit main() and use KNOWN values for the 'result', to test the 'math'.
The datasheet will have a table of temps vs bits. I'd use 3 or 5 values and see how the 'math' works.
If it is correct, then either the 'driver' or hardware would be at fault.
BTW if the device a 3V and the PIC is 5V, you'll have 'problems'...
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 25, 2021 6:55 am     Reply with quote

The "math" is doing fine..
I really get that value out of the MAX..
And I am using the following board to communicate with the device:

https://download.mikroe.com/documents/starter-boards/clicker-2/pic18fj/clicker2-pic18fj-manual-v101.pdf

and for the MAX:

https://download.mikroe.com/documents/add-on-boards/click/rtd/rtd-click-schematic-v100.pdf

and configured the last board like page 24 of the datasheet.. 2-wire sensor.
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Wed Aug 25, 2021 7:33 am     Reply with quote

One little thing. You need:

output_high(MAX31865_CS);

at the start of your main. Currently the CS line will be floating, and then
pulled low at the start of the register access. Means the very first access
probably won't actually work, since the line was not high.
Means the first write may well not correctly happen.... Sad
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 25, 2021 8:50 am     Reply with quote

Hello,
Ttelmah,
I changed that.... if it starts working then it will working from the start...
But the value I get is still the same..
0x807F

Any ideas???

Best regards,
Jody
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: MAX31865 what am I doing wrong??
PostPosted: Wed Aug 25, 2021 1:11 pm     Reply with quote

Jody wrote:
What I have:
MAX31865 connected as on page 24 from the datasheet.. the 2-wire sensor connection.
What I get is that the rtd value I read from the MAX31865 is alway 0x8087.

1. What values are you using for the Rref resistor and C1 ?

2. Post a list of connections between your PIC pins and the MAX31865 pins.

3. Post the raw value that you get when you call MAX31865_read_data(void).
Post it in hex.
temtronic



Joined: 01 Jul 2010
Posts: 9247
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Aug 25, 2021 2:57 pm     Reply with quote

0x8000 is about 250-260*C (from the datasheet) so I suspect either a bad TC or wrong components for the RTD device.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Wed Aug 25, 2021 3:22 pm     Reply with quote

Hello,

Rref=470 ohm
C1 = 100nF
CS -> PIN_D1
SCK -> PIN_C3
MISO -> PIN_C4
MOSI -> PIN_C5

after:
spi_write(MAX31856_RTDMSB_REG);
msb = spi_read(0); // Data comes out MSB first
msb = 0x80

and after:
spi_write(MAX31856_RTDLSB_REG);
lsb = spi_read(0);
lsb = 0x7F

after:
// Convert the data bytes into a 16-bit value.
rtd = make16(msb,lsb);
rtd = 0x807F
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 25, 2021 11:01 pm     Reply with quote

On the MAX31865 board, what pins do you have the jumper installed on ?
For the 2-wire sensor connection, the jumper should be on pins 2-3.
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Thu Aug 26, 2021 12:14 am     Reply with quote

OK.
I'd suggest first of all you add a test to see if the fault bit is set. This
might help tell what is wrong.
If this is set, read the error register and look at table 10. This gives the
fault codes that are returned when this bit is 1.
So you really need to read the fault registers and see what it is saying is
wrong. The fault threshold registers are meant to be set to 0xFFFF, and
0x0000 at reset, so the limit errors should not apply.
However looking at the code, your read is wrong. The address byte can
only be written as the first byte after CS drops. It does not anywhere
show sending a subsequent address byte, You read the two registers
by doing a multi byte read, not by sending a second address, the address
automatically increments after each read. The data sheet specifically says:
Quote:

The address byte is always the first byte transferred after CS is driven low.


So you need:
Code:

int16 MAX31865_read_data(void)
{
   int16 rtd;
   int8 msb,lsb;

   output_low(MAX31865_CS);
   delay_us(1); //400nSec is all that is needed
   spi_write(MAX31856_RTDMSB_REG);
   msb = spi_read(0);  // Data comes out MSB first
   lsb = spi_read(0);
   delay_us(1); //400nSec is all that is needed
   output_high(MAX31865_CS);
   
   // Convert the data bytes into a 16-bit value.
   rtd = make16(msb,lsb);
   rtd >>= 1;//remove fault
   return(rtd);
}


You also need to delay 62.5mSec after starting the chip, before the first
reading is available.

I must admit, I cannot see anywhere in the data where it actually
describes how it handles continuous reads in the automatic mode. I'd
have expected you to need to wait for the DRDY bit to drop before a
reading can be made. I would be much happier putting it into single
conversion mode, then triggering a conversion, waiting for this to
complete, and then reading this. Perhaps worth trying.

However I'd suspect that trying to send two addresses is the big problem.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 26, 2021 3:11 am     Reply with quote

Hello Ttelmah,

I check the fault register now after every read-data of the MAX
The fault register data returns always with 0x00..

Checked the PT100 and this one is working fine (right now it is 108ohm).

I seems that everything is working but the data is still not right.....
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 26, 2021 3:26 am     Reply with quote

It is working!!!!!!!!!!!!!!!!!!!!!!

What I changed, in the MAX31865_test.h :
was: #define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_H_TO_L)
now: #define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)

and now it starts giving me the temperature it should be here........
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Thu Aug 26, 2021 3:53 am     Reply with quote

OK.

I meanwhile, took your code and rewrote it to use spi_xfer, and add the
delays that are really needed.
If your code is working without the change to the read routine, it implies
the chip is ignoring the second address write.
Note there is no such thing as 'double' in your chip. This is always just a
standard float32.

Code:

//main31865.c
#include <18F87J50.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOXINST
#FUSES NOIESO

#use delay(crystal=8000000)

#use SPI(SPI1, baud=4000000, MODE=1, bits=32, STREAM=MAX)

#include "math.h"
#include "stdint.h"
#include "MAX31865.h"

void main()
{
   float   Rref    = 470.0;
   uint16_t   result    = 0;
   float   Temperature_vriezer;
   uint16_t   vriezer;
   float   Resistance;
   
   output_high(MAX31865_CS);
   delay_ms(100); //ensure chip has time to wake up
   MAX31865_init(); //wake up chip
   
   while(1)
   {
      result = MAX31865_read_data();
      if (result & 1)
      {
         //error bit is set, read the error status
         result=MAX31865_read8(MAX31856_FAULTSTAT_REG);
         //here add fault diagmostics
      }
      else
      {
         result>>=1; //remove low bit
         if(result == 0x7fff) result = 0;
         Resistance = ((double)result*Rref)/32768;
         Temperature_vriezer = CallendarVanDusen(Resistance);
         vriezer = (int16) Temperature_vriezer;
         delay_ms(17); //minimum 16.5mSec between readings;
      }
   }
}


Code:

//max31865.h
/***************************************************************************************/
// SPI chip select pin
#define MAX31865_CS  PIN_D1

#define MAX31856_CONFIG_REG_READ       0x00
#define MAX31856_CONFIG_REG_WRITE      0x80
#define MAX31856_CONFIG_BIAS           0x80
#define MAX31856_CONFIG_MODEAUTO       0x40
#define MAX31856_CONFIG_MODEOFF        0x00
#define MAX31856_CONFIG_1SHOT          0x20
#define MAX31856_CONFIG_3WIRE          0x10
#define MAX31856_CONFIG_24WIRE         0x00
#define MAX31856_CONFIG_FAULTSTAT      0x02
#define MAX31856_CONFIG_FILT50HZ       0x01
#define MAX31856_CONFIG_FILT60HZ       0x00

#define MAX31856_RTDMSB_REG           0x01
#define MAX31856_RTDLSB_REG           0x02
#define MAX31856_HFAULTMSB_REG        0x03
#define MAX31856_HFAULTLSB_REG        0x04
#define MAX31856_LFAULTMSB_REG        0x05
#define MAX31856_LFAULTLSB_REG        0x06
#define MAX31856_FAULTSTAT_REG        0x07

#define MAX31865_FAULT_HIGHTHRESH     0x80
#define MAX31865_FAULT_LOWTHRESH      0x40
#define MAX31865_FAULT_REFINLOW       0x20
#define MAX31865_FAULT_REFINHIGH      0x10
#define MAX31865_FAULT_RTDINLOW       0x08
#define MAX31865_FAULT_OVUV           0x04
/***************************************************************************************/

//---------------------------------------
// Call this function to read a 16bit value from a register pair
uint16_t MAX31865_read16(int regno)
{
   uint16_t rtd;

   output_low(MAX31865_CS);
   delay_us(1);
   spi_xfer(MAX,regno,8); //send the register number
   rtd = spi_xfer(MAX,0L,16);  // clock out 16 dummy bits and read the reply
   delay_us(1);
   output_high(MAX31865_CS);
   return(rtd);
}

// Call this function to read an 8bit value from a register
uint8_t MAX31865_read8(int regno)
{
   uint8_t rtd;

   output_low(MAX31865_CS);
   delay_us(1);
   spi_xfer(MAX,regno,8); //send the register number
   rtd = spi_xfer(MAX,0,8);  // clock out 8 dummy bits and read the reply
   delay_us(1);
   output_high(MAX31865_CS);
   return(rtd);
}

//specific version for data register
#define MAX31865_read_data() MAX31865_read16(MAX31856_RTDMSB_REG)

//---------------------------------------
// Call this function to write a 8-bit value
// to a MAX31865 register.
void MAX31865_write_register(uint8_t reg_address,uint8_t value)
{
   output_low(MAX31865_CS);
   delay_us(1);
   spi_xfer(MAX,reg_address,8);
   spi_xfer(MAX,value,8);
   delay_us(1);
   output_high(MAX31865_CS);
}

//Resistance to degrees celcius - your PIC does not support a double type
float CallendarVanDusen(float r)
{
   
   float a     = 3.9083E-03;
   float b     = -5.7750E-07;
   float R0    = 100;//bij 0C
   float deel1 = -R0*a;
   float deel2 = ((R0*a)*(R0*a));
   float deel3 = 4*(R0*b*(R0-r));
   float deel4 = 2*R0*b;
   float deel5 = sqrt(deel2 - deel3);   

   float temp = (deel1+deel5)/deel4;
   if(r == 0) temp =0;
delay_us(1);
   return (temp);
}

void MAX31865_init(void)
{
     MAX31865_write_register(MAX31856_CONFIG_REG_WRITE,0xC3);//BIAS, AUTO, 50Hz
   delay_ms(63); //minimum 62.5mSec before a result can be read
}
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 26, 2021 4:23 am     Reply with quote

O I changed it to what you sayed.. only used one write..
but I will check the code you wrote!!!

Do you want to know if it works??
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Thu Aug 26, 2021 4:33 am     Reply with quote

Hi Ttelmah,
Checked your code and it is working like a charm!!!!!!!!!!!!!
thanks for all your help!!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group