Pages: 1 [2] 3   Go Down
Author Topic: RTD / PT100 1000 measurement: Library for MCP 3551 22bit ADC.  (Read 10672 times)
0 Members and 1 Guest are viewing this topic.
Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,
Past one month I was testing the MCP3551-PT100 with a UNO and was very successful except very rarely reading shows -247 and ovf. But it happened very rare and for my application, it was okay. But two days back I switched from UNO to ATMEGA 2560 due to the need of extra pins and UNO stopped receiving sketch(some problem). When the time of connection, display shows correct room temperaure for 5-10 seconds then it went to -247 and ovf one after other. Then it didn't shown correct temperature till now. I checked all the connections and everything is OK(infact i changed only the MISO, SCK and SS connections related to MCP3551). I checked byteCode in serial and have seen that it is alternating between 0 and 2097151-2097140). Output showing '-247.14' and "ovf". Cant figure out whats happening..
somebody please help. Please find my sketch below..

Code:
#include <LiquidCrystal.h>
#include <MCP3551.h>
#include <SPI.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
const int pushButton = 8;
const int MCPPin = 53;
float calRAdevice1 = 13340;
float RTD;
const int RZero = 100;
MCP3551 myRTD(MCPPin);
double temperature;
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2); 
  lcd.setCursor(0, 0);                                           
  lcd.print("ADC& PT100");   
  delay (1000);
  pinMode(pushButton, INPUT);
}
void loop() {
  temperature = digitalLowPass(temperature, myRTD.getCode() ,0.90);   
  int buttonState = digitalRead(pushButton);
  bool rtdReady = myRTD.getCode();
  if(rtdReady)
  { // Serial.println(getRTD1.byteCode);   
    //calculate RTD acc. MCP AN1154:
    RTD = calRAdevice1 * (float(myRTD.byteCode) / ( 2097152.0 - float(myRTD.byteCode)));   
    //This is part of a calculation for T(RTD)
    RTD = (RTD / RZero) - 1;
    float temperature = (RTD * (255.8723 + RTD * (9.6 + RTD * 0.878)));   
    lcd.setCursor(0,1);
    lcd.print(temperature);
    Serial.println(temperature);
    Serial.println(myRTD.byteCode);
    delay (500);
  }

double digitalLowPass(double last_smoothed, double new_value, double filterVal)
{
  double smoothed = (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
  return smoothed;
}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13477
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ovf stands for OVERFLOW, so the value exceeds the limits of print.cpp  A fix to be able to print the whole value exists here - http://forum.arduino.cc/index.php?topic=166041.0 -

Can you give the source of the math? 

Quote
I checked byteCode in serial and have seen that it is alternating between 0 and 2097151-2097140).
2097152.0 has so many digits the float precision might be corrupted:  2097152.0 - 2097151 ==> might be 0 ==> causing a divide by zero

can you change these lines to check?
Code:
...
  if (rtdReady)
  {
    // calculate RTD acc. MCP AN1154:
    float divider = 2097152.0 - float(myRTD.byteCode;
    Serial.print("divider: ");
    Serial.println(divider, 4);
   
    RTD = calRAdevice1 * float(myRTDbyteCode) / divider;   
...
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

how did you manage to set the reference voltage (VREF) to 2V? Wouldn't that effect any other analog reading on the Arduino? Did you use a separate LDO? If so, which, and what Capacitors did you choose?

Thanks again,
J.

Equation 3 and Equation 4 show that due to the ratiometric relation, VREF and RB cancel. They do not
influence the code to RTD-resistance conversion.

from AN.

So the only thing to look for would be the current flowing through the RTD.

@rest

To be serious I have not tested that example very well. The focus was laying on the communication and the bytecode processing of the libary.
Also I'm not sure how the 16 bit operations are handled on the 8 bit AVR. So there is a good change for whatever reason to have a division by zero.
Logged


Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
RTD = calRAdevice1 * (float(myRTD.byteCode) / ( 2097152.0 - float(myRTD.byteCode))); 

this is now also strange to me smiley-grin
The only thing I can remember right now was that direct multiplication between calRAdevice and byteCode will always result in an overflow.
Logged


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13477
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also I'm not sure how the 16 bit operations are handled on the 8 bit AVR. So there is a good change for whatever reason to have a division by zero.
it is not 16 bit problem, it is a float (32bit IEEE754) problem.

Quote
The only thing I can remember right now was that direct multiplication between calRAdevice and byteCode will always result in an overflow.
what are typical values for bytecode?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ovf stands for OVERFLOW, so the value exceeds the limits of print.cpp  A fix to be able to print the whole value exists here - http://forum.arduino.cc/index.php?topic=166041.0 -

Can you give the source of the math? 

Quote
I checked byteCode in serial and have seen that it is alternating between 0 and 2097151-2097140).
2097152.0 has so many digits the float precision might be corrupted:  2097152.0 - 2097151 ==> might be 0 ==> causing a divide by zero

can you change these lines to check?
Code:
...
  if (rtdReady)
  {
    // calculate RTD acc. MCP AN1154:
    float divider = 2097152.0 - float(myRTD.byteCode;
    Serial.print("divider: ");
    Serial.println(divider, 4);
   
    RTD = calRAdevice1 * float(myRTDbyteCode) / divider;   
...

I changed the lines as you suggested, please find the code and serial data below..
CODE:

Code:
#include <LiquidCrystal.h>
#include <MCP3551.h>
#include <SPI.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

const int pushButton = 8;
const int MCPPin = 53;
float calRAdevice1 = 13340;
float RTD;
const int RZero = 100;
MCP3551 myRTD(MCPPin);
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2); 
  lcd.setCursor(0, 0);                                           
  lcd.print("MCP3551& PT100");   
  delay (1000);
  pinMode(pushButton, INPUT);
}
void loop() { 
  int buttonState = digitalRead(pushButton);
  bool rtdReady = myRTD.getCode();
  if(rtdReady)
  { // Serial.println(getRTD1.byteCode);   
    //calculate RTD acc. MCP AN1154:   
    float divider = 2097152.0 - float(myRTD.byteCode);
    Serial.print("divider: ");
    Serial.println(divider, 4);   
    RTD = calRAdevice1 * float(myRTD.byteCode) / divider;
    //This is part of a calculation for T(RTD)
    RTD = (RTD / RZero) - 1;
    float temperature = (RTD * (255.8723 + RTD * (9.6 + RTD * 0.878)));   
    Serial.println("Temperature: ");
    Serial.println(temperature);
    Serial.println("code ");
    Serial.println((float(myRTD.byteCode)));
    Serial.println("RTD ");
    Serial.println(RTD);   
    lcd.setCursor(0, 0);                                         
    lcd.print("TEMPERATURE ");                                   
    lcd.setCursor(0, 1);                                         
    lcd.print(temperature);
    delay (1000);
    // A simple method for calibration at 0°C with iced water:
    if (buttonState){
      char n=0;
      float temp=0;
      do
      {
        if (myRTD.getCode());
        {
          temp+= float(myRTD.byteCode);
          n++;
        }
      }
      while (n<10);
      temp /= 10;
      calRAdevice1 = RZero;
      calRAdevice1 /= ( temp /( 2097152.0 - temp));
      delay(2000);
      Serial.print("Ra: ");
      Serial.println(calRAdevice1);
    }
  }
}

SERIAL DATA:

Code:
divider: 2097151.0000
Temperature:
-247.14
code
1.00
RTD
-1.00
divider: 2097152.0000
Temperature:
-247.15
code
0.00
RTD
-1.00
divider: 2097152.0000
Temperature:
-247.15
code
0.00
RTD
-1.00
divider: 2097152.0000
Temperature:
-247.15
code
0.00
RTD
-1.00
divider: 2097152.0000
Temperature:
-247.15
code
0.00
RTD
-1.00
divider: 2097152.0000
Temperature:
-247.15
code
0.00
RTD
-1.00
divider: 2097152.0000




Logged

Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
RTD = calRAdevice1 * (float(myRTD.byteCode) / ( 2097152.0 - float(myRTD.byteCode))); 

this is now also strange to me smiley-grin
The only thing I can remember right now was that direct multiplication between calRAdevice and byteCode will always result in an overflow.


As in my previous post, I checked the setup in UNO over a month satisfactorily. I was about to check the setup in a nearby calibration lab for accuracy (I cross checked with ice and a mercury thermometer[lab grade, calibrated, upto 110C) and thought that it will be nice to change to MEGA(my bad). I made lot of testing and calculations throughout the month, One of them was to check with a trim pot as input and observe the relation between byte code, temperature and RTD. I checked with different resistor values, please see it below

Code:
Trim pot as PT100 >    0        10      25       50       100        150      200      250      300       350      500      800
CODE               >   25      2045    3610      7492     15280      22911     30386     37670     44985     52130    73078   112270
TEMP             >   -246    -215   -191     -130     -5.4      123.4   255.5    390.9    534.2   681.8   1165      2332
RTD                >  -1          -0.87  -0.77    -0.52    -0.02    0.47    0.96       1.44     1.92    2.40    3.82      6.55

I   put the values in excel and got a straight line stating that the setup is liner. So I wonder what caused suddenly the working setup just moved to MEGA caused it to stop working smiley-sad

Logged

Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you measured you resistors? Are they both 6.8 kOhm?
How you have connected the RTD? Two, three, or four conductor?
Looks to me like the values of Ra not correct, because the hardware seems to work well. Or you just measuring the wrong pair of conductors.

Logged


Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes. I measured and tried with different resistors for RA and Rb(6.8k). Also checked PT100( shows 112 ohm) . I even connected 100 ohm resistor in place of PT100. Also changed Another MCP3551. Code is either 0 or 2^21. Is ADC working in that case?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13477
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

weird...
do you have a voltmeter/scope to check the voltage level that enters the ADC, does it shows 'normal' behavior ?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes. Really weird. And it seems I am the only person testing this circuit and sketch.
I checked all the voltages. VREF and VDD getting +5V. Pin 2 & 3(where PT100 connected) showing +5V. Pin 5(SCK) showing 1-1.4 mV. Pin 6(MISO) showing 9-18 mV. Pin 7(CS) showing +5V. Is everuthing Ok?. I am not sure about these values since I didn't checked it when the time its worked smiley-sad
Logged

Kerala, India
Offline Offline
Newbie
*
Karma: 0
Posts: 38
We are the result of 3.8 billion years of evolutionary success. Act like it..
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

robtillaart,
You saved my life. As you can see in my previous post, I checked all the voltages and posted it. Then  suddenly it sparked me that if both the PT100 pins feeding +5V, then how it can convert the temp to voltages. Then I connected a ground pin to Pin number 3 which was there in the original diagram, but the jumper in between confused me. Also last time when I connected this circuit to UNO, I didn't connect this pin to ground. Now I wonder how I was getting correct reading before  smiley-razz. I think sometimes the Pin4(Ground) is accidentally touching the pin 3. Anyway,  robtillaart, thank you for your advice's and valuable help. k4ktus, many many thanks for your wonderful effort and kind help...
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13477
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

welcome
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Lost in Singapore
Offline Offline
Jr. Member
**
Karma: 3
Posts: 74
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah this jumpers are really weird! But the use of them is for connecting 3 and 4 wires to compensate cable length.
Logged


Offline Offline
Jr. Member
**
Karma: 1
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

Am I missng something? What schematic are you guys talking about? The AN1154 does not cover 4 wire PT100´s. So is there any schematic for this circuit to use with wire lenght compensation? Or do you just refer to the MCP3551 Datasheet?

THX,
J.
Logged

Pages: 1 [2] 3   Go Up
Jump to: