Pages: [1]   Go Down
Author Topic: Problem with temperature from SCP1000 sensor (SPI)  (Read 2112 times)
0 Members and 1 Guest are viewing this topic.
Austria
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all!
I've connected a SCP1000 SPI to my Arduino NG (with Atmega8 processor). I connected it using the instructions at http://www.sparkfun.com/tutorials/65 (Diode version). my problem is, that the temperature is increasing from about 24 °C (which is possible) to about 28 °C in about 20 minutes after powering the device. when i turn on a fan, the temperature gets back to about 24 °C.

I'm using a library I found on the forums a long time ago:
SCP1000.h:
Code:
/**
* SCP1000 Library
*
*
* Manages communication with SCP1000 barometric pressure & temperature sensor
*
*/
#ifndef SCP1000_h
#define SCP1000_h

#include "WProgram.h"


class SCP1000
{
public:
float TempC; // DegC
float BaroP; // in hPa (mbar)

SCP1000(const byte selectPin);
void init();
void readSensor();
void resetSensor();
void setStandby();
void setRunMode();


private:
// I/O Pins
byte _selectPin;

void readPressure();
void readTemperature();
unsigned int read_register(byte register_name, byte numBytes);
void write_register(byte register_name, byte data);
byte spi_transfer(volatile byte data);
};

#endif

SCP1000.cpp
Code:
/*
*
* Manages communication with SCP1000 barometric pressure & temperature sensor
*
*/
#include "WProgram.h"
#include "SCP1000.h"

// Class global constants
const byte DataOutPin = 11;   // MOSI
const byte DataInPin = 12;    // MISO
const byte SPIClockPin = 13;  // SCK

// Register Addresses
const byte REVID = 0x00; // ASIC Revision Number
const byte OPREG = 0x03; // Operation Register
const byte OPSTATUS = 0x04; // Operation Status
const byte STATUS = 0x07; // ASIC Status
const byte PRESSURE = 0x1F; // Pressure 3 MSB
const byte PRESSURE_LSB = 0x20; // Pressure 16 LSB
const byte TEMP = 0x21; // 16 bit temp
const byte RSTR = 0x06; // Soft Reset register

// Mode values
const byte HiResMode = 0x0A; // Hi Resolution, Constant Readings
const byte StandbyMode = 0x00; // No operation





SCP1000::SCP1000(const byte selectPin)
{
// User chosen Slave Select Pin
_selectPin = selectPin;
}

/* ================ Public methods ================ */

void SCP1000::init()
{
// Set Pin directions
pinMode(DataOutPin, OUTPUT);
pinMode(DataInPin, INPUT);
pinMode(SPIClockPin,OUTPUT);
pinMode(_selectPin,OUTPUT);
digitalWrite(_selectPin,HIGH); //disable device 

// Set SPI control register
// SPIE = 0 no interupt
// SPE = 1 SPI enabled
// DORD = 0 (MSB first)
// MSTR = 1 (master)
// CPOL = 0 (clock idle when low)
// CPHA = 0 (samples MOSI on rising edge)
// SPR1 = 1 & SPR0 = 1 (125kHz)
SPCR = 0b01010011;
SPSR = 0b00000000;

delay(100); // Allow SCP1000 to complete initialization
setRunMode();

}

/*
 * Fetch values from the sensor
 */
void SCP1000::readSensor()
{
readTemperature();
readPressure();
}

/*
 * Send a soft reset
 */
void SCP1000::resetSensor()
{
write_register(RSTR, 0x01);
delay(100); // allow time for reset to complete
}

/*
 * Set sensor to standby mode
 * Stops all sensor operations
 */
void SCP1000::setStandby()
{
write_register(OPREG, StandbyMode);
}

/*
 * Set sensor to run mode
 */
void SCP1000::setRunMode()
{
// Set SCP1000 Mode -- Hi resolution, continuous readings
write_register(OPREG, HiResMode);
}

/* ================ Private methods ================ */

/*
* Reads current pressure value
*/
void SCP1000::readPressure()
{
unsigned long pressure;

// Pressure value is in 19-bit unsigned format
// Value = Pa * 4
pressure = read_register(PRESSURE, 1);  // Read MSB
pressure &= 0b00000111; // mask unused bits
pressure <<= 16; // shift into upper word

pressure  |= read_register(PRESSURE_LSB, 2); // read low word

// Convert to real pressure in hPa
BaroP = pressure / 400.0;

}


/*
* Reads the current temperature value
*/
void SCP1000::readTemperature()
{
int temp_in;

// Temperature word is 14-bit signed int = (DegC * 20)
temp_in = read_register(TEMP, 2);

// Shift sign bit (bit 13) to proper position for signed int (bit 15)
// This is equivalent to multiplying by 4, so now temp_in = DegC * 80
temp_in <<= 2;
TempC = temp_in / 80.0; // Convert to real DegC
}

/*
 * Read a register from the device; 1 or 2 bytes
 */
unsigned int SCP1000::read_register(byte register_name, byte numBytes)
{
unsigned int in_word;

// SCP1000 registers are either 1 or 2 bytes long
numBytes = (numBytes > 2) ? 2 : numBytes;  // ensure # of bytes is 0..2

// SCP1000 command format is 6-bit address, 1-bit R/W, and 1-bit "0"
register_name <<= 2; // Shift register address to upper bits
register_name &= 0b11111100; //Read command

digitalWrite(_selectPin,LOW); // Select SPI Device
spi_transfer(register_name); // Send register address to device

for(; numBytes > 0; --numBytes) {
in_word <<= 8; // move existing bits up by one byte
in_word |= spi_transfer(0x00); // add next byte
}

digitalWrite(_selectPin,HIGH); // End Communiction

return(in_word);
}

/*
 * Write single byte to a device register
*/
void SCP1000::write_register(byte register_name, byte data)
{
//SCP1000 command format is 6-bit address, 1-bit R/W, and 1-bit "0"
register_name <<= 2; // Shift register address to upper bits
register_name |= 0b00000010; // Write command

digitalWrite(_selectPin,LOW); //Select SPI device
spi_transfer(register_name); //Send register location
spi_transfer(data); //Send value to record into register
digitalWrite(_selectPin,HIGH); // End Communication

}

/*
 * Transfer single byte over SPI Bus.  Tx & Rx happen simultaneously
 */
byte SCP1000::spi_transfer(volatile byte data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission
{};
return SPDR; // return the received byte
}

my sketch looks like (I shortened it):
Code:
#include <SCP1000.h>

#define SCP_PIN 10        // for the presure/temperature board

SCP1000 scp1000(SCP_PIN);

void setup(void) {
  Serial.begin(9600);
 
  scp1000.init();
}

void loop(void) {
  writeData();
  delay(300); // just sleep some time
}

void writeData() {
  scp1000.setRunMode();
  delay(100);
  scp1000.readSensor();
  scp1000.setStandby();

  writeTemperatureAndPresure();
  Serial.println(); // mark the end
}

void writeTemperatureAndPresure() {
  Serial.print("temperature=");
  Serial.println(scp1000.TempC);
  Serial.print("presure=");
  Serial.println(scp1000.BaroP);
}

I'm looking for some advice to fix the problem.
Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12179
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Move the sensor away from the source of heat or leave the fan on - something is generating heat and without forced ventilation it's building up.  The SCP1000 sensor only takes 25uA so I doubt it's the sensor, probably the Arduino or its power supply?  It might also be radiant heat from some nearby source.
Logged

[ I won't respond to messages, use the forum please ]

0
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm deeply suspicious that the temperature sensor on the SCP1000 is not meant to be use for measuring ambient temperature.

Instead, I think it is there for measuring the die temperature and the value is used to compensate the pressure sensor readings --- it's then given to us as a freebie.  I agree that the chip doesn't draw much current so one wouldn't expect much self heating, but I have noticed that the temp reading can be affected by how often you read the device, so something is going on there.

This is just a guess; I don't mean to malign the device because it is a very good pressure sensor.  I have have measured pressure noise (which determines resolution) of as low as 1.1 Pascal.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

juri I think Bob's right I have just purchased a SCP1000 and noted the same thing the temp seems way off room temp. I had a conversation with a old friend who looked at the data sheet with me and it makes ref to the temp compensation. I did think like your self it was a flaw in the calculation Fahrenheit to degrees C.  My next step is to try and get the SCP1000 displaying the pressure on a 2X16 LCD.
Logged

Regards

Andy

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12179
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm deeply suspicious that the temperature sensor on the SCP1000 is not meant to be use for measuring ambient temperature.

Instead, I think it is there for measuring the die temperature and the value is used to compensate the pressure sensor readings --- it's then given to us as a freebie.  I agree that the chip doesn't draw much current so one wouldn't expect much self heating, but I have noticed that the temp reading can be affected by how often you read the device, so something is going on there.

This is just a guess; I don't mean to malign the device because it is a very good pressure sensor.  I have have measured pressure noise (which determines resolution) of as low as 1.1 Pascal.

The fact that forced ventilation seems to bring the reading back to ambient suggests its quite usable for measuring ambient temp under those conditions - probably fine for a weather station or radiosonde where there's always some breeze available.
Logged

[ I won't respond to messages, use the forum please ]

Austria
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks a lot for your replies. I think my next step will be to add another dedicated temperature sensor I've around to see if both show an increasing temperature. I'll keep you updated on the results (will take some time, I currently don't have much time for that)
Logged

Pages: [1]   Go Up
Jump to: