Documente Academic
Documente Profesional
Documente Cultură
Some specs
Notes on operation
On timing:
Startup (after first powered, after powerdown, and after reset) takes up to 150ms:
60ms is basically a given wait time
...after which you can either wait for STATUS's STARTUP bit, or just wait
90ms
In SPI, wait for ≥100ns after you assert slave select (more than that may be prudent)
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 1/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
I'm guessing the speed versus resolution is just how much it supersamples. Note that the
pressure value is always retrieved as a 19-bit int (always in the same scale), that the
15/17 bits seems to be an indication of whether the lowest-significance bits should be
considered noise.
While the SCP1000 is an SPI slave, DRDY (both a pin and an internal register bit) is
raised when the module has a new sample ready. You could use it to signal (or interrupt)
the SPI master to service the SPC1000. Since the DRDY state is in a register, you don't
need to use DRDY wire to trigger the master, but it does mean you'll service it faster and
don't need to poll the sensor a lot.
Fast-enough servicing matters because in the continuous sampling modes, the chip
expects you to consume the sample fairly quickly after it raises DRDY. After you read
DATARD16, DRDY will go low again. If you do not read the value in time (that time
depends mostly on refresh speed of the mode), STATUS[RTERR] (bit 4) will become 1,
and you have to read DATARD16 to clear this -- and that read may give nonsense data).
When you cannot guarantee that you'll read out the value fast enough (e.g. on
microcontrollers that can be unpredictably busy), look at triggered mode: it only requires
that you read the data before the next time you trigger(verify). To use triggering, set the
triggered mode, and then either pulse on the TRIG pin (pulse length at least 200ns) or
write 0x0C in the OPERATION register (0x03). The sensor needs some time doing the
actual sample before it raises DRDY (apparently at least 140ms in the 15-bit mode and at
least 500ms in the 17-bit mode). To select the resolution you set 0x05 in CFG for 17 bits
(the default), or 0x0D for 15 bits, before triggering.
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 2/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
(0x03) OPERATION
- set the mode here.
When switching
between modes you
should write 0x00 first
to disable sampling,
then set the mode you
want. Check for
readiness in the status
register - or just wait
for ~50ms(verify))
(0x1F in SPI, 0x7F in
TWI) DATARD8 - the SPC1000's registers (from the datasheet)
3 most significant bits
[2:0] of the 19-bit pressure value
(0x20 in SPI, 0x80 in TWI) DATARD16 - the 16 least significant bits of the 19-bit
pressure data. Note that reading this specific register has other effects
(0x21 in SPI, 0x81 in TWI) TEMPOUT - 14 bits of temperature data in [13:0]
(0x07) STATUS - ASIC status
Bit 0 (STARTUP): 0 if startup has finished, 1 if it's still working
Bit 4 (RTERR): data not read fast enough after DRDY; clear by reading
DATARD16
Bit 5 (DRDY): mirrors DRDY pin
(0x00) CFG, lets you set 17 bits (0x05) or 15 bits (0x0D) and only seems relevant
to triggered mode
There are more, some registers do double service when doing indirect data reads/writes,
and you can read/write the EEPROM, but if you need any of that you can can shoo and
read the PDF.
The pressure data is an integer in the range 120000 (for 30kPa) and 480000 (for 120kPa),
so divide by 4. If the raw figure is outside that range you should treat it as invalid. I've
seen values around four billion.
The temperature data is a signed (two's complement) int, and you divide by 20 for
degrees Celsius (so has ~.05 degrees resolution).
If you take the PD pin high, the sensor will stay powered down (consuming ~0.2 μA),
and the output pins will tristate. If you take PD low to start it up, wait a bit for startup.
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 3/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
See also:
http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/SCP1000-
FamilySpec.pdf
On an Arduino
Most arduinos are 5V and the SCP1000 wants all its pins to be 3.3V (including the SPI
ones), so unless you have one of the few Arduinos that works on 3.3V you'll want to
drop the voltage from 5V to ~3.3V. (It'll work on 5V, but it's probably not very good for
the sensor in the long run).
The easiest way, which cheats a little, is probably to add some inline resistors the lines
(except MISO, as that's powered from the SCP1000), mostly to make the job easier for
the SCP's internal clamping diodes - they can only handle so much current, and you're
limiting how much they'll see.
You may also want to pull up slave select, though this may not be strictly
necessary(verify).
Example code, using an interrupt setup (which means you free your loop() from having
to poll (but make sure there's no noise on the interrupt line)):
/*
* Reads VTI's SCP1000-D01 (SPI) 30-120kPa pressure sensor
*
* Based on some code on the arduino.cc forums by a certain Conor,
* generalized somewhat and adapted to follow the datasheet more,
* although I'm not sure whether this needs more delays,
* as e.g. in the VTI code sample.
*
* This version uses the sensor's DRDY pin to interrupt the Arduino
* (via arduino digital pin 2), which means we don't have to poll
* from the arduino side, and we service the sensor more immediately
* after it's done.
*
* Without that interrupt you would probably poll for the STATUS's DRDY bit:
* if (scp_read_register8(SCP1000_REG_STATUS, SPI_SLAVESELECT)&B00100000)
* service_scp1000();
* I suggest only doing this with triggered mode, to avoid the whole RTERR issue.
*
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 4/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
* You can simplify this code a little (it was stripped from a two-SCP1000 test)
*/
// MOSI, MISO and SCLK are fixed if you use the AVR's hardware SPI
// but you still need to declare them as input/output pins in setup()
#define SPI_SLAVESELECT 10
#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_CLOCK 13
void setup() {
Serial.begin(9600); // For monitoring
// SPI init
byte clr; //dummy variable
pinMode(SPI_MOSI, OUTPUT);
pinMode(SPI_MISO, INPUT );
pinMode(SPI_CLOCK, OUTPUT);
pinMode(SPI_SLAVESELECT, OUTPUT);
digitalWrite(SPI_SLAVESELECT, HIGH); // HIGH: do not select
digitalWrite(SPI_CLOCK, HIGH);
SPCR = B01010011; // MPIE=0 (no interrupt enable)
// SPE=1 (enable SPI)
// DORD=0 (MSB first)
// MSTR=1 (AVR is master)
// CPOL=0 (clock idle when low)
// CPHA=0 (samples on rising edge)
// SPR1=1 & SPR0=1 (250kHz)
clr=SPSR; // clear status register (by just reading it)
clr=SPDR; // clear data register (by just reading it)
//SCP1000 Init: Reset, wait for startup (takes ~60ms because we explicitly wait that long), set sampling mode
scp_write_register(SCP1000_REG_RSTR, 0x01, SPI_SLAVESELECT);
delay(60);
while (scp_read_register8(SCP1000_REG_STATUS, SPI_SLAVESELECT)&B00000001) delay(10);
//presumably the 50ms wait after setting 0x00 mode doesn't apply when we have just reset
//scp_write_register(SCP1000_REG_OPERATION, SCP1000_OPERATION_HIGHRES, SPI_SLAVESELECT);
//scp_write_register(SCP1000_REG_OPERATION, SCP1000_OPERATION_HIGHSPEED, SPI_SLAVESELECT);
//This examples uses (SPI-based) triggering, so the previous two lines (continuous modes) are commented out
//Use a rising edge on Arduino pin 2 (connected to the SCP1000's DRDY pin)
// to service the sensor via an interrupt.
pinMode(2,INPUT);
attachInterrupt(0, service_scp1000, RISING); // interrupt 0: arduino digital pin 2
new_sample=false;
}
void loop() {
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 5/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
if (abs(millis()-last_triggered)>5000) { // For example every five seconds
scp_write_register(SCP1000_REG_OPERATION, SCP1000_OPERATION_TRIGGERED, SPI_SLAVESELECT);
last_triggered=millis();
} else {
// Twiddle our thumbs visibly.
delay(10);
Serial.write('.');
}
// When the interrupt function marks that a new sample is available, print it.
if (new_sample) {
new_sample=false;
Serial.print("\nTemperature: ");
Serial.print(signed_temperature/20.);
Serial.print(" degrees Celsius (raw: ");
Serial.print(temperature_raw);
Serial.print(")\nPressure: ");
Serial.print(pressure_raw/400.);
Serial.print(" millibar (raw: ");
Serial.print(pressure_raw);
Serial.print(")\n\n");
}
}
void service_scp1000() { // Reads the sensor, sets mostly-raw values in global volatile variables
// Theoretically we won't miss a DRDY when it interrupts the uC, but it can't hurt to check
temp_status = scp_read_register8(SCP1000_REG_STATUS, SPI_SLAVESELECT);
if (temp_status&B00010000) {
//if either RTERR was set, clear it by reading data and skip real output
scp_read_register16(SCP1000_REG_DATARD16, SPI_SLAVESELECT);
////check that that worked:
//tstat2 = scp_read_register8(SCP1000_REG_STATUS, SPI_SLAVESELECT1);
//if (tstat2&B00010000) Serial.print("RTERR cleared ");
//else Serial.print("RTERR still there - huh? ");
//Serial.print("\n");
// We give up on this sample and wait for the next.
new_sample=true;
}
/* Asks for pin because this was written to test two SPC1000s on the same bus
*
* The SCP wants its addresses shifted <<2
* with the new bit 0 always 0,
* and bit 1 controls read(0)/write(1)
*/
char scp_read_register8(char register_address, byte select_pin) {
char in_byte;
register_address = register_address<<2;
digitalWrite(select_pin,LOW); //Select SPI Device
spi_transfer(register_address); //Write byte to device
in_byte = spi_transfer();
digitalWrite(select_pin,HIGH);
return in_byte;
}
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 6/7
23/3/2018 SCP1000 pressure sensor notes - Helpful
Note that for continuous sampling and two sensors, waiting for one DRDY and then the
other will mean your reads will be out of sync and you'll eventually not service a DRDY
fast enough. You can choose to miss one sample and rely on checking RTERR and
clearing with a read, but there are various cleverer setups.
https://helpful.knobs-dials.com/index.php/SCP1000_pressure_sensor_notes 7/7