SCP1000 Barometric Pressure Sensor and Parallax's Basic Stamp II

Here're my notes on connecting the SCP1000 pressure sensor to a Basic Stamp.  I chose to use the Basic stamp 2 because I figured if I could get the code to work on a BS2, then it would work on the other members of the Stamp family (BS2p, BS2pe, BS2px) where you can take advantage of the additional commands, memory, and features (i.e. I2CIN, I2COUT, GET, PUT, program slots, etc.).  So this page has a lot of bit banging to make this work.

The SCP1000 is manufactured by VTI Technologies.  I purchased the sensor from SparkFun Electronics.  They mount the SPI version of the SCP1000 sensor to a breakout board to make it easier to interface.  Since this is a 3.3 volt sensor, I picked up a 3.3v to 5v interface kit from Kronosrobotics.  Kronosrobotics have an app note on interfacing the SCP1000 breakout board using the 3.3v to 5v interface.  I then hooked it up to the BS2 Basic stamp from Parallax Inc using the Professional Development board.  I did a bit of searching the web but didn't found much on interfacing the SCP100 to the Basic Stamp.  So using the technical notes and data sheets from VTI website, I marched ahead.  The documents I used were;  Technical Note TN46 C-code example for SCP1000-D01, Technical Note TN59 SCP1000 series ASIC updateSCP1000-D01-D11 datasheet, and SCP1000 Product Family Specification.  The sensor I got has P01 marking on top of the sensor.  This means use product specification rev 0.06.

Note: Document reference links at the bottom of page in case the links above are broken.

Here is the first test program and sample output of the debug window.

Sample Code #1
Debug window output

The logic of the program #1 is to reset the SCP1000, read the ASIC version, read the status register, write a value to a data register then read it, write and read a number to/from a couple EEPROM locations.  These operations would test directly reading and writing to the registers.  Writing and reading to the EEPROM locations requires the use of indirect routines.

The BASIC program logic was adapted from VTI's Technical Note TN46 C-code example for SCP1000-D01.  The goal was to be able to read and write data to a register.  This was pretty straightforward logicwise but I kept getting the same erroneous response/value when I read a register. After a few hours of thinking, reading the datasheet, and analyzing, I traced it down to the SHIFTIN command.  From the SCP1000 product specification data sheet it sounds like you would sample the bits on the falling edge of the clock. I figured that would be SHIFTIN mode MSBPOST (data is MSB-first; sample bits after clock pulse). I figured this was sampling the MISO line after the data was shifted out.  I changed the mode to MSBPRE and the data appeared.  This first test program verified the logic and subroutines for direct write, direct read, indirect write and indirect read.

Some notes about the subroutines. The SCP1000 has both 8 bit and 16 bit registers.  I wanted one subroutine to handle both types of registers.  The C programming language (as well as other programming languages) allow passing parameters to the subroutines (see TN46 C-code example).  PBASIC doesn't allow for passing parameters to subroutines.  So I came up with checking the register address in the direct read routine.  Normally the NumBits variable is set to 8 bits. If the register address has bit 5 = 1 then its a 16 bit register.  I found mentioned in the product specification sheet that 16 bit registers have bit 5 in the address = 1.  So I setup an if-then statement to handle 8/16 bit register reads.

The other thing I added was a eeprom flag. The reads & writes to the eeprom are indirect.  So if you read/write to a eeprom location, set the eeprom flag before calling the subroutine.

The next step would be to change the program to read the 15-bit temperature and 17-bit pressure.  Here's the sample program I came up with.

Sample Code #2

The program should have enough detail of what is happening.  Here's a couple things about the temperature.  First I only assumed the temperature value was positive.  I'll add the logic to handle negative temperatures in version #3 (Sample Code #3).  The other thing is the decimal output.  According to the data sheet, you take the decimal value read from the temperature register and divide by 20 to get degrees C.  Since the Stamp only does integer math, I multiply the number by 10 before dividing by 20 to get tenths of a degree.

For example, the value from the sensor is 419.

temperature C = 419/20 = 20.95

Integer math would yield 419/20 = 20

Multiply sensor temperature value by 10     (419 * 10)/20 = 209

This allows you to see the tenths of a degree without the decimal point.

 

This next program (sample code 3) continuously reads & displays the temperature and pressure. You can also select the measurement mode.  I pretty much followed the logic of the TN46 C-code example. 

Here's the outline of the program

Define variables
initialize:
   Reset SCP1000 ASIC
   Set low noise mode
   Stop the current mode
   Set measurement mode (hi-res, hi speed or ultra low power)
   Read ASIC revision
   Read status register
main:
   read temperature
   read pressure
   goto main

Sample Code #3

There are a number of comments and debug statements that I used for debugging.  Most are remarked out.  I found that the sensor is quite responsive to temperature changes.

I put some ice in a bag and pressed against the sensor. I was able to get the temperature below 0 C. This is so I can experiment with the negative temperature logic.  The SCP1000 product specification sheet has examples of temperature conversion (section 2.2.3.1).  Basically check bit 13 if it is equal to 1.  If it is then invert the number, AND the result to mask out bits 14 & 15.  Then add 1 to it and change the sign and you get the negative temperature.

Other notes/comments
I added a measurement mode selection to the initialization subroutine.  Set the Measure_Mode variable appropriately and the initialization routine will select high resolution, high speed, or ultra low power measurement mode.

The pressure measurement is a 19 bit value.  The stamp only has 16 bit registers.  The programs only display the hex value.  I captured the pressure & temperature hex values to a file and imported them into Excel.  I then used the HEX2DEC function to convert them to decimal, degrees F & C, kPa, PSI, inHg.  The HEX2DEC function is part of the Analysis ToolPak which you enable via the Tools / Add-ins menu option.  The next goal would be to add the altitude function based on the US Standard Atmosphere 1976.

Another project would be add a Floating Point Coprocessor (see Parallax website) to perform the math functions.

I hope this is of use to others experimenting with the SCP1000.  I think I'll build an altimeter.

Paul

Revised: 02/13/09.

References
Kronosrobotics_SCP1000_interface
SCP1000_Product_Family_Specification_rev_0.06
scp1000_product_family_specification_rev_0.08
scp1000-d01_-d11_pressure_sensor_datasheet_28-08-2007
tn46_c-code_example_for_scp1000-d01_rev_0.1
TN59_SCP1000 series ASIC update_rev_0.1
TN66_SCP1000_FAQ_List_rev_0.2
AN33_SCP1000_Pressure_Sensor_as_barometer_and_altimeter
 

<Back>

<Home>