How to connect SCP1000 pressure sensor

Hello,

I'm trying to interface a scp1000 pressure sensor via arduino spi.

I look at the post http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213217330.

But, before running the code, I'd like to know how to connect the SCP Breakout Board (from Sparkfun SEN-08161, MEMs Barometric Pressure Sensor - SCP1000 Breakout - SEN-08161 - SparkFun Electronics) to the Arduino.

Breakout Board pins are : GND, 3.3V, SCK, MOSI, MISO, CSB, DRDY

From the code, pins are defined as follow

#define SLAVESELECT 10
#define SPICLOCK 13
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO

I wired the SCP Breakout Board to the Arduino as follow :

SCK to Pin 13
MOSI to Pin 11
MISO to Pin 12

How do I connect Pin 10 (SLAVESELECT) ? To which SCP Breakout Board pin ?

Mersing.

Before you do anything you should make sure the breakout board an the sensor can handle the 5V Arduino has on it's pins.

Some 3.3 Volt devices are "5 volt tolerant" and some just go up in smoke.

Hi,

VCC is fine, as I'm using an Ardunio Mini Pro 3.3V.

I assume you've already got yours answered, since months have passed.
Well, I could finally manage my SFE SCP1000 breakout board to work with the red 'Arduino Skinny,' after a couple of weeks searching.
Connections I made :
CSB -> SlaveSelect (Pin 10)
SCK -> clock (Pin 13)
MOSI -> (Pin 11)
MISO -> (Pin 12)
Another Noobi question.
Does CSB stand for ChipSelect something?

Thanks,

Bryan.

chip select bar.

Thank you so much, EmilyJane.

my noob questions:
My understanding is that Arduino Skinny or Pro(3v3) supplies 4 pins for SPI protocols, 10,11,12,and 13.
I'd like to measure and record two or three SCP1000 barometer data to my PC.
If I'd like to connect two or three SCP1000 sensor to one of the Arduino series, what would be the better choice for the purpose.

Would a single arduino allow two or three SCP1000's on the 4pins? If not, may I use other pins, e.g., pin 9, or 8, as SlaveSelect?

Would I need more than two arduinos-SCP1000's hooked up to my PC in that case, running two Arduino programs at the same time?

Would the Mega fill the needs?

So many noobie questions.
Thanks

Bryan

Good question. In Spi.h, the SS pin defaults to digital 10. The class definition doesn't seem to allow the creation of more than one instance of Spi either.

That's the reason I'm using the TWI version of the SCP1000. I have an ethernet shield on the Arduino that I'm using multiple SCP1000s on and I couldn't figure out how to have more than one SPI device either.

Sorry. Does anyone else know?

Edit:
Okay, the ATmega SPI hardware doesn't do anything with /SS when it's configured as a master. It's up to the user to control the /SS line. The library configures D10 as an output but doesn't explicitly set it to a level. That means that your software must be setting it low whenever it needs to be low. It also means that you should be able to add more sensors as long as you configure and control more /SS lines.

Hello everybody...

is your sensor working properly ?

Curiously, when I connect the SCP1000 on a SeeDuino, it's working very fine,
But I need a smaller card, and I'm trying to connect it on a StickDuino, or better on a Pro mini 3V. But there, it does'nt work fine.
In first, after the upload, I get 0, 0 for the pressure & temperature.
I need to power off, then power on the Pro mini, after I can obtain a correct valor for the pressure (100300), but no for the temperature (41°C !! in reality it's 26°). and it seems the valors are not very "stable"......41° +/-1 ....?

Any ideas ...?

Thank you, EmilyJane,

TWI version seems to be the choice for the multi-connection. I will check on the TWI version of SCP1000's.

Bryan.

You're welcome. I use this one:

Connect the PD pin of each sensor and enable them one at a time to write a unique address into their slave address register. Also be aware that they use I2C's repeat start protocol on the 8 and 16 bit read register command.

Thank you for your valuable info.

Bryan.

Hi, if I am using this sensor with a Duemilanove can I connect the power supply to the 3.3V supply on the Duemilanove board and the data pins as normal or is there a need to use a logic level conveter?

If you're connecting to a 5V arduino board, check out this page at Spark Fun:

http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=65

It shows how(and why!) to hook up resistors so you don't toast the 3.3V device. I used the resistor network on mine, and usedthe 3.3V on the Decimilia for the power supply for the device. It works fine.

we are using connor's code and an arduino duemilanove, but we are getting random numbers. pressure(kpa) is in the 66xxx and 99xxx range and temp(fahrenheit) is either -58 or 1xx range.

drdy ???
csb pin 10
miso pin 12
mosi pin 11
sck pin 13
3.3v to 3.3v
gnd to gnd
trig ???
pd ???

do trig pd and drdy have to hooked up?

Thanks
Kathy

I also started out with Coner's code and had the same problems. I fixed a couple of errors and got it working great. Since then I've re-written it into a library.

Header file: scp1000.h

/**
* 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

source file: scp1000.cpp

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

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

// 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
}

example usage: readSCP.pde

/* 
*  Read the Barometric Pressure and Temperature values from SCP1000 sensor 
*
*/
 
#include <SCP1000.h>
 
// Specify slave select pin for SCP1000 device
#define SelectPin 10

SCP1000 scp1000(SelectPin);
 
void setup()
{
   Serial.begin(9600); // Open serial connection to report values to host
   Serial.println("Starting up");
   
   scp1000.init();
}
 
void loop()
{


 
  scp1000.readSensor();
  
 
  Serial.print("Temprature (C/F): ");
  Serial.print(scp1000.TempC);
  Serial.print(" / ");
  Serial.println( (1.8*scp1000.TempC + 32) );
  Serial.print("Pressure (hPa): ");
  Serial.println(scp1000.BaroP); 
  Serial.println("---------------------------------");
 
  delay(60000);
}

So far it's working great. :slight_smile:

Oh, I forgot about your other question. You don't need to use the Drdy pin. The Trig and PD pins should be connected to ground via a resistor. If you're using the Sparkfun breakout board, then this is already done on board and you can just ignore these pins.

Dear Dilbert,

Thanks for the great code. and explanation of the pins its great help to us (me and Kathy (who asked question) are working together). Now our sensor seems to be giving relevant values. Thanks a lot once again. Really appreciate the help. :slight_smile:

3nadh

Glad to help, and thanks to Coner et al for the original code.

The code worked for a day and then it starting giving us the same random values. I unplugged the 3.3v pin and the values normalized. we check the temp reading against a thermostat. and the pressure is generally 989-990 indoors which is reasonable.

can anyone explain why the chip is working without the 3.3v pin?

Hmm, that's curious. I don't know why it would work with the power pin disconnected.

Are you level shifting the I/O pins or are you using an Arduino with 3.3v I/O?