Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions examples/SparkFunPressure_Artemis/SparkFunPressure_Artemis.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
MPL3115A2 Barometric Pressure Sensor Library Example Code
By: Nathan Seidle
SparkFun Electronics
Date: September 24th, 2013
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

Uses the MPL3115A2 library to display the current altitude and temperature

This example shows how to connect using alternate I2C ports on the Artemis. Enjoy! PaulZC 19/10/2019

Available functions:
.begin() Gets sensor on the I2C bus.
.readAltitude() Returns float with meters above sealevel. Ex: 1638.94
.readAltitudeFt() Returns float with feet above sealevel. Ex: 5376.68
.readPressure() Returns float with barometric pressure in Pa. Ex: 83351.25
.readTemp() Returns float with current temperature in Celsius. Ex: 23.37
.readTempF() Returns float with current temperature in Fahrenheit. Ex: 73.96
.setModeBarometer() Puts the sensor into Pascal measurement mode.
.setModeAltimeter() Puts the sensor into altimetery mode.
.setModeStandy() Puts the sensor into Standby mode. Required when changing CTRL1 register.
.setModeActive() Start taking measurements!
.setOversampleRate(byte) Sets the # of samples from 1 to 128. See datasheet.
.enableEventFlags() Sets the fundamental event flags. Required during setup.

*/

#include <Wire.h>
#include "SparkFunMPL3115A2.h"

//Define the Artemis TwoWire port for the MPL3115A2
//See the Wire/Example2_MoreI2CPorts example for more details
TwoWire myWire(3); //Will use Artemis pads 42/43, SCL1/SDA1 on the Artemis Thing Plus

//Create an instance of the object
MPL3115A2 myPressure;

void setup()
{
myWire.begin(); // Join i2c bus
Serial.begin(9600); // Start serial for output

myPressure.begin(myWire); // Get sensor online

// Configure the sensor
//myPressure.setModeAltimeter(); // Measure altitude above sea level in meters
myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa

myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
myPressure.enableEventFlags(); // Enable all three pressure and temp event flags
}

void loop()
{
/*float altitude = myPressure.readAltitude();
Serial.print("Altitude(m):");
Serial.print(altitude, 2);

altitude = myPressure.readAltitudeFt();
Serial.print(" Altitude(ft):");
Serial.print(altitude, 2);*/

float pressure = myPressure.readPressure();
Serial.print("Pressure(Pa):");
Serial.print(pressure, 2);

//float temperature = myPressure.readTemp();
//Serial.print(" Temp(c):");
//Serial.print(temperature, 2);

float temperature = myPressure.readTempF();
Serial.print(" Temp(f):");
Serial.print(temperature, 2);

Serial.println();
}
74 changes: 39 additions & 35 deletions src/SparkFunMPL3115A2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
.setOversampleRate(byte) Sets the # of samples from 1 to 128. See datasheet.
.enableEventFlags() Sets the fundamental event flags. Required during setup.

*/
Updated by PaulZC: October 19th, 2019

*/

#include <Wire.h>

Expand All @@ -43,9 +45,11 @@ MPL3115A2::MPL3115A2()
//Begin
/*******************************************************************************************/
//Start I2C communication
void MPL3115A2::begin(void)
void MPL3115A2::begin(TwoWire &wirePort, uint8_t deviceAddress)
{
Wire.begin();
// Let's assume that Wire.begin(); has been done elsewhere
_i2cPort = &wirePort;
_I2Caddress = deviceAddress;
}


Expand All @@ -64,17 +68,17 @@ float MPL3115A2::readAltitude()
}

// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (Wire.requestFrom(MPL3115A2_ADDRESS, 3) != 3) { // Request three bytes
_i2cPort->beginTransmission(_I2Caddress);
_i2cPort->write(OUT_P_MSB); // Address of data to get
_i2cPort->endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (_i2cPort->requestFrom(_I2Caddress, 3) != 3) { // Request three bytes
return -999;
}

byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
msb = _i2cPort->read();
csb = _i2cPort->read();
lsb = _i2cPort->read();

// The least significant bytes l_altitude and l_temp are 4-bit,
// fractional values, so you must cast the calulation in (float),
Expand Down Expand Up @@ -110,25 +114,25 @@ float MPL3115A2::readPressure()
}

// Read pressure registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_P_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (Wire.requestFrom(MPL3115A2_ADDRESS, 3) != 3) { // Request three bytes
_i2cPort->beginTransmission(_I2Caddress);
_i2cPort->write(OUT_P_MSB); // Address of data to get
_i2cPort->endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (_i2cPort->requestFrom(_I2Caddress, 3) != 3) { // Request three bytes
return -999;
}

byte msb, csb, lsb;
msb = Wire.read();
csb = Wire.read();
lsb = Wire.read();
msb = _i2cPort->read();
csb = _i2cPort->read();
lsb = _i2cPort->read();

toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading

// Pressure comes back as a left shifted 20 bit number
long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb;
pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion.

lsb &= B00110000; //Bits 5/4 represent the fractional component
lsb &= 0x3F; // B00110000; //Bits 5/4 represent the fractional component
lsb >>= 4; //Get it right aligned
float pressure_decimal = (float)lsb/4.0; //Turn it into fraction

Expand All @@ -150,21 +154,21 @@ float MPL3115A2::readTemp()
}

// Read temperature registers
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(OUT_T_MSB); // Address of data to get
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (Wire.requestFrom(MPL3115A2_ADDRESS, 2) != 2) { // Request two bytes
_i2cPort->beginTransmission(_I2Caddress);
_i2cPort->write(OUT_T_MSB); // Address of data to get
_i2cPort->endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
if (_i2cPort->requestFrom(_I2Caddress, 2) != 2) { // Request two bytes
return -999;
}

byte msb, lsb;
msb = Wire.read();
lsb = Wire.read();
msb = _i2cPort->read();
lsb = _i2cPort->read();

toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading

//Negative temperature fix by D.D.G.
word foo = 0;
uint16_t foo = 0;
bool negSign = false;

//Check for 2s compliment
Expand Down Expand Up @@ -241,7 +245,7 @@ void MPL3115A2::setOversampleRate(byte sampleRate)
sampleRate <<= 3; //Align it for the CTRL_REG1 register

byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings
tempSetting &= B11000111; //Clear out old OS bits
tempSetting &= 0xc7; // B11000111; //Clear out old OS bits
tempSetting |= sampleRate; //Mask in new OS bits
IIC_Write(CTRL_REG1, tempSetting);
}
Expand Down Expand Up @@ -271,19 +275,19 @@ void MPL3115A2::toggleOneShot(void)
byte MPL3115A2::IIC_Read(byte regAddr)
{
// This function reads one byte over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr); // Address of CTRL_REG1
Wire.endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data...
return Wire.read();
_i2cPort->beginTransmission(_I2Caddress);
_i2cPort->write(regAddr); // Address of CTRL_REG1
_i2cPort->endTransmission(false); // Send data to I2C dev with option for a repeated start. THIS IS NECESSARY and not supported before Arduino V1.0.1!
_i2cPort->requestFrom(_I2Caddress, 1); // Request the data...
return _i2cPort->read();
}

void MPL3115A2::IIC_Write(byte regAddr, byte value)
{
// This function writes one byto over IIC
Wire.beginTransmission(MPL3115A2_ADDRESS);
Wire.write(regAddr);
Wire.write(value);
Wire.endTransmission(true);
_i2cPort->beginTransmission(_I2Caddress);
_i2cPort->write(regAddr);
_i2cPort->write(value);
_i2cPort->endTransmission(true);
}

112 changes: 58 additions & 54 deletions src/SparkFunMPL3115A2.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,75 +7,76 @@

Get pressure, altitude and temperature from the MPL3115A2 sensor.

Updated by PaulZC: October 19th, 2019

*/

#ifndef _SPARKFUN_MPL3115A2_H_
#define _SPARKFUN_MPL3115A2_H_

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <Wire.h>
#include <Arduino.h>

#define MPL3115A2_ADDRESS 0x60 // Unshifted 7-bit I2C address for sensor

#define STATUS 0x00
#define OUT_P_MSB 0x01
#define OUT_P_CSB 0x02
#define OUT_P_LSB 0x03
#define OUT_T_MSB 0x04
#define OUT_T_LSB 0x05
#define DR_STATUS 0x06
#define OUT_P_DELTA_MSB 0x07
#define OUT_P_DELTA_CSB 0x08
#define OUT_P_DELTA_LSB 0x09
#define OUT_T_DELTA_MSB 0x0A
#define OUT_T_DELTA_LSB 0x0B
#define WHO_AM_I 0x0C
#define F_STATUS 0x0D
#define F_DATA 0x0E
#define F_SETUP 0x0F
#define TIME_DLY 0x10
#define SYSMOD 0x11
#define INT_SOURCE 0x12
#define PT_DATA_CFG 0x13
#define BAR_IN_MSB 0x14
#define BAR_IN_LSB 0x15
#define P_TGT_MSB 0x16
#define P_TGT_LSB 0x17
#define T_TGT 0x18
#define P_WND_MSB 0x19
#define P_WND_LSB 0x1A
#define T_WND 0x1B
#define P_MIN_MSB 0x1C
#define P_MIN_CSB 0x1D
#define P_MIN_LSB 0x1E
#define T_MIN_MSB 0x1F
#define T_MIN_LSB 0x20
#define P_MAX_MSB 0x21
#define P_MAX_CSB 0x22
#define P_MAX_LSB 0x23
#define T_MAX_MSB 0x24
#define T_MAX_LSB 0x25
#define CTRL_REG1 0x26
#define CTRL_REG2 0x27
#define CTRL_REG3 0x28
#define CTRL_REG4 0x29
#define CTRL_REG5 0x2A
#define OFF_P 0x2B
#define OFF_T 0x2C
#define OFF_H 0x2D
// Define MPL3115A2 registers
enum mpl3115a2_regs
{
STATUS = 0x00,
OUT_P_MSB = 0x01,
OUT_P_CSB = 0x02,
OUT_P_LSB = 0x03,
OUT_T_MSB = 0x04,
OUT_T_LSB = 0x05,
DR_STATUS = 0x06,
OUT_P_DELTA_MSB = 0x07,
OUT_P_DELTA_CSB = 0x08,
OUT_P_DELTA_LSB = 0x09,
OUT_T_DELTA_MSB = 0x0A,
OUT_T_DELTA_LSB = 0x0B,
WHO_AM_I = 0x0C,
F_STATUS = 0x0D,
F_DATA = 0x0E,
F_SETUP = 0x0F,
TIME_DLY = 0x10,
SYSMOD = 0x11,
INT_SOURCE = 0x12,
PT_DATA_CFG = 0x13,
BAR_IN_MSB = 0x14,
BAR_IN_LSB = 0x15,
P_TGT_MSB = 0x16,
P_TGT_LSB = 0x17,
T_TGT = 0x18,
P_WND_MSB = 0x19,
P_WND_LSB = 0x1A,
T_WND = 0x1B,
P_MIN_MSB = 0x1C,
P_MIN_CSB = 0x1D,
P_MIN_LSB = 0x1E,
T_MIN_MSB = 0x1F,
T_MIN_LSB = 0x20,
P_MAX_MSB = 0x21,
P_MAX_CSB = 0x22,
P_MAX_LSB = 0x23,
T_MAX_MSB = 0x24,
T_MAX_LSB = 0x25,
CTRL_REG1 = 0x26,
CTRL_REG2 = 0x27,
CTRL_REG3 = 0x28,
CTRL_REG4 = 0x29,
CTRL_REG5 = 0x2A,
OFF_P = 0x2B,
OFF_T = 0x2C,
OFF_H = 0x2D
};


class MPL3115A2 {

public:
MPL3115A2();

//Public Functions
void begin(); // Gets sensor on the I2C bus.
void begin(TwoWire &wirePort = Wire, uint8_t deviceAddress = MPL3115A2_ADDRESS); // Gets sensor on the I2C bus.
float readAltitude(); // Returns float with meters above sealevel. Ex: 1638.94
float readAltitudeFt(); // Returns float with feet above sealevel. Ex: 5376.68
float readPressure(); // Returns float with barometric pressure in Pa. Ex: 83351.25
Expand All @@ -99,6 +100,9 @@ class MPL3115A2 {

//Private Variables

TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware
uint8_t _I2Caddress = MPL3115A2_ADDRESS; //Default 7-bit unshifted address of the MPL3115A2

};

#endif // End include guard