From e2fcc1612d657709f18387dbce2d02f950bf9cb2 Mon Sep 17 00:00:00 2001 From: Paul <5690545+PaulZC@users.noreply.github.com> Date: Sat, 19 Oct 2019 14:24:45 +0100 Subject: [PATCH] Updates for Artemis Updates to allow the MPL3115A2 to be connected to the alternate TwoWire ports on the Artemis --- .../SparkFunPressure_Artemis.ino | 76 ++++++++++++ src/SparkFunMPL3115A2.cpp | 74 ++++++------ src/SparkFunMPL3115A2.h | 112 +++++++++--------- 3 files changed, 173 insertions(+), 89 deletions(-) create mode 100644 examples/SparkFunPressure_Artemis/SparkFunPressure_Artemis.ino diff --git a/examples/SparkFunPressure_Artemis/SparkFunPressure_Artemis.ino b/examples/SparkFunPressure_Artemis/SparkFunPressure_Artemis.ino new file mode 100644 index 0000000..2bda9f1 --- /dev/null +++ b/examples/SparkFunPressure_Artemis/SparkFunPressure_Artemis.ino @@ -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 +#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(); +} diff --git a/src/SparkFunMPL3115A2.cpp b/src/SparkFunMPL3115A2.cpp index 0f5dd0a..68f6d63 100644 --- a/src/SparkFunMPL3115A2.cpp +++ b/src/SparkFunMPL3115A2.cpp @@ -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 @@ -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; } @@ -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), @@ -110,17 +114,17 @@ 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 @@ -128,7 +132,7 @@ float MPL3115A2::readPressure() 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 @@ -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 @@ -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); } @@ -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); } diff --git a/src/SparkFunMPL3115A2.h b/src/SparkFunMPL3115A2.h index 14e8446..ec86dac 100644 --- a/src/SparkFunMPL3115A2.h +++ b/src/SparkFunMPL3115A2.h @@ -7,67 +7,68 @@ 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 +#include #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 { @@ -75,7 +76,7 @@ class MPL3115A2 { 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 @@ -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