Barometric Pressure Sensor (SPI)

Read air pressure and temperature from a sensor using the SPI protocol.

Last revision 2018/05/17 by SM

This example shows how to use the SPI (Serial Peripheral Interface) Communications Library to read data from a SCP1000 Barometric Pressure sensor.

Hardware Required

  • Arduino board
  • SCP1000 Pressure Sensor Breakout Board
  • hook-up wires

Circuit

The circuit for this tutorial.
The circuit for this tutorial.

Schematic

The schematic for this tutorial.
The schematic for this tutorial.

The SCP1000 barometric pressure sensor can read both air pressure and temperature and report them via the SPI connection. For details of the control registers, see the SCP1000 data sheet.

Code

The code below starts out by setting the SCP1000's configuration registers in the

setup()
. In the main loop, it sets the sensor to read in high resolution mode, meaning that it will return a 19-bit value, for the pressure reading, and 16 bits for the temperature. The actual reading in degrees Celsius is the 16-bit result divided by 20.

Then it reads the temperature's two bytes. Once it's got the temperature, it reads the pressure in two parts. First it reads the highest three bits, then the lower 16 bits. It combines these two into one single long integer by bit shifting the high bits then using a bitwise OR to combine them with the lower 16 bits. The actual pressure in Pascal is the 19-bit result divide by 4.

1/*
2
3 SCP1000 Barometric Pressure Sensor Display
4
5 Shows the output of a Barometric Pressure Sensor on a
6
7 Uses the SPI library. For details on the sensor, see:
8
9 http://www.sparkfun.com/commerce/product_info.php?products_id=8161
10
11 http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
12
13 This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
14
15 http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
16
17 Circuit:
18
19 SCP1000 sensor attached to pins 6, 7, 10 - 13:
20
21 DRDY: pin 6
22
23 CSB: pin 7
24
25 MOSI: pin 11
26
27 MISO: pin 12
28
29 SCK: pin 13
30
31 created 31 July 2010
32
33 modified 14 August 2010
34
35 by Tom Igoe
36
37 */
38
39// the sensor communicates using SPI, so include the library:
40#include <SPI.h>
41
42//Sensor's memory register addresses:
43
44const int PRESSURE = 0x1F; //3 most significant bits of pressure
45
46const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure
47
48const int TEMPERATURE = 0x21; //16 bit temperature reading
49
50const byte READ = 0b11111100; // SCP1000's read command
51
52const byte WRITE = 0b00000010; // SCP1000's write command
53
54// pins used for the connection with the sensor
55// the other you need are controlled by the SPI library):
56
57const int dataReadyPin = 6;
58
59const int chipSelectPin = 7;
60
61void setup() {
62
63 Serial.begin(9600);
64
65 // start the SPI library:
66
67 SPI.begin();
68
69 // initialize the data ready and chip select pins:
70
71 pinMode(dataReadyPin, INPUT);
72
73 pinMode(chipSelectPin, OUTPUT);
74
75 //Configure SCP1000 for low noise configuration:
76
77 writeRegister(0x02, 0x2D);
78
79 writeRegister(0x01, 0x03);
80
81 writeRegister(0x03, 0x02);
82
83 // give the sensor time to set up:
84
85 delay(100);
86}
87
88void loop() {
89
90 //Select High Resolution Mode
91
92 writeRegister(0x03, 0x0A);
93
94 // don't do anything until the data ready pin is high:
95
96 if (digitalRead(dataReadyPin) == HIGH) {
97
98 //Read the temperature data
99
100 int tempData = readRegister(0x21, 2);
101
102 // convert the temperature to celsius and display it:
103
104 float realTemp = (float)tempData / 20.0;
105
106 Serial.print("Temp[C]=");
107
108 Serial.print(realTemp);
109
110 //Read the pressure data highest 3 bits:
111
112 byte pressure_data_high = readRegister(0x1F, 1);
113
114 pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
115
116 //Read the pressure data lower 16 bits:
117
118 unsigned int pressure_data_low = readRegister(0x20, 2);
119
120 //combine the two parts into one 19-bit number:
121
122 long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
123
124 // display the temperature:
125
126 Serial.println("\tPressure [Pa]=" + String(pressure));
127
128 }
129}
130
131//Read from or write to register from the SCP1000:
132unsigned int readRegister(byte thisRegister, int bytesToRead) {
133
134 byte inByte = 0; // incoming byte from the SPI
135
136 unsigned int result = 0; // result to return
137
138 Serial.print(thisRegister, BIN);
139
140 Serial.print("\t");
141
142 // SCP1000 expects the register name in the upper 6 bits
143
144 // of the byte. So shift the bits left by two bits:
145
146 thisRegister = thisRegister << 2;
147
148 // now combine the address and the command into one byte
149
150 byte dataToSend = thisRegister & READ;
151
152 Serial.println(thisRegister, BIN);
153
154 // take the chip select low to select the device:
155
156 digitalWrite(chipSelectPin, LOW);
157
158 // send the device the register you want to read:
159
160 SPI.transfer(dataToSend);
161
162 // send a value of 0 to read the first byte returned:
163
164 result = SPI.transfer(0x00);
165
166 // decrement the number of bytes left to read:
167
168 bytesToRead--;
169
170 // if you still have another byte to read:
171
172 if (bytesToRead > 0) {
173
174 // shift the first byte left, then get the second byte:
175
176 result = result << 8;
177
178 inByte = SPI.transfer(0x00);
179
180 // combine the byte you just got with the previous one:
181
182 result = result | inByte;
183
184 // decrement the number of bytes left to read:
185
186 bytesToRead--;
187
188 }
189
190 // take the chip select high to de-select:
191
192 digitalWrite(chipSelectPin, HIGH);
193
194 // return the result:
195
196 return (result);
197}
198
199//Sends a write command to SCP1000
200
201void writeRegister(byte thisRegister, byte thisValue) {
202
203 // SCP1000 expects the register address in the upper 6 bits
204
205 // of the byte. So shift the bits left by two bits:
206
207 thisRegister = thisRegister << 2;
208
209 // now combine the register address and the command into one byte:
210
211 byte dataToSend = thisRegister | WRITE;
212
213 // take the chip select low to select the device:
214
215 digitalWrite(chipSelectPin, LOW);
216
217 SPI.transfer(dataToSend); //Send register location
218
219 SPI.transfer(thisValue); //Send value to record into register
220
221 // take the chip select high to de-select:
222
223 digitalWrite(chipSelectPin, HIGH);
224}

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.