Using Arduino with the BMP180 - Mercury WWW...

Preview:

Citation preview

Using Arduino with the BMP180 Temperature and Pressure module

Dr. Padraig Houlahan

Dept. of Physics, Embry-Riddle Aeronautical University, Prescott, AZ.

Table of ContentsUsing Arduino with GPS Modules................................................................................................................1

Working with GPS and OLED Displays......................................................................................................3

Software..................................................................................................................................................4

Wiring the project...................................................................................................................................5

Operational considerations.....................................................................................................................6

Web Sources............................................................................................................................................7

Software Listing.......................................................................................................................................8

Working with the BMP180 and OLED Displays

BMP180 temperature and pressure modules are relatively inexpensive and can be purchased for about $10 from Adafruit or Sparkfun – see fig.1 A set of header pins is provided for the user to solder before use.

Fig. 1 The Adafruit GPS module retails for about $40.

In addition, for this project we use Adafruit’s 32x128 LCD/OLED display (see figure 2) so we can display data in real time from the GPS module.

Fig. 2 A 32x128 OLED display – about $17.

SoftwareTo work with these devices we used knowledge and expertise encapsulated in the form of libraries contributed to the community in the form of software libraries, example software, and related documentation. Some sources are vendors; others are hobbyists and enthusiasts. We used the Sparkfun libraries and examples as the basis of our sensor code segments, and Adafruit’s SSD1306 libraries and samples for the OLED display.

The software is included as an appendix to this document, and while not trivial, it does contain the typical elements one would expect for this kind of project.

The only issue encountered with the OLED libraries was that they were written to support general formats and needed to be configured to explicitly support the 32x128 pixel version used here, by adding the statement: #define SSD1306_128_32 to the header file.

Since this particular display is small, in order to allow more information to be shown a simple counter was incremented every time through the main loop, and by using a modulus 2 calculation, two different pages could be displayed in turn.

Wiring the projectWiring up the GPS and OLED modules to an Arduino UNO is straightforward, and shown in Fig. 3.

Fig. 3. Wiring the GPS and OLED display modules to the Arduino UNO

The wiring is as following:

SDL (green) and SDA (blue) support the I2C bus connecting to Arduino analog 4 and 5 ports

BMP180 Vin voltage (red) comes from the Arduino 5v port

BMP180 GPS ground (black) connects to an Arduino GND port

OLED RST (orange) connects to Arduino digital port 4.

OLED voltage (red) is sourced from the Arduino 3.3v port

OLED Ground (black) connects to the remaining GND port

Operational considerationsThis project works well and can detect pressure changes between a floor and a desktop - a compelling demonstration for students! The Arduino power sources seem to be adequate, and a 9v battery was sufficient to allow the system to operate independent of the USB cable.

Sample OLED display screens are shown in figure 4, but the possibilities of further customizations makes for ideal student projects.

Fig. 4. Different screen display produced by the included code. Customized alternating displays show temperature data and pressure data.

Web Sources

BMP180 Support:

https://learn.sparkfun.com/tutorials/bmp180-barometric-pressure-sensor-hookup-/installing-the-arduino-library

https://github.com/adafruit/Adafruit_BMP085_Unified

OLED Support:

https://github.com/adafruit/Adafruit_SSD1306

Software Listing[Heavily based on a sparkfun.com BMP180 example and OLED example from Adafruit.]

#include <SFE_BMP180.h> //sparkfun.com library#include <SPI.h>#include <Wire.h>#include <Adafruit_GFX.h>#include <Adafruit_SSD1306.h>#include <stdlib.h>

SFE_BMP180 pressure;#define ALTITUDE 2130.0 // Flagstaff

#define OLED_RESET 4Adafruit_SSD1306 display(OLED_RESET);

#define LOGO16_GLCD_HEIGHT 16 #define LOGO16_GLCD_WIDTH 16 static const unsigned char PROGMEM logo16_glcd_bmp[] ={ B00000000, B11000000, B00000001, B11000000, B00000001, B11000000, B00000011, B11100000, B11110011, B11100000, B11111110, B11111000, B01111110, B11111111, B00110011, B10011111, B00011111, B11111100, B00001101, B01110000, B00011011, B10100000, B00111111, B11100000, B00111111, B11110000, B01111100, B11110000, B01110000, B01110000, B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 32)#error("Height incorrect, please fix Adafruit_SSD1306.h!");#endif

int count;

void setup() { Serial.begin(9600);

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)

display.display(); delay(1000);

// Clear the buffer. display.clearDisplay();

// draw the first ~12 characters in the font //testdrawchar(); display.display(); delay(2000); display.clearDisplay();

// draw scrolling text testscrolltext(); delay(2000); display.clearDisplay();

// text display tests display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Embry-Riddle!");

display.display(); delay(2000);

if (pressure.begin()) Serial.println("BMP180 init success"); else {

Serial.println("BMP180 init fail\n\n"); while(1); // Pause forever. } display.clearDisplay();}

void loop() { char status, buff[10]; String t_str, p_str; double T,P,p0,a; int res; count = count+1;

Serial.println(); Serial.print("provided altitude: "); Serial.print(ALTITUDE,0); Serial.print(" meters, "); Serial.print(ALTITUDE*3.28084,0); Serial.println(" feet"); status = pressure.startTemperature(); if (status != 0) { delay(status);

status = pressure.getTemperature(T); if (status != 0) { // Print out the measurement: Serial.print("temperature: "); Serial.print(T,2); Serial.print(" deg C, "); Serial.print((9.0/5.0)*T+32.0,2); Serial.println(" deg F"); status = pressure.startPressure(3); if (status != 0) { // Wait for the measurement to complete: delay(status);

status = pressure.getPressure(P,T); if (status != 0) { // Print out the measurement: Serial.print("absolute pressure: "); Serial.print(P,2); Serial.print(" mb, "); Serial.print(P*0.0295333727,2); Serial.println(" inHg");

// The pressure sensor returns abolute pressure, which varies with altitude.

// To remove the effects of altitude, use the sealevel function and your current altitude.

// This number is commonly used in weather reports.

// Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.

// Result: p0 = sea-level compensated pressure in mb

p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)

Serial.print("relative (sea-level) pressure: "); Serial.print(p0,2); Serial.print(" mb, "); Serial.print(p0*0.0295333727,2); Serial.println(" inHg");

// On the other hand, if you want to determine your altitude from the pressure reading,

// use the altitude function along with a baseline pressure (sea-level or other).

// Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.

// Result: a = altitude in m.

a = pressure.altitude(P,p0); Serial.print("computed altitude: "); Serial.print(a,0); Serial.print(" meters, "); Serial.print(a*3.28084,0); Serial.println(" feet"); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,0); dtostrf(T,4,2,buff); t_str = buff; t_str += " oC"; dtostrf(P,4,2,buff); p_str = buff; p_str += " mb"; res=count %2; display.clearDisplay(); if (res ==0 ){ display.println("Temp: "); display.setTextColor(BLACK, WHITE); // 'inverted'

text display.println(t_str);

} else { display.setTextColor(WHITE); display.println("Abs. P: "); display.println(p_str); } display.display(); } else Serial.println("error retrieving pressure

measurement\n"); } else Serial.println("error starting pressure measurement\

n"); } else Serial.println("error retrieving temperature

measurement\n"); } else Serial.println("error starting temperature measurement\

n");

delay(5000); // Pause for 5 seconds.}

void testdrawchar(void) { display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0);

for (uint8_t i=0; i < 168; i++) { if (i == '\n') continue; display.write(i); if ((i > 0) && (i % 21 == 0)) display.println(); } display.display();}

void testscrolltext(void) { display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(10,0); display.clearDisplay(); display.println("ERAU"); display.display(); display.startscrollright(0x00, 0x0F);

delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll();}

Recommended