├── .gitattributes ├── .gitignore ├── Libraries ├── Arduino │ ├── .gitignore │ ├── README.md │ ├── examples │ │ ├── SparkFunAltimeter │ │ │ └── SparkFunAltimeter.ino │ │ ├── SparkFunBarometricHgInch │ │ │ └── SparkFunBarometricHgInch.ino │ │ ├── SparkFunMPL3115A2 │ │ │ └── SparkFunMPL3115A2.ino │ │ ├── SparkFunMPL3115A2AdvancedExample │ │ │ ├── SparkFunMPL3115A2AdvancedExample.ino │ │ │ ├── defs.h │ │ │ ├── i2c.h │ │ │ └── types.h │ │ ├── SparkFunPressure │ │ │ └── SparkFunPressure.ino │ │ └── SparkFunSimpleSketchMPL3115A2 │ │ │ └── SparkFunSimpleSketchMPL3115A2.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── SparkFunMPL3115A2.cpp │ │ └── SparkFunMPL3115A2.h └── README.md ├── Production └── MPL3115A2_breakout-Panel-v11b.brd ├── README.md ├── firmware ├── MPL3115A2 │ └── MPL3115A2.ino ├── MPL3115A2_FIFO_example │ ├── MPL3115A2_AdvancedExample.ino │ ├── defs.h │ ├── i2c.h │ └── types.h ├── README.md └── SparkFun_Simple_Sketch_MPL3115A2 │ └── SparkFun_Simple_Sketch_mpl3115a2.ino └── hardware ├── MPL3115A2_breakout.brd ├── MPL3115A2_breakout.sch └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.eep 2 | *.elf 3 | *.d 4 | *.o 5 | *.srec 6 | *.map 7 | *.b#? 8 | *.s#? 9 | *.orig 10 | *.epf 11 | -------------------------------------------------------------------------------- /Libraries/Arduino/.gitignore: -------------------------------------------------------------------------------- 1 | *.eep 2 | *.elf 3 | *.d 4 | *.o 5 | *.srec 6 | *.map 7 | *.b#? 8 | *.s#? 9 | *.orig 10 | *.epf 11 | -------------------------------------------------------------------------------- /Libraries/Arduino/README.md: -------------------------------------------------------------------------------- 1 | MPL3115A2 Altitude/Pressure Sensor Breakout 2 | ================== 3 | 4 | [![MPL3115A2 Altitude/Pressure Sensor Breakout](https://dlnmh9ip6v2uc.cloudfront.net/images/products/1/1/0/8/4/11084-01_medium.jpg) 5 | *MPL3115A2 Altitude/Pressure Sensor Breakout (SEN-11084)*](https://www.sparkfun.com/products/11084) 6 | 7 | The MPL3115A2 is a MEMS pressure sensor that provides Altitude data to within 30cm (with oversampling enabled). The sensor outputs are digitized by a high resolution 24-bit ADC and transmitted over I2C, meaning it's easy to interface with most controllers. 8 | 9 | Repository Contents 10 | ------------------- 11 | 12 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. 13 | * **src** - Source files for the library. 14 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. 15 | * **library.properties** - General library properties for the Arduino package manager. 16 | 17 | Documentation 18 | -------------- 19 | 20 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. 21 | * **[Product Repository](https://github.com/sparkfun/MPL3115A2_Breakout)** - Main repository (including hardware files) for the MPL3115A2 altitude/pressure sensor breakout. 22 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/mpl3115a2-pressure-sensor-hookup-guide)** - Basic hookup guide for the MPL3115A2 altitude/pressure sensor breakout. 23 | 24 | License Information 25 | ------------------- 26 | 27 | This product is _**open source**_! 28 | 29 | The **code** is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 30 | 31 | Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license. 32 | 33 | Distributed as-is; no warranty is given. 34 | 35 | - Your friends at SparkFun. 36 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunAltimeter/SparkFunAltimeter.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Barometric Pressure Sensor Library Example Code 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 24th, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | Uses the MPL3115A2 library to display the current altitude and temperature 9 | 10 | Hardware Connections (Breakoutboard to Arduino): 11 | -VCC = 3.3V 12 | -SDA = A4 (use inline 10k resistor if your board is 5V) 13 | -SCL = A5 (use inline 10k resistor if your board is 5V) 14 | -INT pins can be left unconnected for this demo 15 | 16 | During testing, GPS with 9 satellites reported 5393ft, sensor reported 5360ft (delta of 33ft). Very close! 17 | During testing, GPS with 8 satellites reported 1031ft, sensor reported 1021ft (delta of 10ft). 18 | 19 | Available functions: 20 | .begin() Gets sensor on the I2C bus. 21 | .readAltitude() Returns float with meters above sealevel. Ex: 1638.94 22 | .readAltitudeFt() Returns float with feet above sealevel. Ex: 5376.68 23 | .readPressure() Returns float with barometric pressure in Pa. Ex: 83351.25 24 | .readTemp() Returns float with current temperature in Celsius. Ex: 23.37 25 | .readTempF() Returns float with current temperature in Fahrenheit. Ex: 73.96 26 | .setModeBarometer() Puts the sensor into Pascal measurement mode. 27 | .setModeAltimeter() Puts the sensor into altimetery mode. 28 | .setModeStandy() Puts the sensor into Standby mode. Required when changing CTRL1 register. 29 | .setModeActive() Start taking measurements! 30 | .setOversampleRate(byte) Sets the # of samples from 1 to 128. See datasheet. 31 | .enableEventFlags() Sets the fundamental event flags. Required during setup. 32 | 33 | */ 34 | 35 | #include 36 | #include "SparkFunMPL3115A2.h" 37 | 38 | //Create an instance of the object 39 | MPL3115A2 myPressure; 40 | 41 | void setup() 42 | { 43 | Wire.begin(); // Join i2c bus 44 | Serial.begin(9600); // Start serial for output 45 | 46 | myPressure.begin(); // Get sensor online 47 | 48 | //Configure the sensor 49 | myPressure.setModeAltimeter(); // Measure altitude above sea level in meters 50 | //myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 51 | 52 | myPressure.setOversampleRate(7); // Set Oversample to the recommended 128 53 | myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 54 | } 55 | 56 | void loop() 57 | { 58 | //float altitude = myPressure.readAltitude(); 59 | //Serial.print("Altitude(m):"); 60 | //Serial.print(altitude, 2); 61 | 62 | float altitude = myPressure.readAltitudeFt(); 63 | Serial.print(" Altitude(ft):"); 64 | Serial.print(altitude, 2); 65 | 66 | //float pressure = myPressure.readPressure(); 67 | //Serial.print("Pressure(Pa):"); 68 | //Serial.print(pressure, 2); 69 | 70 | //float temperature = myPressure.readTemp(); 71 | //Serial.print(" Temp(c):"); 72 | //Serial.print(temperature, 2); 73 | 74 | float temperature = myPressure.readTempF(); 75 | Serial.print(" Temp(f):"); 76 | Serial.print(temperature, 2); 77 | 78 | Serial.println(); 79 | } 80 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunBarometricHgInch/SparkFunBarometricHgInch.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Barometric Pressure Sensor Library Example Code 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 24th, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This example coverts pressure from Pascals to inches of mercury, altimeter setting adjusted. 9 | This type of pressure reading is used in the USA on Wunderground. I find it SUPER weird, but it 10 | is needed for home weather stations and aircraft. 11 | 12 | You must set the correct altitude (station_elevation_m) below. Find this altitude using 13 | a GPS unit such as your cell phone. Be sure to put the elevation into meters (1meter = 0.3048ft). 14 | 15 | Hardware Connections (Breakoutboard to Arduino): 16 | -VCC = 3.3V 17 | -SDA = A4 (use inline 10k resistor if your board is 5V) 18 | -SCL = A5 (use inline 10k resistor if your board is 5V) 19 | -INT pins can be left unconnected for this demo 20 | 21 | During testing, GPS with 9 satellites reported 5393ft, sensor reported 5360ft (delta of 33ft). Very close! 22 | 23 | */ 24 | 25 | #include 26 | #include "SparkFunMPL3115A2.h" 27 | 28 | //Create an instance of the object 29 | MPL3115A2 myPressure; 30 | 31 | void setup() 32 | { 33 | Wire.begin(); // Join i2c bus 34 | Serial.begin(9600); // Start serial for output 35 | 36 | myPressure.begin(); // Get sensor online 37 | 38 | //Configure the sensor 39 | //myPressure.setModeAltimeter(); // Measure altitude above sea level in meters 40 | myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 41 | 42 | myPressure.setOversampleRate(7); // Set Oversample to the recommended 128 43 | myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 44 | } 45 | 46 | void loop() 47 | { 48 | float pressure = myPressure.readPressure(); 49 | Serial.print("Pressure(Pa):"); 50 | Serial.print(pressure, 2); 51 | 52 | float temperature = myPressure.readTempF(); 53 | Serial.print(" Temp(f):"); 54 | Serial.print(temperature, 2); 55 | 56 | //References: 57 | //Definition of "altimeter setting": http://www.crh.noaa.gov/bou/awebphp/definitions_pressure.php 58 | //Altimeter setting: http://www.srh.noaa.gov/epz/?n=wxcalc_altimetersetting 59 | //Altimeter setting: http://www.srh.noaa.gov/images/epz/wxcalc/altimeterSetting.pdf 60 | //Verified against Boulder, CO readings: http://www.crh.noaa.gov/bou/include/webpres.php?product=webpres.txt 61 | 62 | //const int station_elevation_ft = 5374; //Must be obtained with a GPS unit 63 | //float station_elevation_m = station_elevation_ft * 0.3048; //I'm going to hard code this 64 | const int station_elevation_m = 1638; //Accurate for the roof on my house 65 | //1 pascal = 0.01 millibars 66 | pressure /= 100; //pressure is now in millibars 67 | 68 | float part1 = pressure - 0.3; //Part 1 of formula 69 | 70 | const float part2 = 8.42288 / 100000.0; 71 | float part3 = pow((pressure - 0.3), 0.190284); 72 | float part4 = (float)station_elevation_m / part3; 73 | float part5 = (1.0 + (part2 * part4)); 74 | float part6 = pow(part5, (1.0/0.190284)); 75 | float altimeter_setting_pressure_mb = part1 * part6; //Output is now in adjusted millibars 76 | float baroin = altimeter_setting_pressure_mb * 0.02953; 77 | 78 | Serial.print(" Altimeter setting InHg:"); 79 | Serial.print(baroin, 2); 80 | 81 | Serial.println(); 82 | } 83 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunMPL3115A2/SparkFunMPL3115A2.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Altitude Sensor Example 3 | By: A.Weiss, 7/17/2012, changes Nathan Seidle Sept 23rd, 2013 4 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 5 | 6 | Hardware Connections (Breakoutboard to Arduino): 7 | -VCC = 3.3V 8 | -SDA = A4 9 | -SCL = A5 10 | -INT pins can be left unconnected for this demo 11 | 12 | Usage: 13 | -Serial terminal at 9600bps 14 | -Prints altitude in meters, temperature in degrees C, with 1/16 resolution. 15 | -software enabled interrupt on new data, ~1Hz with full resolution 16 | 17 | During testing, GPS with 9 sattelites reported 5393ft, sensor reported 5360ft (delta of 33ft). Very close! 18 | 19 | */ 20 | 21 | #include // for IIC communication 22 | 23 | #define STATUS 0x00 24 | #define OUT_P_MSB 0x01 25 | #define OUT_P_CSB 0x02 26 | #define OUT_P_LSB 0x03 27 | #define OUT_T_MSB 0x04 28 | #define OUT_T_LSB 0x05 29 | #define DR_STATUS 0x06 30 | #define OUT_P_DELTA_MSB 0x07 31 | #define OUT_P_DELTA_CSB 0x08 32 | #define OUT_P_DELTA_LSB 0x09 33 | #define OUT_T_DELTA_MSB 0x0A 34 | #define OUT_T_DELTA_LSB 0x0B 35 | #define WHO_AM_I 0x0C 36 | #define F_STATUS 0x0D 37 | #define F_DATA 0x0E 38 | #define F_SETUP 0x0F 39 | #define TIME_DLY 0x10 40 | #define SYSMOD 0x11 41 | #define INT_SOURCE 0x12 42 | #define PT_DATA_CFG 0x13 43 | #define BAR_IN_MSB 0x14 44 | #define BAR_IN_LSB 0x15 45 | #define P_TGT_MSB 0x16 46 | #define P_TGT_LSB 0x17 47 | #define T_TGT 0x18 48 | #define P_WND_MSB 0x19 49 | #define P_WND_LSB 0x1A 50 | #define T_WND 0x1B 51 | #define P_MIN_MSB 0x1C 52 | #define P_MIN_CSB 0x1D 53 | #define P_MIN_LSB 0x1E 54 | #define T_MIN_MSB 0x1F 55 | #define T_MIN_LSB 0x20 56 | #define P_MAX_MSB 0x21 57 | #define P_MAX_CSB 0x22 58 | #define P_MAX_LSB 0x23 59 | #define T_MAX_MSB 0x24 60 | #define T_MAX_LSB 0x25 61 | #define CTRL_REG1 0x26 62 | #define CTRL_REG2 0x27 63 | #define CTRL_REG3 0x28 64 | #define CTRL_REG4 0x29 65 | #define CTRL_REG5 0x2A 66 | #define OFF_P 0x2B 67 | #define OFF_T 0x2C 68 | #define OFF_H 0x2D 69 | 70 | #define MPL3115A2_ADDRESS 0x60 // 7-bit I2C address 71 | 72 | long startTime; 73 | 74 | void setup() 75 | { 76 | Wire.begin(); // join i2c bus 77 | Serial.begin(57600); // start serial for output 78 | 79 | if(IIC_Read(WHO_AM_I) == 196) 80 | Serial.println("MPL3115A2 online!"); 81 | else 82 | Serial.println("No response - check connections"); 83 | 84 | // Configure the sensor 85 | setModeAltimeter(); // Measure altitude above sea level in meters 86 | //setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 87 | 88 | setOversampleRate(7); // Set Oversample to the recommended 128 89 | enableEventFlags(); // Enable all three pressure and temp event flags 90 | } 91 | 92 | void loop() 93 | { 94 | startTime = millis(); 95 | 96 | float altitude = readAltitude(); 97 | Serial.print("Altitude(m):"); 98 | Serial.print(altitude, 2); 99 | 100 | //altitude = readAltitudeFt(); 101 | //Serial.print(" Altitude(ft):"); 102 | //Serial.print(altitude, 2); 103 | 104 | /*float pressure = readPressure(); 105 | Serial.print(" Pressure(Pa):"); 106 | Serial.println(pressure, 2);*/ 107 | 108 | //float temperature = readTemp(); 109 | //Serial.print(" Temp(c):"); 110 | //Serial.print(temperature, 2); 111 | 112 | //float temperature = readTempF(); 113 | //Serial.print(" Temp(f):"); 114 | //Serial.print(temperature, 2); 115 | 116 | Serial.print(" time diff:"); 117 | Serial.print(millis() - startTime); 118 | 119 | Serial.println(); 120 | 121 | //delay(1); 122 | } 123 | 124 | //Returns the number of meters above sea level 125 | float readAltitude() 126 | { 127 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 128 | 129 | //Wait for PDR bit, indicates we have new pressure data 130 | int counter = 0; 131 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 132 | { 133 | if(++counter > 100) return(-999); //Error out 134 | delay(1); 135 | } 136 | 137 | // Read pressure registers 138 | Wire.beginTransmission(MPL3115A2_ADDRESS); 139 | Wire.write(OUT_P_MSB); // Address of data to get 140 | 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! 141 | Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes 142 | 143 | //Wait for data to become available 144 | counter = 0; 145 | while(Wire.available() < 3) 146 | { 147 | if(counter++ > 100) return(-999); //Error out 148 | delay(1); 149 | } 150 | 151 | byte msb, csb, lsb; 152 | msb = Wire.read(); 153 | csb = Wire.read(); 154 | lsb = Wire.read(); 155 | 156 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 157 | 158 | // The least significant bytes l_altitude and l_temp are 4-bit, 159 | // fractional values, so you must cast the calulation in (float), 160 | // shift the value over 4 spots to the right and divide by 16 (since 161 | // there are 16 values in 4-bits). 162 | float tempcsb = (lsb>>4)/16.0; 163 | 164 | float altitude = (float)( (msb << 8) | csb) + tempcsb; 165 | 166 | return(altitude); 167 | } 168 | 169 | //Returns the number of feet above sea level 170 | float readAltitudeFt() 171 | { 172 | return(readAltitude() * 3.28084); 173 | } 174 | 175 | //Reads the current pressure in Pa 176 | //Unit must be set in barometric pressure mode 177 | float readPressure() 178 | { 179 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 180 | 181 | //Wait for PDR bit, indicates we have new pressure data 182 | int counter = 0; 183 | while( (IIC_Read(STATUS) & (1<<2)) == 0) 184 | { 185 | if(++counter > 100) return(-999); //Error out 186 | delay(1); 187 | } 188 | 189 | // Read pressure registers 190 | Wire.beginTransmission(MPL3115A2_ADDRESS); 191 | Wire.write(OUT_P_MSB); // Address of data to get 192 | 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! 193 | Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes 194 | 195 | //Wait for data to become available 196 | counter = 0; 197 | while(Wire.available() < 3) 198 | { 199 | if(counter++ > 100) return(-999); //Error out 200 | delay(1); 201 | } 202 | 203 | byte msb, csb, lsb; 204 | msb = Wire.read(); 205 | csb = Wire.read(); 206 | lsb = Wire.read(); 207 | 208 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 209 | 210 | // Pressure comes back as a left shifted 20 bit number 211 | long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb; 212 | pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion. 213 | 214 | lsb &= 0b00110000; //Bits 5/4 represent the fractional component 215 | lsb >>= 4; //Get it right aligned 216 | float pressure_decimal = (float)lsb/4.0; //Turn it into fraction 217 | 218 | float pressure = (float)pressure_whole + pressure_decimal; 219 | 220 | return(pressure); 221 | } 222 | 223 | float readTemp() 224 | { 225 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 226 | 227 | //Wait for TDR bit, indicates we have new temp data 228 | int counter = 0; 229 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 230 | { 231 | if(++counter > 100) return(-999); //Error out 232 | delay(1); 233 | } 234 | 235 | // Read temperature registers 236 | Wire.beginTransmission(MPL3115A2_ADDRESS); 237 | Wire.write(OUT_T_MSB); // Address of data to get 238 | 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! 239 | Wire.requestFrom(MPL3115A2_ADDRESS, 2); // Request two bytes 240 | 241 | //Wait for data to become available 242 | counter = 0; 243 | while(Wire.available() < 2) 244 | { 245 | if(++counter > 100) return(-999); //Error out 246 | delay(1); 247 | } 248 | 249 | byte msb, lsb; 250 | msb = Wire.read(); 251 | lsb = Wire.read(); 252 | 253 | // The least significant bytes l_altitude and l_temp are 4-bit, 254 | // fractional values, so you must cast the calulation in (float), 255 | // shift the value over 4 spots to the right and divide by 16 (since 256 | // there are 16 values in 4-bits). 257 | float templsb = (lsb>>4)/16.0; //temp, fraction of a degree 258 | 259 | float temperature = (float)(msb + templsb); 260 | 261 | return(temperature); 262 | } 263 | 264 | //Give me temperature in fahrenheit! 265 | float readTempF() 266 | { 267 | return((readTemp() * 9.0)/ 5.0 + 32.0); // Convert celsius to fahrenheit 268 | } 269 | 270 | //Sets the mode to Barometer 271 | //CTRL_REG1, ALT bit 272 | void setModeBarometer() 273 | { 274 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 275 | tempSetting &= ~(1<<7); //Clear ALT bit 276 | IIC_Write(CTRL_REG1, tempSetting); 277 | } 278 | 279 | //Sets the mode to Altimeter 280 | //CTRL_REG1, ALT bit 281 | void setModeAltimeter() 282 | { 283 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 284 | tempSetting |= (1<<7); //Set ALT bit 285 | IIC_Write(CTRL_REG1, tempSetting); 286 | } 287 | 288 | //Puts the sensor in standby mode 289 | //This is needed so that we can modify the major control registers 290 | void setModeStandby() 291 | { 292 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 293 | tempSetting &= ~(1<<0); //Clear SBYB bit for Standby mode 294 | IIC_Write(CTRL_REG1, tempSetting); 295 | } 296 | 297 | //Puts the sensor in active mode 298 | //This is needed so that we can modify the major control registers 299 | void setModeActive() 300 | { 301 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 302 | tempSetting |= (1<<0); //Set SBYB bit for Active mode 303 | IIC_Write(CTRL_REG1, tempSetting); 304 | } 305 | 306 | //Setup FIFO mode to one of three modes. See page 26, table 31 307 | //From user jr4284 308 | void setFIFOMode(byte f_Mode) 309 | { 310 | if (f_Mode > 3) f_Mode = 3; // FIFO value cannot exceed 3. 311 | f_Mode <<= 6; // Shift FIFO byte left 6 to put it in bits 6, 7. 312 | 313 | byte tempSetting = IIC_Read(F_SETUP); //Read current settings 314 | tempSetting &= ~(3<<6); // clear bits 6, 7 315 | tempSetting |= f_Mode; //Mask in new FIFO bits 316 | IIC_Write(F_SETUP, tempSetting); 317 | } 318 | 319 | //Call with a rate from 0 to 7. See page 33 for table of ratios. 320 | //Sets the over sample rate. Datasheet calls for 128 but you can set it 321 | //from 1 to 128 samples. The higher the oversample rate the greater 322 | //the time between data samples. 323 | void setOversampleRate(byte sampleRate) 324 | { 325 | if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111 326 | sampleRate <<= 3; //Align it for the CTRL_REG1 register 327 | 328 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 329 | tempSetting &= 0b11000111; //Clear out old OS bits 330 | tempSetting |= sampleRate; //Mask in new OS bits 331 | IIC_Write(CTRL_REG1, tempSetting); 332 | } 333 | 334 | //Clears then sets the OST bit which causes the sensor to immediately take another reading 335 | //Needed to sample faster than 1Hz 336 | void toggleOneShot(void) 337 | { 338 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 339 | tempSetting &= ~(1<<1); //Clear OST bit 340 | IIC_Write(CTRL_REG1, tempSetting); 341 | 342 | tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe 343 | tempSetting |= (1<<1); //Set OST bit 344 | IIC_Write(CTRL_REG1, tempSetting); 345 | } 346 | 347 | //Enables the pressure and temp measurement event flags so that we can 348 | //test against them. This is recommended in datasheet during setup. 349 | void enableEventFlags() 350 | { 351 | IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags 352 | } 353 | 354 | // These are the two I2C functions in this sketch. 355 | byte IIC_Read(byte regAddr) 356 | { 357 | // This function reads one byte over IIC 358 | Wire.beginTransmission(MPL3115A2_ADDRESS); 359 | Wire.write(regAddr); // Address of CTRL_REG1 360 | 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! 361 | Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data... 362 | return Wire.read(); 363 | } 364 | 365 | void IIC_Write(byte regAddr, byte value) 366 | { 367 | // This function writes one byto over IIC 368 | Wire.beginTransmission(MPL3115A2_ADDRESS); 369 | Wire.write(regAddr); 370 | Wire.write(value); 371 | Wire.endTransmission(true); 372 | } 373 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunMPL3115A2AdvancedExample/SparkFunMPL3115A2AdvancedExample.ino: -------------------------------------------------------------------------------- 1 | /* MPL3115A2 Example Code 2 | by: Kris Winer adapted from skeleton codes by Jim Lindblom, A. Weiss, and Nathan Seidle (Thanks guys!) 3 | Modified: February 12, 2014 by Kris Winer 4 | Original date: November 17, 2011, Jim Lindblom, SparkFun Electronics 5 | 6 | IDE example usage for most features of the MPL3115A2 I2C Precision Altimeter. 7 | 8 | Basic functions are implemented including absolute pressure (50 to 110 kPa), altimeter pressure (mmHg), 9 | altitude (meters or feet), and temperature (-40 to 85 C). 10 | 11 | In addition, provision for the FIFO mode in the initialization, watermark/overflow setting, and register 12 | read functions for autonomous data logging over as many as nine hours with 32 data samples of P, T. 13 | 14 | Hardware setup: 15 | MPL3115A2 Breakout ------------ Arduino Mini Pro 3.3 V 16 | 3.3V --------------------- 3.3V 17 | SDA ----------------------- A4 18 | SCL ----------------------- A5 19 | INT2 ---------------------- D4 20 | INT1 ---------------------- D5 21 | GND ---------------------- GND 22 | 23 | SDA and SCL should have external pull-up resistors (to 3.3V) if using a 5 V Arduino. 24 | They should be on the MPL3115A2 SparkFun breakout board. 25 | I didn't need any for the 3.3 V Pro Mini. 26 | 27 | Jim Lindblom's Note: The MMA8452 is an I2C sensor, however this code does 28 | not make use of the Arduino Wire library. Because the sensor 29 | is not 5V tolerant, we can't use the internal pull-ups used 30 | by the Wire library. Instead use the included i2c.h, defs.h and types.h files. 31 | 32 | The MPL3115A2 in this sketch is interfaced with a Pro Mini operating at 3.3 V, so we could use the 33 | Arduino Wire library. However, I will follow Jim Lindblom's example. 34 | 35 | The MPL3115A2 has internal First in/First out data storage enabling autonomous data logging for up to 32 samples 36 | of pressure/altitude and temperature. I programmed the Pro Mini through a FTDI Basic interface board and noticed 37 | every time I hooked it up to the Arduino/Sensor or opened a serial monitor the devices were re-initialized, 38 | defeating the autonomous logging function. 39 | 40 | This was remedied by placing a 10 uF capacitor between reset and ground before either reconnecting the sensor 41 | through the FTDI board or opening a serial monitor. Either event drives the reset low, the capacitor keeps the 42 | reset high long enough to avoid resetting. Of course, the capacitor must be removed when uploading a new or updated 43 | sketch or an error will be generated. 44 | 45 | I got this idea from: 46 | http://electronics.stackexchange.com/questions/24743/arduino-resetting-while-reconnecting-the-serial-terminal 47 | where there is a little more discussion. Thanks 0xAKHIL! 48 | 49 | Lastly, I put a piece of porous foam over the sensor to block ambient light since thre is some indication the 50 | pressure and altitude reading are light sensitive. 51 | 52 | */ 53 | 54 | #include "i2c.h" // not the wire library, can't use pull-ups 55 | #include //include the OLED library to control LCD 56 | 57 | Adafruit_CharacterOLED lcd(OLED_V2, 6, 7, 8, 9, 10, 11, 12); // initialize the LCD library with the numbers of the interface pins 58 | 59 | // make a custom character for degree symbol: 60 | byte degree[8] = { 61 | 0b00100, 62 | 0b01010, 63 | 0b00100, 64 | 0b00000, 65 | 0b00000, 66 | 0b00000, 67 | 0b00000, 68 | 0b00000 69 | }; 70 | 71 | // make a custom character for Mercury symbol: 72 | byte mercury[8] = { 73 | 0b10100, 74 | 0b11100, 75 | 0b10100, 76 | 0b10100, 77 | 0b00011, 78 | 0b00011, 79 | 0b00001, 80 | 0b00011 81 | }; 82 | 83 | // Standard 7-bit I2C slave address is 1100000 = 0x60, 8-bit read address is 0xC1, 8-bit write is 0xC0 84 | #define MPL3115A2_ADDRESS 0x60 // SA0 is high, 0x1C if low 85 | 86 | // Register defines courtesy A. Weiss and Nathan Seidle, SparkFun Electronics 87 | #define STATUS 0x00 88 | #define OUT_P_MSB 0x01 89 | #define OUT_P_CSB 0x02 90 | #define OUT_P_LSB 0x03 91 | #define OUT_T_MSB 0x04 92 | #define OUT_T_LSB 0x05 93 | #define DR_STATUS 0x06 94 | #define OUT_P_DELTA_MSB 0x07 95 | #define OUT_P_DELTA_CSB 0x08 96 | #define OUT_P_DELTA_LSB 0x09 97 | #define OUT_T_DELTA_MSB 0x0A 98 | #define OUT_T_DELTA_LSB 0x0B 99 | #define WHO_AM_I 0x0C 100 | #define F_STATUS 0x0D 101 | #define F_DATA 0x0E 102 | #define F_SETUP 0x0F 103 | #define TIME_DLY 0x10 104 | #define SYSMOD 0x11 105 | #define INT_SOURCE 0x12 106 | #define PT_DATA_CFG 0x13 107 | #define BAR_IN_MSB 0x14 // Set at factory to equivalent sea level pressure for measurement location, generally no need to change 108 | #define BAR_IN_LSB 0x15 // Set at factory to equivalent sea level pressure for measurement location, generally no need to change 109 | #define P_TGT_MSB 0x16 110 | #define P_TGT_LSB 0x17 111 | #define T_TGT 0x18 112 | #define P_WND_MSB 0x19 113 | #define P_WND_LSB 0x1A 114 | #define T_WND 0x1B 115 | #define P_MIN_MSB 0x1C 116 | #define P_MIN_CSB 0x1D 117 | #define P_MIN_LSB 0x1E 118 | #define T_MIN_MSB 0x1F 119 | #define T_MIN_LSB 0x20 120 | #define P_MAX_MSB 0x21 121 | #define P_MAX_CSB 0x22 122 | #define P_MAX_LSB 0x23 123 | #define T_MAX_MSB 0x24 124 | #define T_MAX_LSB 0x25 125 | #define CTRL_REG1 0x26 126 | #define CTRL_REG2 0x27 127 | #define CTRL_REG3 0x28 128 | #define CTRL_REG4 0x29 129 | #define CTRL_REG5 0x2A 130 | #define OFF_P 0x2B 131 | #define OFF_T 0x2C 132 | #define OFF_H 0x2D 133 | 134 | // Define Device inputs 135 | // Integer values between 0 < n < 7 give oversample ratios 2^n and 136 | // sampling intervals of 0=6 ms , 1=10, 2=18, 3=34, 4=66, 5=130, 6=258, and 7=512 137 | const byte SAMPLERATE = 7; // maximum oversample = 7 138 | // Set time between FIFO data points from 1 to 16328 s (For some reason I get a spurious result for ST_Value = 15) 139 | const byte ST_VALUE = 1; // Set auto time step (2^ST_VALUE) seconds 140 | int FIFOon = 1; // Choose realtime data acquisition or FIFO delayed data acquisition; default is real time 141 | int AltimeterMode = 0; // use to choose between altimeter and barometer modes for FIFO data 142 | 143 | // Define device outputs 144 | float altitude = 0.; 145 | float pressure = 0.; 146 | float temperature = 0.; 147 | 148 | // Interrupt Pin definitions 149 | const int int1Pin = 4; // New data available interrupt 150 | // Interrupt events: FIFO, Pressure window, temperature window, pressure threshold, 151 | // temperature threshold, pressure change, and temperature change set in CNTL_REG5 152 | const int int2Pin = 5; 153 | const int readoutPin = 2; // We will allow FIFO data to be serial printed when the readout pin is set to high 154 | 155 | void setup() 156 | { 157 | 158 | Serial.begin(9600); 159 | 160 | // create a degree, mercury symbol characters 161 | lcd.createChar(4, degree); 162 | lcd.createChar(5, mercury); 163 | 164 | lcd.begin(16, 2);// Initialize the LCD with 16 characters and 2 lines 165 | 166 | // Read the WHO_AM_I register, this is a good test of communication 167 | byte c = readRegister(WHO_AM_I); // Read WHO_AM_I register 168 | if (c == 0xC4) // WHO_AM_I should always be 0xC4 169 | { 170 | 171 | MPL3115A2Reset(); // Start off by resetting all registers to the default 172 | 173 | // Set up the interrupt pins, they're set as active high, push-pull 174 | pinMode(int1Pin, INPUT); 175 | digitalWrite(int1Pin, LOW); // Initialize interrupt pins to LOW 176 | pinMode(int2Pin, INPUT); 177 | digitalWrite(int2Pin, LOW);// Initialize interrupt pins to LOW 178 | pinMode(readoutPin, INPUT); 179 | digitalWrite(readoutPin, LOW);// Initialize readout pin to LOW 180 | 181 | SampleRate(SAMPLERATE); // Set oversampling rate 182 | Serial.print("Oversampling Rate is "); Serial.println(SAMPLERATE); 183 | TimeStep(ST_VALUE); // Set data update interval 184 | Serial.print("Data update interval is "); Serial.print((unsigned long) (1 << ST_VALUE)); Serial.println(" seconds"); 185 | MPL3115A2enableEventflags(); 186 | Serial.println("MPL3115A2 event flags enabled..."); 187 | 188 | } 189 | else 190 | { 191 | Serial.print("Could not connect to MPL3115A2: 0x"); 192 | Serial.println(c, HEX); 193 | while(1) ; // Loop forever if communication doesn't happen 194 | } 195 | } 196 | 197 | void loop() 198 | { 199 | 200 | // Currently configured to continuously log data if FIFOon = 1; the FIFO buffer is read and output to a serial monitor 201 | // when digital pin 2 is momentarily set HIGH. The data begins accumulating again after the data read. In the 202 | // initFIFOMPL3115A2() function, the overflow interrupt can be set instead of watermark, then the data log only 203 | // occurs once until the overflow interrupt is triggered on FIFO data register full condition; for some reason, this happens 204 | // after reading 31 not 32 data points. 205 | 206 | if(FIFOon == 1) { 207 | 208 | initFIFOMPL3115A2(); // initialize the accelerometer for delayed (FIFO) acquisition if communication is OK 209 | Serial.println("MPL3115A2 FIFO data acquisition active..."); 210 | if(AltimeterMode) {ActiveAltimeterMode(); Serial.println("Active Altimeter Mode");} // Choose either barometer or altimeter mode 211 | else {ActiveBarometerMode(); Serial.println("Active Barometer Mode");} 212 | 213 | byte rawData[160]; 214 | 215 | // This is similar to the interrupt method in the active data acquisition routine 216 | // Watermark mode should continuously log data and download to serial monitor after readoutPin set HIGH 217 | // Overflow mode should write out the data just once, when the 32 samples have been acquired 218 | // Sensor presumably takes one data read at start; can wait for other 31 data reads before checking interrupts 219 | // 220 | unsigned long count = 1 << ST_VALUE; // Use unsigned long because this number can get quite large! 221 | unsigned long i = 0; 222 | for (i=0; i < 31*count; i++) { 223 | lcd.setCursor(0,0); lcd.print("Wait "); 224 | lcd.setCursor(6,0); lcd.print((31*count - i)); lcd.print("s "); 225 | lcd.setCursor(0,1); lcd.print("in FIFO mode "); 226 | delay(1000); 227 | } 228 | while(digitalRead(int2Pin) == LOW); // Wait for interrupt event on intPin2 229 | while ((readRegister(INT_SOURCE) & 0x40) == 0); Serial.println("Interrupt on FIFO source"); // Wait for interrupt source = FIFO on bit 6 230 | while (readRegister(F_STATUS) & 0x80 | 0x40 == 0); // Should clear the INT_SOURCE bit 231 | Clock(); // capture time overflow condition reached 232 | lcd.setCursor(0,1); lcd.print("Data pts = "); lcd.print((int) (readRegister(F_STATUS)<<2)/4); // Print number of data points successfully acquired 233 | 234 | // We will allow delayed read of FIFO registers by requiring digital pin to go HIGH before read; 235 | // This is useful for autonomous data acquisition applications where the data is collected at one time 236 | // and downloaded to the serial monitor or other output device at another time. This is a poor man's data logger! 237 | while(digitalRead(readoutPin) == LOW); // Wait for the readout pin to go momentarily HIGH before data read 238 | 239 | unsigned long c = readRegister(TIME_DLY); // Check how much time has elapsed since last write; useful for overflow (read once) mode 240 | Serial.print("Time since last write = "); Serial.print(c*count); Serial.println(" seconds"); 241 | 242 | readRegisters(F_DATA, 160, &rawData[0]); // If overflow reached, dump the FIFO data registers 243 | 244 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 245 | // Process the FIFO data buffer contents and print to serial monitor 246 | // Convert all the raw FIFO data to pressure/altitude and temperature 247 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 248 | int j; 249 | for(j = 0; j < 160; j+=5) { 250 | 251 | // Pressure/Altitude bytes 252 | byte msb = rawData[j]; 253 | byte csb = rawData[j+1]; 254 | byte lsb = rawData[j+2]; 255 | // Temperature bytes 256 | byte msbT = rawData[j+3]; 257 | byte lsbT = rawData[j+4]; 258 | 259 | if(AltimeterMode) { 260 | // Calculate altitude, check for negative sign in altimeter data 261 | long foo = 0; 262 | if(msb > 0x7F) { 263 | foo = ~((long)msb << 16 | (long)csb << 8 | (long)lsb) + 1; // 2's complement the data 264 | altitude = (float) (foo >> 8) + (float) ((lsb >> 4)/16.0); // Whole number plus fraction altitude in meters for negative altitude 265 | altitude *= -1.; 266 | } 267 | else { 268 | foo = ((msb << 8) | csb); 269 | altitude = (float) (foo) + (float) ((lsb >> 4)/16.0); // Whole number plus fraction altitude in meters 270 | } 271 | } 272 | else { 273 | long pressure_whole = ((long)msb << 16 | (long)csb << 8 | (long)lsb) ; // Construct whole number pressure 274 | pressure_whole >>= 6; 275 | 276 | lsb &= 0x30; 277 | lsb >>= 4; 278 | float pressure_frac = (float) lsb/4.0; 279 | 280 | pressure = (float) (pressure_whole) + pressure_frac; 281 | } 282 | 283 | // Calculate temperature, check for negative sign 284 | long foo = 0; 285 | if(msbT > 0x7F) { 286 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 287 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 288 | temperature *= -1.; 289 | } 290 | else { 291 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 292 | } 293 | 294 | // Output data array to serial printer; comma delimits useful for importing into excel spreadsheet 295 | Serial.print("Time ,"); Serial.print((j/5)*(1< 0x7F) { 421 | foo = ~((long)msbA << 16 | (long)csbA << 8 | (long)lsbA) + 1; // 2's complement the data 422 | altitude = (float) (foo >> 8) + (float) ((lsbA >> 4)/16.0); // Whole number plus fraction altitude in meters for negative altitude 423 | altitude *= -1.; 424 | } 425 | else { 426 | altitude = (float) ( (msbA << 8) | csbA) + (float) ((lsbA >> 4)/16.0); // Whole number plus fraction altitude in meters 427 | } 428 | 429 | // Calculate temperature, check for negative sign 430 | if(msbT > 0x7F) { 431 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 432 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 433 | temperature *= -1.; 434 | } 435 | else { 436 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 437 | } 438 | } 439 | 440 | void readPressure() 441 | { 442 | byte rawData[5]; // msb/csb/lsb pressure and msb/lsb temperature stored in five contiguous registers 443 | 444 | 445 | // We can read the data either by polling or interrupt; see data sheet for relative advantages 446 | // First we try hardware interrupt, which should take less power, etc. 447 | while (digitalRead(int1Pin) == LOW); // Wait for interrupt pin int1Pin to go HIGH 448 | digitalWrite(int1Pin, LOW); // Reset interrupt pin int1Pin 449 | while((readRegister(INT_SOURCE) & 0x80) == 0); // Check that the interrupt source is a data ready interrupt 450 | // or use a polling method 451 | // Check data read status; if PTDR (bit 4) not set, then 452 | // toggle OST bit to cause sensor to immediately take a reading 453 | // Setting the one shot toggle is the way to get faster than 1 Hz data read rates 454 | // while ((readRegister(STATUS) & 0x08) == 0); // toggleOneShot(); 455 | 456 | readRegisters(OUT_P_MSB, 5, &rawData[0]); // Read the five raw data registers into data array 457 | 458 | // Pressure bytes 459 | byte msbP = rawData[0]; 460 | byte csbP = rawData[1]; 461 | byte lsbP = rawData[2]; 462 | // Temperature bytes 463 | byte msbT = rawData[3]; 464 | byte lsbT = rawData[4]; 465 | 466 | long pressure_whole = ((long)msbP << 16 | (long)csbP << 8 | (long)lsbP) ; // Construct whole number pressure 467 | pressure_whole >>= 6; 468 | 469 | lsbP &= 0x30; 470 | lsbP >>= 4; 471 | float pressure_frac = (float) lsbP/4.0; 472 | 473 | pressure = (float) (pressure_whole) + pressure_frac; 474 | 475 | // Calculate temperature, check for negative sign 476 | long foo = 0; 477 | if(msbT > 0x7F) { 478 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 479 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 480 | temperature *= -1.; 481 | } 482 | else { 483 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 484 | } 485 | } 486 | 487 | /* 488 | ===================================================================================================== 489 | Define functions according to 490 | "Data Manipulation and Basic Settings of the MPL3115A2 Command Line Interface Drive Code" 491 | by Miguel Salhuana 492 | Freescale Semiconductor Application Note AN4519 Rev 0.1, 08/2012 493 | ===================================================================================================== 494 | */ 495 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 496 | // Clears then sets OST bit which causes the sensor to immediately take another reading 497 | void toggleOneShot() 498 | { 499 | MPL3115A2Active(); // Set to active to start reading 500 | byte c = readRegister(CTRL_REG1); 501 | writeRegister(CTRL_REG1, c & ~(1<<1)); // Clear OST (bit 1) 502 | c = readRegister(CTRL_REG1); 503 | writeRegister(CTRL_REG1, c | (1<<1)); // Set OST bit to 1 504 | } 505 | 506 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 507 | // Set the Outputting Sample Rate 508 | void SampleRate(byte samplerate) 509 | { 510 | MPL3115A2Standby(); // Must be in standby to change registers 511 | 512 | byte c = readRegister(CTRL_REG1); 513 | writeRegister(CTRL_REG1, c & ~(0x38)); // Clear OSR bits 3,4,5 514 | if(samplerate < 8) { // OSR between and 7 515 | writeRegister(CTRL_REG1, c | (samplerate << 3)); // Write OSR to bits 3,4,5 516 | } 517 | 518 | MPL3115A2Active(); // Set to active to start reading 519 | } 520 | 521 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 522 | // Initialize the MPL3115A2 registers for FIFO mode 523 | void initFIFOMPL3115A2() 524 | { 525 | // Clear all interrupts by reading the data output registers 526 | byte temp; 527 | temp = readRegister(OUT_P_MSB); 528 | temp = readRegister(OUT_P_CSB); 529 | temp = readRegister(OUT_P_LSB); 530 | temp = readRegister(OUT_T_MSB); 531 | temp = readRegister(OUT_T_LSB); 532 | temp = readRegister(F_STATUS); 533 | 534 | MPL3115A2Standby(); // Must be in standby to change registers 535 | 536 | // Set CTRL_REG4 register to configure interupt enable 537 | // Enable data ready interrupt (bit 7), enable FIFO (bit 6), enable pressure window (bit 5), temperature window (bit 4), 538 | // pressure threshold (bit 3), temperature threshold (bit 2), pressure change (bit 1) and temperature change (bit 0) 539 | writeRegister(CTRL_REG4, 0x40); // enable FIFO 540 | 541 | // Configure INT 1 for data ready, all other (inc. FIFO) interrupts to INT2 542 | writeRegister(CTRL_REG5, 0x80); 543 | 544 | // Set CTRL_REG3 register to configure interupt signal type 545 | // Active HIGH, push-pull interupts INT1 and INT 2 546 | writeRegister(CTRL_REG3, 0x22); 547 | 548 | // Set FIFO mode 549 | writeRegister(F_SETUP, 0x00); // Clear FIFO mode 550 | // writeRegister(F_SETUP, 0x80); // Set F_MODE to interrupt when overflow = 32 reached 551 | writeRegister(F_SETUP, 0x60); // Set F_MODE to accept 32 data samples and interrupt when watermark = 32 reached 552 | 553 | MPL3115A2Active(); // Set to active to start reading 554 | } 555 | 556 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 557 | // Initialize the MPL3115A2 for realtime data collection 558 | void initRealTimeMPL3115A2() 559 | { 560 | // Clear all interrupts by reading the data output registers 561 | byte temp; 562 | temp = readRegister(OUT_P_MSB); 563 | temp = readRegister(OUT_P_CSB); 564 | temp = readRegister(OUT_P_LSB); 565 | temp = readRegister(OUT_T_MSB); 566 | temp = readRegister(OUT_T_LSB); 567 | temp = readRegister(F_STATUS); 568 | 569 | MPL3115A2Standby(); // Must be in standby to change registers 570 | 571 | // Set CTRL_REG4 register to configure interupt enable 572 | // Enable data ready interrupt (bit 7), enable FIFO (bit 6), enable pressure window (bit 5), temperature window (bit 4), 573 | // pressure threshold (bit 3), temperature threshold (bit 2), pressure change (bit 1) and temperature change (bit 0) 574 | writeRegister(CTRL_REG4, 0x80); 575 | 576 | // Configure INT 1 for data ready, all other interrupts to INT2 577 | writeRegister(CTRL_REG5, 0x80); 578 | 579 | // Set CTRL_REG3 register to configure interupt signal type 580 | // Active HIGH, push-pull interupts INT1 and INT 2 581 | writeRegister(CTRL_REG3, 0x22); 582 | 583 | // Set FIFO mode 584 | writeRegister(F_SETUP, 0x00); // disable FIFO mode 585 | 586 | MPL3115A2Active(); // Set to active to start reading 587 | } 588 | 589 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 590 | // Set the Auto Acquisition Time Step 591 | void TimeStep(byte ST_Value) 592 | { 593 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 594 | 595 | byte c = readRegister(CTRL_REG2); // Read contents of register CTRL_REG2 596 | if (ST_Value <= 0xF) { 597 | writeRegister(CTRL_REG2, (c | ST_Value)); // Set time step n from 0x0 to 0xF (bits 0 - 3) for time intervals from 1 to 32768 (2^n) seconds 598 | } 599 | 600 | MPL3115A2Active(); // Set to active to start reading 601 | } 602 | 603 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 604 | // Enable the pressure and temperature event flags 605 | // Bit 2 is general data ready event mode on new Pressure/Altitude or temperature data 606 | // Bit 1 is event flag on new Pressure/Altitude data 607 | // Bit 0 is event flag on new Temperature data 608 | void MPL3115A2enableEventflags() 609 | { 610 | MPL3115A2Standby(); // Must be in standby to change registers 611 | writeRegister(PT_DATA_CFG, 0x07); //Enable all three pressure and temperature event flags 612 | MPL3115A2Active(); // Set to active to start reading 613 | } 614 | 615 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 616 | // Enter Active Altimeter mode 617 | void ActiveAltimeterMode() 618 | { 619 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 620 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 621 | writeRegister(CTRL_REG1, c | (0x80)); // Set ALT (bit 7) to 1 622 | MPL3115A2Active(); // Set to active to start reading 623 | } 624 | 625 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 626 | // Enter Active Barometer mode 627 | void ActiveBarometerMode() 628 | { 629 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 630 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 631 | writeRegister(CTRL_REG1, c & ~(0x80)); // Set ALT (bit 7) to 0 632 | MPL3115A2Active(); // Set to active to start reading 633 | } 634 | 635 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 636 | // Software resets the MPL3115A2. 637 | // It must be in standby to change most register settings 638 | void MPL3115A2Reset() 639 | { 640 | writeRegister(CTRL_REG1, (0x04)); // Set RST (bit 2) to 1 641 | } 642 | 643 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 644 | // Sets the MPL3115A2 to standby mode. 645 | // It must be in standby to change most register settings 646 | void MPL3115A2Standby() 647 | { 648 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 649 | writeRegister(CTRL_REG1, c & ~(0x01)); // Set SBYB (bit 0) to 0 650 | } 651 | 652 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 653 | // Sets the MPL3115A2 to active mode. 654 | // Needs to be in this mode to output data 655 | void MPL3115A2Active() 656 | { 657 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 658 | writeRegister(CTRL_REG1, c | 0x01); // Set SBYB (bit 0) to 1 659 | } 660 | 661 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 662 | // Read i registers sequentially, starting at address into the dest byte array 663 | void readRegisters(byte address, int i, byte * dest) 664 | { 665 | i2cSendStart(); 666 | i2cWaitForComplete(); 667 | 668 | i2cSendByte((MPL3115A2_ADDRESS<<1)); // write 0xB4 669 | i2cWaitForComplete(); 670 | 671 | i2cSendByte(address); // write register address 672 | i2cWaitForComplete(); 673 | 674 | i2cSendStart(); 675 | i2cSendByte((MPL3115A2_ADDRESS<<1)|0x01); // write 0xB5 676 | i2cWaitForComplete(); 677 | for (int j=0; j= 60) { 783 | seconds = seconds - 60; 784 | } // end while 785 | 786 | while(minutes >= 60) { 787 | minutes = minutes - 60; 788 | } // end while 789 | 790 | while(hours > 12) { 791 | hours = hours - 12; 792 | } // end while 793 | 794 | // If seconds less than 10, print a zero in the tens place and seconds thereafter 795 | 796 | if(seconds <= 9) { 797 | lcd.setCursor(6,0); 798 | lcd.print("0"); 799 | lcd.setCursor(7,0); 800 | lcd.print(seconds); 801 | } 802 | 803 | // Otherwise, if seconds greater than 9 print 804 | 805 | else { 806 | lcd.setCursor(6,0); 807 | lcd.print(seconds); 808 | } 809 | 810 | // If minutes less than 10, print a zero in the tens place and minutes thereafter 811 | 812 | if(minutes <= 9) { 813 | lcd.setCursor(3,0); 814 | lcd.print("0"); 815 | lcd.setCursor(4,0); 816 | lcd.print(minutes); 817 | } 818 | 819 | // Otherwise, if minutes greater than 9 print 820 | 821 | else { 822 | lcd.setCursor(3,0); 823 | lcd.print(minutes); 824 | } 825 | 826 | // If hours less than 10, print a zero in the tens place and hours thereafter 827 | 828 | if(hours <= 9) { 829 | lcd.setCursor(0,0); 830 | lcd.print("0"); 831 | lcd.setCursor(1,0); 832 | lcd.print(hours); 833 | } 834 | 835 | // Otherwise, if hours greater than 9 print 836 | 837 | else { 838 | lcd.setCursor(0,0); 839 | lcd.print(hours); 840 | } 841 | 842 | } 843 | 844 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 845 | // End of Sketch MPL3115A2 846 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunMPL3115A2AdvancedExample/defs.h: -------------------------------------------------------------------------------- 1 | /*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ 2 | //***************************************************************************** 3 | // 4 | // File Name : 'avrlibdefs.h' 5 | // Title : AVRlib global defines and macros include file 6 | // Author : Pascal Stang 7 | // Created : 7/12/2001 8 | // Revised : 9/30/2002 9 | // Version : 1.1 10 | // Target MCU : Atmel AVR series 11 | // Editor Tabs : 4 12 | // 13 | // Description : This include file is designed to contain items useful to all 14 | // code files and projects, regardless of specific implementation. 15 | // 16 | // This code is distributed under the GNU Public License 17 | // which can be found at http://www.gnu.org/licenses/gpl.txt 18 | // 19 | //***************************************************************************** 20 | 21 | 22 | #ifndef AVRLIBDEFS_H 23 | #define AVRLIBDEFS_H 24 | 25 | //#define F_CPU 4000000 26 | #define MEM_TYPE 1 27 | 28 | // Code compatibility to new AVR-libc 29 | // outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli() 30 | #ifndef outb 31 | #define outb(addr, data) addr = (data) 32 | #endif 33 | #ifndef inb 34 | #define inb(addr) (addr) 35 | #endif 36 | #ifndef outw 37 | #define outw(addr, data) addr = (data) 38 | #endif 39 | #ifndef inw 40 | #define inw(addr) (addr) 41 | #endif 42 | #ifndef BV 43 | #define BV(bit) (1<<(bit)) 44 | #endif 45 | //#ifndef cbi 46 | // #define cbi(reg,bit) reg &= ~(BV(bit)) 47 | //#endif 48 | //#ifndef sbi 49 | // #define sbi(reg,bit) reg |= (BV(bit)) 50 | //#endif 51 | #ifndef cli 52 | #define cli() __asm__ __volatile__ ("cli" ::) 53 | #endif 54 | #ifndef sei 55 | #define sei() __asm__ __volatile__ ("sei" ::) 56 | #endif 57 | 58 | // support for individual port pin naming in the mega128 59 | // see port128.h for details 60 | #ifdef __AVR_ATmega128__ 61 | // not currently necessary due to inclusion 62 | // of these defines in newest AVR-GCC 63 | // do a quick test to see if include is needed 64 | #ifndef PD0 65 | //#include "port128.h" 66 | #endif 67 | #endif 68 | 69 | // use this for packed structures 70 | // (this is seldom necessary on an 8-bit architecture like AVR, 71 | // but can assist in code portability to AVR) 72 | #define GNUC_PACKED __attribute__((packed)) 73 | 74 | // port address helpers 75 | #define DDR(x) ((x)-1) // address of data direction register of port x 76 | #define PIN(x) ((x)-2) // address of input register of port x 77 | 78 | // MIN/MAX/ABS macros 79 | #define MIN(a,b) ((ab)?(a):(b)) 81 | #define ABS(x) ((x>0)?(x):(-x)) 82 | 83 | // constants 84 | #define PI 3.14159265359 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunMPL3115A2AdvancedExample/i2c.h: -------------------------------------------------------------------------------- 1 | // This library provides the high-level functions needed to use the I2C 2 | // serial interface supported by the hardware of several AVR processors. 3 | #include 4 | #include 5 | #include "types.h" 6 | #include "defs.h" 7 | 8 | // TWSR values (not bits) 9 | // (taken from avr-libc twi.h - thank you Marek Michalkiewicz) 10 | // Master 11 | #define TW_START 0x08 12 | #define TW_REP_START 0x10 13 | // Master Transmitter 14 | #define TW_MT_SLA_ACK 0x18 15 | #define TW_MT_SLA_NACK 0x20 16 | #define TW_MT_DATA_ACK 0x28 17 | #define TW_MT_DATA_NACK 0x30 18 | #define TW_MT_ARB_LOST 0x38 19 | // Master Receiver 20 | #define TW_MR_ARB_LOST 0x38 21 | #define TW_MR_SLA_ACK 0x40 22 | #define TW_MR_SLA_NACK 0x48 23 | #define TW_MR_DATA_ACK 0x50 24 | #define TW_MR_DATA_NACK 0x58 25 | // Slave Transmitter 26 | #define TW_ST_SLA_ACK 0xA8 27 | #define TW_ST_ARB_LOST_SLA_ACK 0xB0 28 | #define TW_ST_DATA_ACK 0xB8 29 | #define TW_ST_DATA_NACK 0xC0 30 | #define TW_ST_LAST_DATA 0xC8 31 | // Slave Receiver 32 | #define TW_SR_SLA_ACK 0x60 33 | #define TW_SR_ARB_LOST_SLA_ACK 0x68 34 | #define TW_SR_GCALL_ACK 0x70 35 | #define TW_SR_ARB_LOST_GCALL_ACK 0x78 36 | #define TW_SR_DATA_ACK 0x80 37 | #define TW_SR_DATA_NACK 0x88 38 | #define TW_SR_GCALL_DATA_ACK 0x90 39 | #define TW_SR_GCALL_DATA_NACK 0x98 40 | #define TW_SR_STOP 0xA0 41 | // Misc 42 | #define TW_NO_INFO 0xF8 43 | #define TW_BUS_ERROR 0x00 44 | 45 | // defines and constants 46 | #define TWCR_CMD_MASK 0x0F 47 | #define TWSR_STATUS_MASK 0xF8 48 | 49 | // return values 50 | #define I2C_OK 0x00 51 | #define I2C_ERROR_NODEV 0x01 52 | 53 | #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask)) 54 | #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask)) 55 | 56 | #define WRITE_sda() DDRC = DDRC | 0b00010000 //SDA must be output when writing 57 | #define READ_sda() DDRC = DDRC & 0b11101111 //SDA must be input when reading - don't forget the resistor on SDA!! 58 | 59 | // functions 60 | 61 | //! Initialize I2C (TWI) interface 62 | void i2cInit(void); 63 | 64 | //! Set the I2C transaction bitrate (in KHz) 65 | void i2cSetBitrate(unsigned short bitrateKHz); 66 | 67 | // Low-level I2C transaction commands 68 | //! Send an I2C start condition in Master mode 69 | void i2cSendStart(void); 70 | //! Send an I2C stop condition in Master mode 71 | void i2cSendStop(void); 72 | //! Wait for current I2C operation to complete 73 | void i2cWaitForComplete(void); 74 | //! Send an (address|R/W) combination or a data byte over I2C 75 | void i2cSendByte(unsigned char data); 76 | //! Receive a data byte over I2C 77 | // ackFlag = TRUE if recevied data should be ACK'ed 78 | // ackFlag = FALSE if recevied data should be NACK'ed 79 | void i2cReceiveByte(unsigned char ackFlag); 80 | //! Pick up the data that was received with i2cReceiveByte() 81 | unsigned char i2cGetReceivedByte(void); 82 | //! Get current I2c bus status from TWSR 83 | unsigned char i2cGetStatus(void); 84 | void delay_ms(uint16_t x); 85 | 86 | // high-level I2C transaction commands 87 | 88 | //! send I2C data to a device on the bus (non-interrupt based) 89 | unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data); 90 | //! receive I2C data from a device on the bus (non-interrupt based) 91 | unsigned char i2cMasterReceiveNI(unsigned char deviceAddr, unsigned char length, unsigned char *data); 92 | 93 | /********************* 94 | ****I2C Functions**** 95 | *********************/ 96 | 97 | void i2cInit(void) 98 | { 99 | // set i2c bit rate to 40KHz 100 | i2cSetBitrate(100); 101 | // enable TWI (two-wire interface) 102 | sbi(TWCR, TWEN); // Enable TWI 103 | } 104 | 105 | void i2cSetBitrate(unsigned short bitrateKHz) 106 | { 107 | unsigned char bitrate_div; 108 | // set i2c bitrate 109 | // SCL freq = F_CPU/(16+2*TWBR)) 110 | cbi(TWSR, TWPS0); 111 | cbi(TWSR, TWPS1); 112 | 113 | //calculate bitrate division 114 | bitrate_div = ((F_CPU/4000l)/bitrateKHz); 115 | if(bitrate_div >= 16) 116 | bitrate_div = (bitrate_div-16)/2; 117 | outb(TWBR, bitrate_div); 118 | } 119 | 120 | void i2cSendStart(void) 121 | { 122 | WRITE_sda(); 123 | // send start condition 124 | TWCR = (1< 0 ; x--){ 184 | for ( y = 0 ; y < 90 ; y++){ 185 | for ( z = 0 ; z < 6 ; z++){ 186 | asm volatile ("nop"); 187 | } 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunMPL3115A2AdvancedExample/types.h: -------------------------------------------------------------------------------- 1 | //useful things to include in code 2 | 3 | #ifndef TYPES_H 4 | #define TYPES_H 5 | 6 | #ifndef WIN32 7 | // true/false defines 8 | #define FALSE 0 9 | #define TRUE -1 10 | #endif 11 | 12 | // datatype definitions macros 13 | typedef unsigned char u08; 14 | typedef signed char s08; 15 | typedef unsigned short u16; 16 | typedef signed short s16; 17 | typedef unsigned long u32; 18 | typedef signed long s32; 19 | typedef unsigned long long u64; 20 | typedef signed long long s64; 21 | 22 | /* use inttypes.h instead 23 | // C99 standard integer type definitions 24 | typedef unsigned char uint8_t; 25 | typedef signed char int8_t; 26 | typedef unsigned short uint16_t; 27 | typedef signed short int16_t; 28 | typedef unsigned long uint32_t; 29 | typedef signed long int32_t; 30 | typedef unsigned long uint64_t; 31 | typedef signed long int64_t; 32 | */ 33 | // maximum value that can be held 34 | // by unsigned data types (8,16,32bits) 35 | #define MAX_U08 255 36 | #define MAX_U16 65535 37 | #define MAX_U32 4294967295 38 | 39 | // maximum values that can be held 40 | // by signed data types (8,16,32bits) 41 | #define MIN_S08 -128 42 | #define MAX_S08 127 43 | #define MIN_S16 -32768 44 | #define MAX_S16 32767 45 | #define MIN_S32 -2147483648 46 | #define MAX_S32 2147483647 47 | 48 | #ifndef WIN32 49 | // more type redefinitions 50 | typedef unsigned char BOOL; 51 | typedef unsigned char BYTE; 52 | typedef unsigned int WORD; 53 | typedef unsigned long DWORD; 54 | 55 | typedef unsigned char UCHAR; 56 | typedef unsigned int UINT; 57 | typedef unsigned short USHORT; 58 | typedef unsigned long ULONG; 59 | 60 | typedef char CHAR; 61 | typedef int INT; 62 | typedef long LONG; 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunPressure/SparkFunPressure.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Barometric Pressure Sensor Library Example Code 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 24th, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | Uses the MPL3115A2 library to display the current altitude and temperature 9 | 10 | Hardware Connections (Breakoutboard to Arduino): 11 | -VCC = 3.3V 12 | -SDA = A4 (use inline 10k resistor if your board is 5V) 13 | -SCL = A5 (use inline 10k resistor if your board is 5V) 14 | -INT pins can be left unconnected for this demo 15 | 16 | During testing, GPS with 9 satellites reported 5393ft, sensor reported 5360ft (delta of 33ft). Very close! 17 | During testing, GPS with 8 satellites reported 1031ft, sensor reported 1021ft (delta of 10ft). 18 | 19 | Available functions: 20 | .begin() Gets sensor on the I2C bus. 21 | .readAltitude() Returns float with meters above sealevel. Ex: 1638.94 22 | .readAltitudeFt() Returns float with feet above sealevel. Ex: 5376.68 23 | .readPressure() Returns float with barometric pressure in Pa. Ex: 83351.25 24 | .readTemp() Returns float with current temperature in Celsius. Ex: 23.37 25 | .readTempF() Returns float with current temperature in Fahrenheit. Ex: 73.96 26 | .setModeBarometer() Puts the sensor into Pascal measurement mode. 27 | .setModeAltimeter() Puts the sensor into altimetery mode. 28 | .setModeStandy() Puts the sensor into Standby mode. Required when changing CTRL1 register. 29 | .setModeActive() Start taking measurements! 30 | .setOversampleRate(byte) Sets the # of samples from 1 to 128. See datasheet. 31 | .enableEventFlags() Sets the fundamental event flags. Required during setup. 32 | 33 | */ 34 | 35 | #include 36 | #include "SparkFunMPL3115A2.h" 37 | 38 | //Create an instance of the object 39 | MPL3115A2 myPressure; 40 | 41 | void setup() 42 | { 43 | Wire.begin(); // Join i2c bus 44 | Serial.begin(9600); // Start serial for output 45 | 46 | myPressure.begin(); // Get sensor online 47 | 48 | // Configure the sensor 49 | //myPressure.setModeAltimeter(); // Measure altitude above sea level in meters 50 | myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 51 | 52 | myPressure.setOversampleRate(7); // Set Oversample to the recommended 128 53 | myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 54 | } 55 | 56 | void loop() 57 | { 58 | /*float altitude = myPressure.readAltitude(); 59 | Serial.print("Altitude(m):"); 60 | Serial.print(altitude, 2); 61 | 62 | altitude = myPressure.readAltitudeFt(); 63 | Serial.print(" Altitude(ft):"); 64 | Serial.print(altitude, 2);*/ 65 | 66 | float pressure = myPressure.readPressure(); 67 | Serial.print("Pressure(Pa):"); 68 | Serial.print(pressure, 2); 69 | 70 | //float temperature = myPressure.readTemp(); 71 | //Serial.print(" Temp(c):"); 72 | //Serial.print(temperature, 2); 73 | 74 | float temperature = myPressure.readTempF(); 75 | Serial.print(" Temp(f):"); 76 | Serial.print(temperature, 2); 77 | 78 | Serial.println(); 79 | } -------------------------------------------------------------------------------- /Libraries/Arduino/examples/SparkFunSimpleSketchMPL3115A2/SparkFunSimpleSketchMPL3115A2.ino: -------------------------------------------------------------------------------- 1 | 2 | /****************************************************************************** 3 | 4 | 5 | 6 | 7 | 8 | Simple Sketch to get started. 9 | 10 | This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 11 | Distributed as-is; no warranty is given. 12 | */ 13 | 14 | // PIR example 15 | #include 16 | #include 17 | #include 18 | 19 | SoftwareSerial display(3, 2); 20 | 21 | //Create an instance of the object 22 | MPL3115A2 myPressure; 23 | 24 | char pastring[10]; 25 | char tmpstring[10]; 26 | 27 | float pressure; 28 | float temperature; 29 | 30 | int ipress; 31 | int itemp; 32 | 33 | void setup() 34 | { 35 | Wire.begin(); // Join i2c bus 36 | Serial.begin(9600); // Start serial for output 37 | 38 | myPressure.begin(); // Get sensor online 39 | 40 | myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 41 | 42 | myPressure.setOversampleRate(7); // Set Oversample to the recommended 128 43 | myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 44 | 45 | display.begin(9600); 46 | Serial.begin(9600); 47 | delay(500); 48 | 49 | display.write(254); // move cursor to beginning of first line 50 | display.write(128); 51 | 52 | display.write(" "); // clear display 53 | display.write(" "); 54 | } 55 | 56 | void loop() 57 | { 58 | pressure = myPressure.readPressure(); 59 | ipress = pressure; 60 | sprintf(pastring, "%3d", ipress); 61 | 62 | Serial.print("Pressure(Pa): "); 63 | Serial.print(pastring); 64 | 65 | display.write("Pres (Pa): "); 66 | display.write(pastring); 67 | 68 | temperature = myPressure.readTempF(); 69 | itemp = temperature; 70 | sprintf(tmpstring, "%3d", itemp); 71 | 72 | Serial.print(" Temp(f): "); 73 | Serial.print(temperature, 2); 74 | 75 | display.write("Temp (f): "); 76 | display.write(tmpstring); 77 | 78 | Serial.println(); 79 | 80 | display.write(254); // move cursor to beginning of first line 81 | display.write(128); 82 | 83 | delay(100); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /Libraries/Arduino/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | MPL3115A2 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | readAltitude KEYWORD2 17 | readAltitudeFt KEYWORD2 18 | readPressure KEYWORD2 19 | readTemp KEYWORD2 20 | readTempF KEYWORD2 21 | setModeBarometer KEYWORD2 22 | setModeAltimeter KEYWORD2 23 | setModeStandby KEYWORD2 24 | setModeActive KEYWORD2 25 | setOversampleRate KEYWORD2 26 | enableEventFlags KEYWORD2 27 | 28 | ####################################### 29 | # Constants (LITERAL1) 30 | ####################################### -------------------------------------------------------------------------------- /Libraries/Arduino/library.properties: -------------------------------------------------------------------------------- 1 | name=SparkFun MPL3115A2 Altitude and Pressure Sensor Breakout 2 | version=1.2.0 3 | author=SparkFun Electronics 4 | maintainer=SparkFun Electronics 5 | sentence=SparkFun's breakout for the Freescale MPL3115A2 Precision Altimeter 6 | paragraph=Breakout board for MEMS altitude sensor capable of 30cm altitude resolution. 7 | category=Sensors 8 | url=https://github.com/sparkfun/SparkFun_MPL3115A2_Breakout_Arduino_Library 9 | architectures=* -------------------------------------------------------------------------------- /Libraries/Arduino/src/SparkFunMPL3115A2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Barometric Pressure Sensor Library 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 22nd, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | This library allows an Arduino to read from the MPL3115A2 low-cost high-precision pressure sensor. 9 | 10 | If you have feature suggestions or need support please use the github support page: https://github.com/sparkfun/MPL3115A2_Breakout 11 | 12 | Hardware Setup: The MPL3115A2 lives on the I2C bus. Attach the SDA pin to A4, SCL to A5. Use inline 10k resistors 13 | if you have a 5V board. If you are using the SparkFun breakout board you *do not* need 4.7k pull-up resistors 14 | on the bus (they are built-in). 15 | 16 | Link to the breakout board product: 17 | 18 | Software: 19 | .begin() Gets sensor on the I2C bus. 20 | .readAltitude() Returns float with meters above sealevel. Ex: 1638.94 21 | .readAltitudeFt() Returns float with feet above sealevel. Ex: 5376.68 22 | .readPressure() Returns float with barometric pressure in Pa. Ex: 83351.25 23 | .readTemp() Returns float with current temperature in Celsius. Ex: 23.37 24 | .readTempF() Returns float with current temperature in Fahrenheit. Ex: 73.96 25 | .setModeBarometer() Puts the sensor into Pascal measurement mode. 26 | .setModeAltimeter() Puts the sensor into altimetery mode. 27 | .setModeStandy() Puts the sensor into Standby mode. Required when changing CTRL1 register. 28 | .setModeActive() Start taking measurements! 29 | .setOversampleRate(byte) Sets the # of samples from 1 to 128. See datasheet. 30 | .enableEventFlags() Sets the fundamental event flags. Required during setup. 31 | 32 | */ 33 | 34 | #include 35 | 36 | #include "SparkFunMPL3115A2.h" 37 | 38 | MPL3115A2::MPL3115A2() 39 | { 40 | //Set initial values for private vars 41 | } 42 | 43 | //Begin 44 | /*******************************************************************************************/ 45 | //Start I2C communication 46 | void MPL3115A2::begin(void) 47 | { 48 | Wire.begin(); 49 | } 50 | 51 | 52 | //Returns the number of meters above sea level 53 | //Returns -1 if no new data is available 54 | float MPL3115A2::readAltitude() 55 | { 56 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 57 | 58 | //Wait for PDR bit, indicates we have new pressure data 59 | int counter = 0; 60 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 61 | { 62 | if(++counter > 600) return(-999); //Error out after max of 512ms for a read 63 | delay(1); 64 | } 65 | 66 | // Read pressure registers 67 | Wire.beginTransmission(MPL3115A2_ADDRESS); 68 | Wire.write(OUT_P_MSB); // Address of data to get 69 | 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! 70 | if (Wire.requestFrom(MPL3115A2_ADDRESS, 3) != 3) { // Request three bytes 71 | return -999; 72 | } 73 | 74 | byte msb, csb, lsb; 75 | msb = Wire.read(); 76 | csb = Wire.read(); 77 | lsb = Wire.read(); 78 | 79 | // The least significant bytes l_altitude and l_temp are 4-bit, 80 | // fractional values, so you must cast the calulation in (float), 81 | // shift the value over 4 spots to the right and divide by 16 (since 82 | // there are 16 values in 4-bits). 83 | float tempcsb = (lsb>>4)/16.0; 84 | 85 | float altitude = (float)( (msb << 8) | csb) + tempcsb; 86 | 87 | return(altitude); 88 | } 89 | 90 | //Returns the number of feet above sea level 91 | float MPL3115A2::readAltitudeFt() 92 | { 93 | return(readAltitude() * 3.28084); 94 | } 95 | 96 | //Reads the current pressure in Pa 97 | //Unit must be set in barometric pressure mode 98 | //Returns -1 if no new data is available 99 | float MPL3115A2::readPressure() 100 | { 101 | //Check PDR bit, if it's not set then toggle OST 102 | if(IIC_Read(STATUS) & (1<<2) == 0) toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 103 | 104 | //Wait for PDR bit, indicates we have new pressure data 105 | int counter = 0; 106 | while(IIC_Read(STATUS) & (1<<2) == 0) 107 | { 108 | if(++counter > 600) return(-999); //Error out after max of 512ms for a read 109 | delay(1); 110 | } 111 | 112 | // Read pressure registers 113 | Wire.beginTransmission(MPL3115A2_ADDRESS); 114 | Wire.write(OUT_P_MSB); // Address of data to get 115 | 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! 116 | if (Wire.requestFrom(MPL3115A2_ADDRESS, 3) != 3) { // Request three bytes 117 | return -999; 118 | } 119 | 120 | byte msb, csb, lsb; 121 | msb = Wire.read(); 122 | csb = Wire.read(); 123 | lsb = Wire.read(); 124 | 125 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 126 | 127 | // Pressure comes back as a left shifted 20 bit number 128 | long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb; 129 | pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion. 130 | 131 | lsb &= B00110000; //Bits 5/4 represent the fractional component 132 | lsb >>= 4; //Get it right aligned 133 | float pressure_decimal = (float)lsb/4.0; //Turn it into fraction 134 | 135 | float pressure = (float)pressure_whole + pressure_decimal; 136 | 137 | return(pressure); 138 | } 139 | 140 | float MPL3115A2::readTemp() 141 | { 142 | if(IIC_Read(STATUS) & (1<<1) == 0) toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 143 | 144 | //Wait for TDR bit, indicates we have new temp data 145 | int counter = 0; 146 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 147 | { 148 | if(++counter > 600) return(-999); //Error out after max of 512ms for a read 149 | delay(1); 150 | } 151 | 152 | // Read temperature registers 153 | Wire.beginTransmission(MPL3115A2_ADDRESS); 154 | Wire.write(OUT_T_MSB); // Address of data to get 155 | 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! 156 | if (Wire.requestFrom(MPL3115A2_ADDRESS, 2) != 2) { // Request two bytes 157 | return -999; 158 | } 159 | 160 | byte msb, lsb; 161 | msb = Wire.read(); 162 | lsb = Wire.read(); 163 | 164 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 165 | 166 | //Negative temperature fix by D.D.G. 167 | word foo = 0; 168 | bool negSign = false; 169 | 170 | //Check for 2s compliment 171 | if(msb > 0x7F) 172 | { 173 | foo = ~((msb << 8) + lsb) + 1; //2’s complement 174 | msb = foo >> 8; 175 | lsb = foo & 0x00F0; 176 | negSign = true; 177 | } 178 | 179 | // The least significant bytes l_altitude and l_temp are 4-bit, 180 | // fractional values, so you must cast the calulation in (float), 181 | // shift the value over 4 spots to the right and divide by 16 (since 182 | // there are 16 values in 4-bits). 183 | float templsb = (lsb>>4)/16.0; //temp, fraction of a degree 184 | 185 | float temperature = (float)(msb + templsb); 186 | 187 | if (negSign) temperature = 0 - temperature; 188 | 189 | return(temperature); 190 | } 191 | 192 | //Give me temperature in fahrenheit! 193 | float MPL3115A2::readTempF() 194 | { 195 | return((readTemp() * 9.0)/ 5.0 + 32.0); // Convert celsius to fahrenheit 196 | } 197 | 198 | //Sets the mode to Barometer 199 | //CTRL_REG1, ALT bit 200 | void MPL3115A2::setModeBarometer() 201 | { 202 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 203 | tempSetting &= ~(1<<7); //Clear ALT bit 204 | IIC_Write(CTRL_REG1, tempSetting); 205 | } 206 | 207 | //Sets the mode to Altimeter 208 | //CTRL_REG1, ALT bit 209 | void MPL3115A2::setModeAltimeter() 210 | { 211 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 212 | tempSetting |= (1<<7); //Set ALT bit 213 | IIC_Write(CTRL_REG1, tempSetting); 214 | } 215 | 216 | //Puts the sensor in standby mode 217 | //This is needed so that we can modify the major control registers 218 | void MPL3115A2::setModeStandby() 219 | { 220 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 221 | tempSetting &= ~(1<<0); //Clear SBYB bit for Standby mode 222 | IIC_Write(CTRL_REG1, tempSetting); 223 | } 224 | 225 | //Puts the sensor in active mode 226 | //This is needed so that we can modify the major control registers 227 | void MPL3115A2::setModeActive() 228 | { 229 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 230 | tempSetting |= (1<<0); //Set SBYB bit for Active mode 231 | IIC_Write(CTRL_REG1, tempSetting); 232 | } 233 | 234 | //Call with a rate from 0 to 7. See page 33 for table of ratios. 235 | //Sets the over sample rate. Datasheet calls for 128 but you can set it 236 | //from 1 to 128 samples. The higher the oversample rate the greater 237 | //the time between data samples. 238 | void MPL3115A2::setOversampleRate(byte sampleRate) 239 | { 240 | if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111 241 | sampleRate <<= 3; //Align it for the CTRL_REG1 register 242 | 243 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 244 | tempSetting &= B11000111; //Clear out old OS bits 245 | tempSetting |= sampleRate; //Mask in new OS bits 246 | IIC_Write(CTRL_REG1, tempSetting); 247 | } 248 | 249 | //Enables the pressure and temp measurement event flags so that we can 250 | //test against them. This is recommended in datasheet during setup. 251 | void MPL3115A2::enableEventFlags() 252 | { 253 | IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags 254 | } 255 | 256 | //Clears then sets the OST bit which causes the sensor to immediately take another reading 257 | //Needed to sample faster than 1Hz 258 | void MPL3115A2::toggleOneShot(void) 259 | { 260 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 261 | tempSetting &= ~(1<<1); //Clear OST bit 262 | IIC_Write(CTRL_REG1, tempSetting); 263 | 264 | tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe 265 | tempSetting |= (1<<1); //Set OST bit 266 | IIC_Write(CTRL_REG1, tempSetting); 267 | } 268 | 269 | 270 | // These are the two I2C functions in this sketch. 271 | byte MPL3115A2::IIC_Read(byte regAddr) 272 | { 273 | // This function reads one byte over IIC 274 | Wire.beginTransmission(MPL3115A2_ADDRESS); 275 | Wire.write(regAddr); // Address of CTRL_REG1 276 | 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! 277 | Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data... 278 | return Wire.read(); 279 | } 280 | 281 | void MPL3115A2::IIC_Write(byte regAddr, byte value) 282 | { 283 | // This function writes one byto over IIC 284 | Wire.beginTransmission(MPL3115A2_ADDRESS); 285 | Wire.write(regAddr); 286 | Wire.write(value); 287 | Wire.endTransmission(true); 288 | } 289 | 290 | -------------------------------------------------------------------------------- /Libraries/Arduino/src/SparkFunMPL3115A2.h: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Barometric Pressure Sensor Library 3 | By: Nathan Seidle 4 | SparkFun Electronics 5 | Date: September 24th, 2013 6 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 7 | 8 | Get pressure, altitude and temperature from the MPL3115A2 sensor. 9 | 10 | */ 11 | 12 | #ifndef _SPARKFUN_MPL3115A2_H_ 13 | #define _SPARKFUN_MPL3115A2_H_ 14 | 15 | #if defined(ARDUINO) && ARDUINO >= 100 16 | #include "Arduino.h" 17 | #else 18 | #include "WProgram.h" 19 | #endif 20 | 21 | #include 22 | 23 | #define MPL3115A2_ADDRESS 0x60 // Unshifted 7-bit I2C address for sensor 24 | 25 | #define STATUS 0x00 26 | #define OUT_P_MSB 0x01 27 | #define OUT_P_CSB 0x02 28 | #define OUT_P_LSB 0x03 29 | #define OUT_T_MSB 0x04 30 | #define OUT_T_LSB 0x05 31 | #define DR_STATUS 0x06 32 | #define OUT_P_DELTA_MSB 0x07 33 | #define OUT_P_DELTA_CSB 0x08 34 | #define OUT_P_DELTA_LSB 0x09 35 | #define OUT_T_DELTA_MSB 0x0A 36 | #define OUT_T_DELTA_LSB 0x0B 37 | #define WHO_AM_I 0x0C 38 | #define F_STATUS 0x0D 39 | #define F_DATA 0x0E 40 | #define F_SETUP 0x0F 41 | #define TIME_DLY 0x10 42 | #define SYSMOD 0x11 43 | #define INT_SOURCE 0x12 44 | #define PT_DATA_CFG 0x13 45 | #define BAR_IN_MSB 0x14 46 | #define BAR_IN_LSB 0x15 47 | #define P_TGT_MSB 0x16 48 | #define P_TGT_LSB 0x17 49 | #define T_TGT 0x18 50 | #define P_WND_MSB 0x19 51 | #define P_WND_LSB 0x1A 52 | #define T_WND 0x1B 53 | #define P_MIN_MSB 0x1C 54 | #define P_MIN_CSB 0x1D 55 | #define P_MIN_LSB 0x1E 56 | #define T_MIN_MSB 0x1F 57 | #define T_MIN_LSB 0x20 58 | #define P_MAX_MSB 0x21 59 | #define P_MAX_CSB 0x22 60 | #define P_MAX_LSB 0x23 61 | #define T_MAX_MSB 0x24 62 | #define T_MAX_LSB 0x25 63 | #define CTRL_REG1 0x26 64 | #define CTRL_REG2 0x27 65 | #define CTRL_REG3 0x28 66 | #define CTRL_REG4 0x29 67 | #define CTRL_REG5 0x2A 68 | #define OFF_P 0x2B 69 | #define OFF_T 0x2C 70 | #define OFF_H 0x2D 71 | 72 | class MPL3115A2 { 73 | 74 | public: 75 | MPL3115A2(); 76 | 77 | //Public Functions 78 | void begin(); // Gets sensor on the I2C bus. 79 | float readAltitude(); // Returns float with meters above sealevel. Ex: 1638.94 80 | float readAltitudeFt(); // Returns float with feet above sealevel. Ex: 5376.68 81 | float readPressure(); // Returns float with barometric pressure in Pa. Ex: 83351.25 82 | float readTemp(); // Returns float with current temperature in Celsius. Ex: 23.37 83 | float readTempF(); // Returns float with current temperature in Fahrenheit. Ex: 73.96 84 | void setModeBarometer(); // Puts the sensor into Pascal measurement mode. 85 | void setModeAltimeter(); // Puts the sensor into altimetery mode. 86 | void setModeStandby(); // Puts the sensor into Standby mode. Required when changing CTRL1 register. 87 | void setModeActive(); // Start taking measurements! 88 | void setOversampleRate(byte); // Sets the # of samples from 1 to 128. See datasheet. 89 | void enableEventFlags(); // Sets the fundamental event flags. Required during setup. 90 | 91 | //Public Variables 92 | 93 | private: 94 | //Private Functions 95 | 96 | void toggleOneShot(); 97 | byte IIC_Read(byte regAddr); 98 | void IIC_Write(byte regAddr, byte value); 99 | 100 | //Private Variables 101 | 102 | }; 103 | 104 | #endif // End include guard 105 | -------------------------------------------------------------------------------- /Libraries/README.md: -------------------------------------------------------------------------------- 1 | SparkFun MPL3115A2 Breakout Libraries 2 | ================================= 3 | 4 | Libraries for use in different environments. 5 | 6 | 7 | Directory Contents 8 | ------------------- 9 | * **/Arduino** - [Arduino IDE](http://www.arduino.cc/en/Main/Software) libraries 10 | 11 | 12 | License Information 13 | ------------------- 14 | This product is open source! 15 | The code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 16 | Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license. 17 | 18 | Distributed as-is; no warranty is given. 19 | 20 | - Your friends at SparkFun. 21 | 22 | MPL3115A2_Advance Example.ino was developed by Kris Winer. 23 | 24 | 25 | 26 | BUILD INSTRUCTIONS: 27 | 28 | $git subtree add -P --squash 29 | 30 | $git subtree pull -P --squash -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SparkFun MPL3115A2 Altitude/Pressure Sensor Breakout 2 | ==================================================== 3 | 4 | [![MPL3115A2 Altitude/Pressure Sensor Breakout](https://dlnmh9ip6v2uc.cloudfront.net/images/products/1/1/0/8/4/11084-01_medium.jpg) 5 | *MPL3115A2 Altitude/Pressure Sensor Breakout (SEN-11084)*](https://www.sparkfun.com/products/11084) 6 | 7 | The MPL3115A2 is a MEMS pressure sensor that provides Altitude data to within 30cm (with oversampling enabled). The sensor outputs are digitized by a high resolution 24-bit ADC and transmitted over I2C, meaning it's easy to interface with most controllers. 8 | 9 | Repository Contents 10 | ------------------- 11 | * **/Firmware** - Example Arduino sketch to use with the sensor. 12 | * **/Hardware** - All Eagle design files (.brd, .sch) 13 | * **/Libraries** - All Arduino libraries 14 | 15 | Documentation 16 | -------------- 17 | * **[Library](https://github.com/sparkfun/SparkFun_MPL3115A2_Breakout_Arduino_Library)** - Arduino library for the MPL3115A2. 18 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/mpl3115a2-pressure-sensor-hookup-guide)** - Basic hookup guide for the MPL3115A2 Breakout. 19 | * **[SparkFun Fritzing repo](https://github.com/sparkfun/Fritzing_Parts)** - Fritzing diagrams for SparkFun products. 20 | * **[SparkFun 3D Model repo](https://github.com/sparkfun/3D_Models)** - 3D models of SparkFun products. 21 | 22 | License Information 23 | ------------------- 24 | The hardware is released under [Creative Commons ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/). 25 | The code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 26 | 27 | Distributed as-is; no warranty is given. 28 | -------------------------------------------------------------------------------- /firmware/MPL3115A2/MPL3115A2.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MPL3115A2 Altitude Sensor Example 3 | By: A.Weiss, 7/17/2012, changes Nathan Seidle Sept 23rd, 2013 4 | License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). 5 | 6 | Hardware Connections (Breakoutboard to Arduino): 7 | -VCC = 3.3V 8 | -SDA = A4 9 | -SCL = A5 10 | -INT pins can be left unconnected for this demo 11 | 12 | Usage: 13 | -Serial terminal at 9600bps 14 | -Prints altitude in meters, temperature in degrees C, with 1/16 resolution. 15 | -software enabled interrupt on new data, ~1Hz with full resolution 16 | 17 | During testing, GPS with 9 sattelites reported 5393ft, sensor reported 5360ft (delta of 33ft). Very close! 18 | 19 | */ 20 | 21 | #include // for IIC communication 22 | 23 | #define STATUS 0x00 24 | #define OUT_P_MSB 0x01 25 | #define OUT_P_CSB 0x02 26 | #define OUT_P_LSB 0x03 27 | #define OUT_T_MSB 0x04 28 | #define OUT_T_LSB 0x05 29 | #define DR_STATUS 0x06 30 | #define OUT_P_DELTA_MSB 0x07 31 | #define OUT_P_DELTA_CSB 0x08 32 | #define OUT_P_DELTA_LSB 0x09 33 | #define OUT_T_DELTA_MSB 0x0A 34 | #define OUT_T_DELTA_LSB 0x0B 35 | #define WHO_AM_I 0x0C 36 | #define F_STATUS 0x0D 37 | #define F_DATA 0x0E 38 | #define F_SETUP 0x0F 39 | #define TIME_DLY 0x10 40 | #define SYSMOD 0x11 41 | #define INT_SOURCE 0x12 42 | #define PT_DATA_CFG 0x13 43 | #define BAR_IN_MSB 0x14 44 | #define BAR_IN_LSB 0x15 45 | #define P_TGT_MSB 0x16 46 | #define P_TGT_LSB 0x17 47 | #define T_TGT 0x18 48 | #define P_WND_MSB 0x19 49 | #define P_WND_LSB 0x1A 50 | #define T_WND 0x1B 51 | #define P_MIN_MSB 0x1C 52 | #define P_MIN_CSB 0x1D 53 | #define P_MIN_LSB 0x1E 54 | #define T_MIN_MSB 0x1F 55 | #define T_MIN_LSB 0x20 56 | #define P_MAX_MSB 0x21 57 | #define P_MAX_CSB 0x22 58 | #define P_MAX_LSB 0x23 59 | #define T_MAX_MSB 0x24 60 | #define T_MAX_LSB 0x25 61 | #define CTRL_REG1 0x26 62 | #define CTRL_REG2 0x27 63 | #define CTRL_REG3 0x28 64 | #define CTRL_REG4 0x29 65 | #define CTRL_REG5 0x2A 66 | #define OFF_P 0x2B 67 | #define OFF_T 0x2C 68 | #define OFF_H 0x2D 69 | 70 | #define MPL3115A2_ADDRESS 0x60 // 7-bit I2C address 71 | 72 | long startTime; 73 | 74 | void setup() 75 | { 76 | Wire.begin(); // join i2c bus 77 | Serial.begin(57600); // start serial for output 78 | 79 | if(IIC_Read(WHO_AM_I) == 196) 80 | Serial.println("MPL3115A2 online!"); 81 | else 82 | Serial.println("No response - check connections"); 83 | 84 | // Configure the sensor 85 | setModeAltimeter(); // Measure altitude above sea level in meters 86 | //setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 87 | 88 | setOversampleRate(7); // Set Oversample to the recommended 128 89 | enableEventFlags(); // Enable all three pressure and temp event flags 90 | } 91 | 92 | void loop() 93 | { 94 | startTime = millis(); 95 | 96 | float altitude = readAltitude(); 97 | Serial.print("Altitude(m):"); 98 | Serial.print(altitude, 2); 99 | 100 | //altitude = readAltitudeFt(); 101 | //Serial.print(" Altitude(ft):"); 102 | //Serial.print(altitude, 2); 103 | 104 | /*float pressure = readPressure(); 105 | Serial.print(" Pressure(Pa):"); 106 | Serial.println(pressure, 2);*/ 107 | 108 | //float temperature = readTemp(); 109 | //Serial.print(" Temp(c):"); 110 | //Serial.print(temperature, 2); 111 | 112 | //float temperature = readTempF(); 113 | //Serial.print(" Temp(f):"); 114 | //Serial.print(temperature, 2); 115 | 116 | Serial.print(" time diff:"); 117 | Serial.print(millis() - startTime); 118 | 119 | Serial.println(); 120 | 121 | //delay(1); 122 | } 123 | 124 | //Returns the number of meters above sea level 125 | float readAltitude() 126 | { 127 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 128 | 129 | //Wait for PDR bit, indicates we have new pressure data 130 | int counter = 0; 131 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 132 | { 133 | if(++counter > 100) return(-999); //Error out 134 | delay(1); 135 | } 136 | 137 | // Read pressure registers 138 | Wire.beginTransmission(MPL3115A2_ADDRESS); 139 | Wire.write(OUT_P_MSB); // Address of data to get 140 | 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! 141 | Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes 142 | 143 | //Wait for data to become available 144 | counter = 0; 145 | while(Wire.available() < 3) 146 | { 147 | if(counter++ > 100) return(-999); //Error out 148 | delay(1); 149 | } 150 | 151 | byte msb, csb, lsb; 152 | msb = Wire.read(); 153 | csb = Wire.read(); 154 | lsb = Wire.read(); 155 | 156 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 157 | 158 | // The least significant bytes l_altitude and l_temp are 4-bit, 159 | // fractional values, so you must cast the calulation in (float), 160 | // shift the value over 4 spots to the right and divide by 16 (since 161 | // there are 16 values in 4-bits). 162 | float tempcsb = (lsb>>4)/16.0; 163 | 164 | float altitude = (float)( (msb << 8) | csb) + tempcsb; 165 | 166 | return(altitude); 167 | } 168 | 169 | //Returns the number of feet above sea level 170 | float readAltitudeFt() 171 | { 172 | return(readAltitude() * 3.28084); 173 | } 174 | 175 | //Reads the current pressure in Pa 176 | //Unit must be set in barometric pressure mode 177 | float readPressure() 178 | { 179 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 180 | 181 | //Wait for PDR bit, indicates we have new pressure data 182 | int counter = 0; 183 | while( (IIC_Read(STATUS) & (1<<2)) == 0) 184 | { 185 | if(++counter > 100) return(-999); //Error out 186 | delay(1); 187 | } 188 | 189 | // Read pressure registers 190 | Wire.beginTransmission(MPL3115A2_ADDRESS); 191 | Wire.write(OUT_P_MSB); // Address of data to get 192 | 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! 193 | Wire.requestFrom(MPL3115A2_ADDRESS, 3); // Request three bytes 194 | 195 | //Wait for data to become available 196 | counter = 0; 197 | while(Wire.available() < 3) 198 | { 199 | if(counter++ > 100) return(-999); //Error out 200 | delay(1); 201 | } 202 | 203 | byte msb, csb, lsb; 204 | msb = Wire.read(); 205 | csb = Wire.read(); 206 | lsb = Wire.read(); 207 | 208 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 209 | 210 | // Pressure comes back as a left shifted 20 bit number 211 | long pressure_whole = (long)msb<<16 | (long)csb<<8 | (long)lsb; 212 | pressure_whole >>= 6; //Pressure is an 18 bit number with 2 bits of decimal. Get rid of decimal portion. 213 | 214 | lsb &= 0b00110000; //Bits 5/4 represent the fractional component 215 | lsb >>= 4; //Get it right aligned 216 | float pressure_decimal = (float)lsb/4.0; //Turn it into fraction 217 | 218 | float pressure = (float)pressure_whole + pressure_decimal; 219 | 220 | return(pressure); 221 | } 222 | 223 | float readTemp() 224 | { 225 | toggleOneShot(); //Toggle the OST bit causing the sensor to immediately take another reading 226 | 227 | //Wait for TDR bit, indicates we have new temp data 228 | int counter = 0; 229 | while( (IIC_Read(STATUS) & (1<<1)) == 0) 230 | { 231 | if(++counter > 100) return(-999); //Error out 232 | delay(1); 233 | } 234 | 235 | // Read temperature registers 236 | Wire.beginTransmission(MPL3115A2_ADDRESS); 237 | Wire.write(OUT_T_MSB); // Address of data to get 238 | 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! 239 | Wire.requestFrom(MPL3115A2_ADDRESS, 2); // Request two bytes 240 | 241 | //Wait for data to become available 242 | counter = 0; 243 | while(Wire.available() < 2) 244 | { 245 | if(++counter > 100) return(-999); //Error out 246 | delay(1); 247 | } 248 | 249 | byte msb, lsb; 250 | msb = Wire.read(); 251 | lsb = Wire.read(); 252 | 253 | // The least significant bytes l_altitude and l_temp are 4-bit, 254 | // fractional values, so you must cast the calulation in (float), 255 | // shift the value over 4 spots to the right and divide by 16 (since 256 | // there are 16 values in 4-bits). 257 | float templsb = (lsb>>4)/16.0; //temp, fraction of a degree 258 | 259 | float temperature = (float)(msb + templsb); 260 | 261 | return(temperature); 262 | } 263 | 264 | //Give me temperature in fahrenheit! 265 | float readTempF() 266 | { 267 | return((readTemp() * 9.0)/ 5.0 + 32.0); // Convert celsius to fahrenheit 268 | } 269 | 270 | //Sets the mode to Barometer 271 | //CTRL_REG1, ALT bit 272 | void setModeBarometer() 273 | { 274 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 275 | tempSetting &= ~(1<<7); //Clear ALT bit 276 | IIC_Write(CTRL_REG1, tempSetting); 277 | } 278 | 279 | //Sets the mode to Altimeter 280 | //CTRL_REG1, ALT bit 281 | void setModeAltimeter() 282 | { 283 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 284 | tempSetting |= (1<<7); //Set ALT bit 285 | IIC_Write(CTRL_REG1, tempSetting); 286 | } 287 | 288 | //Puts the sensor in standby mode 289 | //This is needed so that we can modify the major control registers 290 | void setModeStandby() 291 | { 292 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 293 | tempSetting &= ~(1<<0); //Clear SBYB bit for Standby mode 294 | IIC_Write(CTRL_REG1, tempSetting); 295 | } 296 | 297 | //Puts the sensor in active mode 298 | //This is needed so that we can modify the major control registers 299 | void setModeActive() 300 | { 301 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 302 | tempSetting |= (1<<0); //Set SBYB bit for Active mode 303 | IIC_Write(CTRL_REG1, tempSetting); 304 | } 305 | 306 | //Setup FIFO mode to one of three modes. See page 26, table 31 307 | //From user jr4284 308 | void setFIFOMode(byte f_Mode) 309 | { 310 | if (f_Mode > 3) f_Mode = 3; // FIFO value cannot exceed 3. 311 | f_Mode <<= 6; // Shift FIFO byte left 6 to put it in bits 6, 7. 312 | 313 | byte tempSetting = IIC_Read(F_SETUP); //Read current settings 314 | tempSetting &= ~(3<<6); // clear bits 6, 7 315 | tempSetting |= f_Mode; //Mask in new FIFO bits 316 | IIC_Write(F_SETUP, tempSetting); 317 | } 318 | 319 | //Call with a rate from 0 to 7. See page 33 for table of ratios. 320 | //Sets the over sample rate. Datasheet calls for 128 but you can set it 321 | //from 1 to 128 samples. The higher the oversample rate the greater 322 | //the time between data samples. 323 | void setOversampleRate(byte sampleRate) 324 | { 325 | if(sampleRate > 7) sampleRate = 7; //OS cannot be larger than 0b.0111 326 | sampleRate <<= 3; //Align it for the CTRL_REG1 register 327 | 328 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 329 | tempSetting &= 0b11000111; //Clear out old OS bits 330 | tempSetting |= sampleRate; //Mask in new OS bits 331 | IIC_Write(CTRL_REG1, tempSetting); 332 | } 333 | 334 | //Clears then sets the OST bit which causes the sensor to immediately take another reading 335 | //Needed to sample faster than 1Hz 336 | void toggleOneShot(void) 337 | { 338 | byte tempSetting = IIC_Read(CTRL_REG1); //Read current settings 339 | tempSetting &= ~(1<<1); //Clear OST bit 340 | IIC_Write(CTRL_REG1, tempSetting); 341 | 342 | tempSetting = IIC_Read(CTRL_REG1); //Read current settings to be safe 343 | tempSetting |= (1<<1); //Set OST bit 344 | IIC_Write(CTRL_REG1, tempSetting); 345 | } 346 | 347 | //Enables the pressure and temp measurement event flags so that we can 348 | //test against them. This is recommended in datasheet during setup. 349 | void enableEventFlags() 350 | { 351 | IIC_Write(PT_DATA_CFG, 0x07); // Enable all three pressure and temp event flags 352 | } 353 | 354 | // These are the two I2C functions in this sketch. 355 | byte IIC_Read(byte regAddr) 356 | { 357 | // This function reads one byte over IIC 358 | Wire.beginTransmission(MPL3115A2_ADDRESS); 359 | Wire.write(regAddr); // Address of CTRL_REG1 360 | 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! 361 | Wire.requestFrom(MPL3115A2_ADDRESS, 1); // Request the data... 362 | return Wire.read(); 363 | } 364 | 365 | void IIC_Write(byte regAddr, byte value) 366 | { 367 | // This function writes one byto over IIC 368 | Wire.beginTransmission(MPL3115A2_ADDRESS); 369 | Wire.write(regAddr); 370 | Wire.write(value); 371 | Wire.endTransmission(true); 372 | } 373 | -------------------------------------------------------------------------------- /firmware/MPL3115A2_FIFO_example/MPL3115A2_AdvancedExample.ino: -------------------------------------------------------------------------------- 1 | /* MPL3115A2 Example Code 2 | by: Kris Winer adapted from skeleton codes by Jim Lindblom, A. Weiss, and Nathan Seidle (Thanks guys!) 3 | Modified: February 12, 2014 by Kris Winer 4 | Original date: November 17, 2011, Jim Lindblom, SparkFun Electronics 5 | 6 | IDE example usage for most features of the MPL3115A2 I2C Precision Altimeter. 7 | 8 | Basic functions are implemented including absolute pressure (50 to 110 kPa), altimeter pressure (mmHg), 9 | altitude (meters or feet), and temperature (-40 to 85 C). 10 | 11 | In addition, provision for the FIFO mode in the initialization, watermark/overflow setting, and register 12 | read functions for autonomous data logging over as many as nine hours with 32 data samples of P, T. 13 | 14 | Hardware setup: 15 | MPL3115A2 Breakout ------------ Arduino Mini Pro 3.3 V 16 | 3.3V --------------------- 3.3V 17 | SDA ----------------------- A4 18 | SCL ----------------------- A5 19 | INT2 ---------------------- D4 20 | INT1 ---------------------- D5 21 | GND ---------------------- GND 22 | 23 | SDA and SCL should have external pull-up resistors (to 3.3V) if using a 5 V Arduino. 24 | They should be on the MPL3115A2 SparkFun breakout board. 25 | I didn't need any for the 3.3 V Pro Mini. 26 | 27 | Jim Lindblom's Note: The MMA8452 is an I2C sensor, however this code does 28 | not make use of the Arduino Wire library. Because the sensor 29 | is not 5V tolerant, we can't use the internal pull-ups used 30 | by the Wire library. Instead use the included i2c.h, defs.h and types.h files. 31 | 32 | The MPL3115A2 in this sketch is interfaced with a Pro Mini operating at 3.3 V, so we could use the 33 | Arduino Wire library. However, I will follow Jim Lindblom's example. 34 | 35 | The MPL3115A2 has internal First in/First out data storage enabling autonomous data logging for up to 32 samples 36 | of pressure/altitude and temperature. I programmed the Pro Mini through a FTDI Basic interface board and noticed 37 | every time I hooked it up to the Arduino/Sensor or opened a serial monitor the devices were re-initialized, 38 | defeating the autonomous logging function. 39 | 40 | This was remedied by placing a 10 uF capacitor between reset and ground before either reconnecting the sensor 41 | through the FTDI board or opening a serial monitor. Either event drives the reset low, the capacitor keeps the 42 | reset high long enough to avoid resetting. Of course, the capacitor must be removed when uploading a new or updated 43 | sketch or an error will be generated. 44 | 45 | I got this idea from: 46 | http://electronics.stackexchange.com/questions/24743/arduino-resetting-while-reconnecting-the-serial-terminal 47 | where there is a little more discussion. Thanks 0xAKHIL! 48 | 49 | Lastly, I put a piece of porous foam over the sensor to block ambient light since thre is some indication the 50 | pressure and altitude reading are light sensitive. 51 | 52 | */ 53 | 54 | #include "i2c.h" // not the wire library, can't use pull-ups 55 | #include //include the OLED library to control LCD 56 | 57 | Adafruit_CharacterOLED lcd(OLED_V2, 6, 7, 8, 9, 10, 11, 12); // initialize the LCD library with the numbers of the interface pins 58 | 59 | // make a custom character for degree symbol: 60 | byte degree[8] = { 61 | 0b00100, 62 | 0b01010, 63 | 0b00100, 64 | 0b00000, 65 | 0b00000, 66 | 0b00000, 67 | 0b00000, 68 | 0b00000 69 | }; 70 | 71 | // make a custom character for Mercury symbol: 72 | byte mercury[8] = { 73 | 0b10100, 74 | 0b11100, 75 | 0b10100, 76 | 0b10100, 77 | 0b00011, 78 | 0b00011, 79 | 0b00001, 80 | 0b00011 81 | }; 82 | 83 | // Standard 7-bit I2C slave address is 1100000 = 0x60, 8-bit read address is 0xC1, 8-bit write is 0xC0 84 | #define MPL3115A2_ADDRESS 0x60 // SA0 is high, 0x1C if low 85 | 86 | // Register defines courtesy A. Weiss and Nathan Seidle, SparkFun Electronics 87 | #define STATUS 0x00 88 | #define OUT_P_MSB 0x01 89 | #define OUT_P_CSB 0x02 90 | #define OUT_P_LSB 0x03 91 | #define OUT_T_MSB 0x04 92 | #define OUT_T_LSB 0x05 93 | #define DR_STATUS 0x06 94 | #define OUT_P_DELTA_MSB 0x07 95 | #define OUT_P_DELTA_CSB 0x08 96 | #define OUT_P_DELTA_LSB 0x09 97 | #define OUT_T_DELTA_MSB 0x0A 98 | #define OUT_T_DELTA_LSB 0x0B 99 | #define WHO_AM_I 0x0C 100 | #define F_STATUS 0x0D 101 | #define F_DATA 0x0E 102 | #define F_SETUP 0x0F 103 | #define TIME_DLY 0x10 104 | #define SYSMOD 0x11 105 | #define INT_SOURCE 0x12 106 | #define PT_DATA_CFG 0x13 107 | #define BAR_IN_MSB 0x14 // Set at factory to equivalent sea level pressure for measurement location, generally no need to change 108 | #define BAR_IN_LSB 0x15 // Set at factory to equivalent sea level pressure for measurement location, generally no need to change 109 | #define P_TGT_MSB 0x16 110 | #define P_TGT_LSB 0x17 111 | #define T_TGT 0x18 112 | #define P_WND_MSB 0x19 113 | #define P_WND_LSB 0x1A 114 | #define T_WND 0x1B 115 | #define P_MIN_MSB 0x1C 116 | #define P_MIN_CSB 0x1D 117 | #define P_MIN_LSB 0x1E 118 | #define T_MIN_MSB 0x1F 119 | #define T_MIN_LSB 0x20 120 | #define P_MAX_MSB 0x21 121 | #define P_MAX_CSB 0x22 122 | #define P_MAX_LSB 0x23 123 | #define T_MAX_MSB 0x24 124 | #define T_MAX_LSB 0x25 125 | #define CTRL_REG1 0x26 126 | #define CTRL_REG2 0x27 127 | #define CTRL_REG3 0x28 128 | #define CTRL_REG4 0x29 129 | #define CTRL_REG5 0x2A 130 | #define OFF_P 0x2B 131 | #define OFF_T 0x2C 132 | #define OFF_H 0x2D 133 | 134 | // Define Device inputs 135 | // Integer values between 0 < n < 7 give oversample ratios 2^n and 136 | // sampling intervals of 0=6 ms , 1=10, 2=18, 3=34, 4=66, 5=130, 6=258, and 7=512 137 | const byte SAMPLERATE = 7; // maximum oversample = 7 138 | // Set time between FIFO data points from 1 to 16328 s (For some reason I get a spurious result for ST_Value = 15) 139 | const byte ST_VALUE = 1; // Set auto time step (2^ST_VALUE) seconds 140 | int FIFOon = 1; // Choose realtime data acquisition or FIFO delayed data acquisition; default is real time 141 | int AltimeterMode = 0; // use to choose between altimeter and barometer modes for FIFO data 142 | 143 | // Define device outputs 144 | float altitude = 0.; 145 | float pressure = 0.; 146 | float temperature = 0.; 147 | 148 | // Interrupt Pin definitions 149 | const int int1Pin = 4; // New data available interrupt 150 | // Interrupt events: FIFO, Pressure window, temperature window, pressure threshold, 151 | // temperature threshold, pressure change, and temperature change set in CNTL_REG5 152 | const int int2Pin = 5; 153 | const int readoutPin = 2; // We will allow FIFO data to be serial printed when the readout pin is set to high 154 | 155 | void setup() 156 | { 157 | 158 | Serial.begin(9600); 159 | 160 | // create a degree, mercury symbol characters 161 | lcd.createChar(4, degree); 162 | lcd.createChar(5, mercury); 163 | 164 | lcd.begin(16, 2);// Initialize the LCD with 16 characters and 2 lines 165 | 166 | // Read the WHO_AM_I register, this is a good test of communication 167 | byte c = readRegister(WHO_AM_I); // Read WHO_AM_I register 168 | if (c == 0xC4) // WHO_AM_I should always be 0xC4 169 | { 170 | 171 | MPL3115A2Reset(); // Start off by resetting all registers to the default 172 | 173 | // Set up the interrupt pins, they're set as active high, push-pull 174 | pinMode(int1Pin, INPUT); 175 | digitalWrite(int1Pin, LOW); // Initialize interrupt pins to LOW 176 | pinMode(int2Pin, INPUT); 177 | digitalWrite(int2Pin, LOW);// Initialize interrupt pins to LOW 178 | pinMode(readoutPin, INPUT); 179 | digitalWrite(readoutPin, LOW);// Initialize readout pin to LOW 180 | 181 | SampleRate(SAMPLERATE); // Set oversampling rate 182 | Serial.print("Oversampling Rate is "); Serial.println(SAMPLERATE); 183 | TimeStep(ST_VALUE); // Set data update interval 184 | Serial.print("Data update interval is "); Serial.print((unsigned long) (1 << ST_VALUE)); Serial.println(" seconds"); 185 | MPL3115A2enableEventflags(); 186 | Serial.println("MPL3115A2 event flags enabled..."); 187 | 188 | } 189 | else 190 | { 191 | Serial.print("Could not connect to MPL3115A2: 0x"); 192 | Serial.println(c, HEX); 193 | while(1) ; // Loop forever if communication doesn't happen 194 | } 195 | } 196 | 197 | void loop() 198 | { 199 | 200 | // Currently configured to continuously log data if FIFOon = 1; the FIFO buffer is read and output to a serial monitor 201 | // when digital pin 2 is momentarily set HIGH. The data begins accumulating again after the data read. In the 202 | // initFIFOMPL3115A2() function, the overflow interrupt can be set instead of watermark, then the data log only 203 | // occurs once until the overflow interrupt is triggered on FIFO data register full condition; for some reason, this happens 204 | // after reading 31 not 32 data points. 205 | 206 | if(FIFOon == 1) { 207 | 208 | initFIFOMPL3115A2(); // initialize the accelerometer for delayed (FIFO) acquisition if communication is OK 209 | Serial.println("MPL3115A2 FIFO data acquisition active..."); 210 | if(AltimeterMode) {ActiveAltimeterMode(); Serial.println("Active Altimeter Mode");} // Choose either barometer or altimeter mode 211 | else {ActiveBarometerMode(); Serial.println("Active Barometer Mode");} 212 | 213 | byte rawData[160]; 214 | 215 | // This is similar to the interrupt method in the active data acquisition routine 216 | // Watermark mode should continuously log data and download to serial monitor after readoutPin set HIGH 217 | // Overflow mode should write out the data just once, when the 32 samples have been acquired 218 | // Sensor presumably takes one data read at start; can wait for other 31 data reads before checking interrupts 219 | // 220 | unsigned long count = 1 << ST_VALUE; // Use unsigned long because this number can get quite large! 221 | unsigned long i = 0; 222 | for (i=0; i < 31*count; i++) { 223 | lcd.setCursor(0,0); lcd.print("Wait "); 224 | lcd.setCursor(6,0); lcd.print((31*count - i)); lcd.print("s "); 225 | lcd.setCursor(0,1); lcd.print("in FIFO mode "); 226 | delay(1000); 227 | } 228 | while(digitalRead(int2Pin) == LOW); // Wait for interrupt event on intPin2 229 | while ((readRegister(INT_SOURCE) & 0x40) == 0); Serial.println("Interrupt on FIFO source"); // Wait for interrupt source = FIFO on bit 6 230 | while (readRegister(F_STATUS) & 0x80 | 0x40 == 0); // Should clear the INT_SOURCE bit 231 | Clock(); // capture time overflow condition reached 232 | lcd.setCursor(0,1); lcd.print("Data pts = "); lcd.print((int) (readRegister(F_STATUS)<<2)/4); // Print number of data points successfully acquired 233 | 234 | // We will allow delayed read of FIFO registers by requiring digital pin to go HIGH before read; 235 | // This is useful for autonomous data acquisition applications where the data is collected at one time 236 | // and downloaded to the serial monitor or other output device at another time. This is a poor man's data logger! 237 | while(digitalRead(readoutPin) == LOW); // Wait for the readout pin to go momentarily HIGH before data read 238 | 239 | unsigned long c = readRegister(TIME_DLY); // Check how much time has elapsed since last write; useful for overflow (read once) mode 240 | Serial.print("Time since last write = "); Serial.print(c*count); Serial.println(" seconds"); 241 | 242 | readRegisters(F_DATA, 160, &rawData[0]); // If overflow reached, dump the FIFO data registers 243 | 244 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 245 | // Process the FIFO data buffer contents and print to serial monitor 246 | // Convert all the raw FIFO data to pressure/altitude and temperature 247 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 248 | int j; 249 | for(j = 0; j < 160; j+=5) { 250 | 251 | // Pressure/Altitude bytes 252 | byte msb = rawData[j]; 253 | byte csb = rawData[j+1]; 254 | byte lsb = rawData[j+2]; 255 | // Temperature bytes 256 | byte msbT = rawData[j+3]; 257 | byte lsbT = rawData[j+4]; 258 | 259 | if(AltimeterMode) { 260 | // Calculate altitude, check for negative sign in altimeter data 261 | long foo = 0; 262 | if(msb > 0x7F) { 263 | foo = ~((long)msb << 16 | (long)csb << 8 | (long)lsb) + 1; // 2's complement the data 264 | altitude = (float) (foo >> 8) + (float) ((lsb >> 4)/16.0); // Whole number plus fraction altitude in meters for negative altitude 265 | altitude *= -1.; 266 | } 267 | else { 268 | foo = ((msb << 8) | csb); 269 | altitude = (float) (foo) + (float) ((lsb >> 4)/16.0); // Whole number plus fraction altitude in meters 270 | } 271 | } 272 | else { 273 | long pressure_whole = ((long)msb << 16 | (long)csb << 8 | (long)lsb) ; // Construct whole number pressure 274 | pressure_whole >>= 6; 275 | 276 | lsb &= 0x30; 277 | lsb >>= 4; 278 | float pressure_frac = (float) lsb/4.0; 279 | 280 | pressure = (float) (pressure_whole) + pressure_frac; 281 | } 282 | 283 | // Calculate temperature, check for negative sign 284 | long foo = 0; 285 | if(msbT > 0x7F) { 286 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 287 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 288 | temperature *= -1.; 289 | } 290 | else { 291 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 292 | } 293 | 294 | // Output data array to serial printer; comma delimits useful for importing into excel spreadsheet 295 | Serial.print("Time ,"); Serial.print((j/5)*(1< 0x7F) { 421 | foo = ~((long)msbA << 16 | (long)csbA << 8 | (long)lsbA) + 1; // 2's complement the data 422 | altitude = (float) (foo >> 8) + (float) ((lsbA >> 4)/16.0); // Whole number plus fraction altitude in meters for negative altitude 423 | altitude *= -1.; 424 | } 425 | else { 426 | altitude = (float) ( (msbA << 8) | csbA) + (float) ((lsbA >> 4)/16.0); // Whole number plus fraction altitude in meters 427 | } 428 | 429 | // Calculate temperature, check for negative sign 430 | if(msbT > 0x7F) { 431 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 432 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 433 | temperature *= -1.; 434 | } 435 | else { 436 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 437 | } 438 | } 439 | 440 | void readPressure() 441 | { 442 | byte rawData[5]; // msb/csb/lsb pressure and msb/lsb temperature stored in five contiguous registers 443 | 444 | 445 | // We can read the data either by polling or interrupt; see data sheet for relative advantages 446 | // First we try hardware interrupt, which should take less power, etc. 447 | while (digitalRead(int1Pin) == LOW); // Wait for interrupt pin int1Pin to go HIGH 448 | digitalWrite(int1Pin, LOW); // Reset interrupt pin int1Pin 449 | while((readRegister(INT_SOURCE) & 0x80) == 0); // Check that the interrupt source is a data ready interrupt 450 | // or use a polling method 451 | // Check data read status; if PTDR (bit 4) not set, then 452 | // toggle OST bit to cause sensor to immediately take a reading 453 | // Setting the one shot toggle is the way to get faster than 1 Hz data read rates 454 | // while ((readRegister(STATUS) & 0x08) == 0); // toggleOneShot(); 455 | 456 | readRegisters(OUT_P_MSB, 5, &rawData[0]); // Read the five raw data registers into data array 457 | 458 | // Pressure bytes 459 | byte msbP = rawData[0]; 460 | byte csbP = rawData[1]; 461 | byte lsbP = rawData[2]; 462 | // Temperature bytes 463 | byte msbT = rawData[3]; 464 | byte lsbT = rawData[4]; 465 | 466 | long pressure_whole = ((long)msbP << 16 | (long)csbP << 8 | (long)lsbP) ; // Construct whole number pressure 467 | pressure_whole >>= 6; 468 | 469 | lsbP &= 0x30; 470 | lsbP >>= 4; 471 | float pressure_frac = (float) lsbP/4.0; 472 | 473 | pressure = (float) (pressure_whole) + pressure_frac; 474 | 475 | // Calculate temperature, check for negative sign 476 | long foo = 0; 477 | if(msbT > 0x7F) { 478 | foo = ~(msbT << 8 | lsbT) + 1 ; // 2's complement 479 | temperature = (float) (foo >> 8) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 480 | temperature *= -1.; 481 | } 482 | else { 483 | temperature = (float) (msbT) + (float)((lsbT >> 4)/16.0); // add whole and fractional degrees Centigrade 484 | } 485 | } 486 | 487 | /* 488 | ===================================================================================================== 489 | Define functions according to 490 | "Data Manipulation and Basic Settings of the MPL3115A2 Command Line Interface Drive Code" 491 | by Miguel Salhuana 492 | Freescale Semiconductor Application Note AN4519 Rev 0.1, 08/2012 493 | ===================================================================================================== 494 | */ 495 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 496 | // Clears then sets OST bit which causes the sensor to immediately take another reading 497 | void toggleOneShot() 498 | { 499 | MPL3115A2Active(); // Set to active to start reading 500 | byte c = readRegister(CTRL_REG1); 501 | writeRegister(CTRL_REG1, c & ~(1<<1)); // Clear OST (bit 1) 502 | c = readRegister(CTRL_REG1); 503 | writeRegister(CTRL_REG1, c | (1<<1)); // Set OST bit to 1 504 | } 505 | 506 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 507 | // Set the Outputting Sample Rate 508 | void SampleRate(byte samplerate) 509 | { 510 | MPL3115A2Standby(); // Must be in standby to change registers 511 | 512 | byte c = readRegister(CTRL_REG1); 513 | writeRegister(CTRL_REG1, c & ~(0x38)); // Clear OSR bits 3,4,5 514 | if(samplerate < 8) { // OSR between and 7 515 | writeRegister(CTRL_REG1, c | (samplerate << 3)); // Write OSR to bits 3,4,5 516 | } 517 | 518 | MPL3115A2Active(); // Set to active to start reading 519 | } 520 | 521 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 522 | // Initialize the MPL3115A2 registers for FIFO mode 523 | void initFIFOMPL3115A2() 524 | { 525 | // Clear all interrupts by reading the data output registers 526 | byte temp; 527 | temp = readRegister(OUT_P_MSB); 528 | temp = readRegister(OUT_P_CSB); 529 | temp = readRegister(OUT_P_LSB); 530 | temp = readRegister(OUT_T_MSB); 531 | temp = readRegister(OUT_T_LSB); 532 | temp = readRegister(F_STATUS); 533 | 534 | MPL3115A2Standby(); // Must be in standby to change registers 535 | 536 | // Set CTRL_REG4 register to configure interupt enable 537 | // Enable data ready interrupt (bit 7), enable FIFO (bit 6), enable pressure window (bit 5), temperature window (bit 4), 538 | // pressure threshold (bit 3), temperature threshold (bit 2), pressure change (bit 1) and temperature change (bit 0) 539 | writeRegister(CTRL_REG4, 0x40); // enable FIFO 540 | 541 | // Configure INT 1 for data ready, all other (inc. FIFO) interrupts to INT2 542 | writeRegister(CTRL_REG5, 0x80); 543 | 544 | // Set CTRL_REG3 register to configure interupt signal type 545 | // Active HIGH, push-pull interupts INT1 and INT 2 546 | writeRegister(CTRL_REG3, 0x22); 547 | 548 | // Set FIFO mode 549 | writeRegister(F_SETUP, 0x00); // Clear FIFO mode 550 | // writeRegister(F_SETUP, 0x80); // Set F_MODE to interrupt when overflow = 32 reached 551 | writeRegister(F_SETUP, 0x60); // Set F_MODE to accept 32 data samples and interrupt when watermark = 32 reached 552 | 553 | MPL3115A2Active(); // Set to active to start reading 554 | } 555 | 556 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 557 | // Initialize the MPL3115A2 for realtime data collection 558 | void initRealTimeMPL3115A2() 559 | { 560 | // Clear all interrupts by reading the data output registers 561 | byte temp; 562 | temp = readRegister(OUT_P_MSB); 563 | temp = readRegister(OUT_P_CSB); 564 | temp = readRegister(OUT_P_LSB); 565 | temp = readRegister(OUT_T_MSB); 566 | temp = readRegister(OUT_T_LSB); 567 | temp = readRegister(F_STATUS); 568 | 569 | MPL3115A2Standby(); // Must be in standby to change registers 570 | 571 | // Set CTRL_REG4 register to configure interupt enable 572 | // Enable data ready interrupt (bit 7), enable FIFO (bit 6), enable pressure window (bit 5), temperature window (bit 4), 573 | // pressure threshold (bit 3), temperature threshold (bit 2), pressure change (bit 1) and temperature change (bit 0) 574 | writeRegister(CTRL_REG4, 0x80); 575 | 576 | // Configure INT 1 for data ready, all other interrupts to INT2 577 | writeRegister(CTRL_REG5, 0x80); 578 | 579 | // Set CTRL_REG3 register to configure interupt signal type 580 | // Active HIGH, push-pull interupts INT1 and INT 2 581 | writeRegister(CTRL_REG3, 0x22); 582 | 583 | // Set FIFO mode 584 | writeRegister(F_SETUP, 0x00); // disable FIFO mode 585 | 586 | MPL3115A2Active(); // Set to active to start reading 587 | } 588 | 589 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 590 | // Set the Auto Acquisition Time Step 591 | void TimeStep(byte ST_Value) 592 | { 593 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 594 | 595 | byte c = readRegister(CTRL_REG2); // Read contents of register CTRL_REG2 596 | if (ST_Value <= 0xF) { 597 | writeRegister(CTRL_REG2, (c | ST_Value)); // Set time step n from 0x0 to 0xF (bits 0 - 3) for time intervals from 1 to 32768 (2^n) seconds 598 | } 599 | 600 | MPL3115A2Active(); // Set to active to start reading 601 | } 602 | 603 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 604 | // Enable the pressure and temperature event flags 605 | // Bit 2 is general data ready event mode on new Pressure/Altitude or temperature data 606 | // Bit 1 is event flag on new Pressure/Altitude data 607 | // Bit 0 is event flag on new Temperature data 608 | void MPL3115A2enableEventflags() 609 | { 610 | MPL3115A2Standby(); // Must be in standby to change registers 611 | writeRegister(PT_DATA_CFG, 0x07); //Enable all three pressure and temperature event flags 612 | MPL3115A2Active(); // Set to active to start reading 613 | } 614 | 615 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 616 | // Enter Active Altimeter mode 617 | void ActiveAltimeterMode() 618 | { 619 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 620 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 621 | writeRegister(CTRL_REG1, c | (0x80)); // Set ALT (bit 7) to 1 622 | MPL3115A2Active(); // Set to active to start reading 623 | } 624 | 625 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 626 | // Enter Active Barometer mode 627 | void ActiveBarometerMode() 628 | { 629 | MPL3115A2Standby(); // First put device in standby mode to allow write to registers 630 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 631 | writeRegister(CTRL_REG1, c & ~(0x80)); // Set ALT (bit 7) to 0 632 | MPL3115A2Active(); // Set to active to start reading 633 | } 634 | 635 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 636 | // Software resets the MPL3115A2. 637 | // It must be in standby to change most register settings 638 | void MPL3115A2Reset() 639 | { 640 | writeRegister(CTRL_REG1, (0x04)); // Set RST (bit 2) to 1 641 | } 642 | 643 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 644 | // Sets the MPL3115A2 to standby mode. 645 | // It must be in standby to change most register settings 646 | void MPL3115A2Standby() 647 | { 648 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 649 | writeRegister(CTRL_REG1, c & ~(0x01)); // Set SBYB (bit 0) to 0 650 | } 651 | 652 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 653 | // Sets the MPL3115A2 to active mode. 654 | // Needs to be in this mode to output data 655 | void MPL3115A2Active() 656 | { 657 | byte c = readRegister(CTRL_REG1); // Read contents of register CTRL_REG1 658 | writeRegister(CTRL_REG1, c | 0x01); // Set SBYB (bit 0) to 1 659 | } 660 | 661 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 662 | // Read i registers sequentially, starting at address into the dest byte array 663 | void readRegisters(byte address, int i, byte * dest) 664 | { 665 | i2cSendStart(); 666 | i2cWaitForComplete(); 667 | 668 | i2cSendByte((MPL3115A2_ADDRESS<<1)); // write 0xB4 669 | i2cWaitForComplete(); 670 | 671 | i2cSendByte(address); // write register address 672 | i2cWaitForComplete(); 673 | 674 | i2cSendStart(); 675 | i2cSendByte((MPL3115A2_ADDRESS<<1)|0x01); // write 0xB5 676 | i2cWaitForComplete(); 677 | for (int j=0; j= 60) { 783 | seconds = seconds - 60; 784 | } // end while 785 | 786 | while(minutes >= 60) { 787 | minutes = minutes - 60; 788 | } // end while 789 | 790 | while(hours > 12) { 791 | hours = hours - 12; 792 | } // end while 793 | 794 | // If seconds less than 10, print a zero in the tens place and seconds thereafter 795 | 796 | if(seconds <= 9) { 797 | lcd.setCursor(6,0); 798 | lcd.print("0"); 799 | lcd.setCursor(7,0); 800 | lcd.print(seconds); 801 | } 802 | 803 | // Otherwise, if seconds greater than 9 print 804 | 805 | else { 806 | lcd.setCursor(6,0); 807 | lcd.print(seconds); 808 | } 809 | 810 | // If minutes less than 10, print a zero in the tens place and minutes thereafter 811 | 812 | if(minutes <= 9) { 813 | lcd.setCursor(3,0); 814 | lcd.print("0"); 815 | lcd.setCursor(4,0); 816 | lcd.print(minutes); 817 | } 818 | 819 | // Otherwise, if minutes greater than 9 print 820 | 821 | else { 822 | lcd.setCursor(3,0); 823 | lcd.print(minutes); 824 | } 825 | 826 | // If hours less than 10, print a zero in the tens place and hours thereafter 827 | 828 | if(hours <= 9) { 829 | lcd.setCursor(0,0); 830 | lcd.print("0"); 831 | lcd.setCursor(1,0); 832 | lcd.print(hours); 833 | } 834 | 835 | // Otherwise, if hours greater than 9 print 836 | 837 | else { 838 | lcd.setCursor(0,0); 839 | lcd.print(hours); 840 | } 841 | 842 | } 843 | 844 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 845 | // End of Sketch MPL3115A2 846 | -------------------------------------------------------------------------------- /firmware/MPL3115A2_FIFO_example/defs.h: -------------------------------------------------------------------------------- 1 | /*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ 2 | //***************************************************************************** 3 | // 4 | // File Name : 'avrlibdefs.h' 5 | // Title : AVRlib global defines and macros include file 6 | // Author : Pascal Stang 7 | // Created : 7/12/2001 8 | // Revised : 9/30/2002 9 | // Version : 1.1 10 | // Target MCU : Atmel AVR series 11 | // Editor Tabs : 4 12 | // 13 | // Description : This include file is designed to contain items useful to all 14 | // code files and projects, regardless of specific implementation. 15 | // 16 | // This code is distributed under the GNU Public License 17 | // which can be found at http://www.gnu.org/licenses/gpl.txt 18 | // 19 | //***************************************************************************** 20 | 21 | 22 | #ifndef AVRLIBDEFS_H 23 | #define AVRLIBDEFS_H 24 | 25 | //#define F_CPU 4000000 26 | #define MEM_TYPE 1 27 | 28 | // Code compatibility to new AVR-libc 29 | // outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli() 30 | #ifndef outb 31 | #define outb(addr, data) addr = (data) 32 | #endif 33 | #ifndef inb 34 | #define inb(addr) (addr) 35 | #endif 36 | #ifndef outw 37 | #define outw(addr, data) addr = (data) 38 | #endif 39 | #ifndef inw 40 | #define inw(addr) (addr) 41 | #endif 42 | #ifndef BV 43 | #define BV(bit) (1<<(bit)) 44 | #endif 45 | //#ifndef cbi 46 | // #define cbi(reg,bit) reg &= ~(BV(bit)) 47 | //#endif 48 | //#ifndef sbi 49 | // #define sbi(reg,bit) reg |= (BV(bit)) 50 | //#endif 51 | #ifndef cli 52 | #define cli() __asm__ __volatile__ ("cli" ::) 53 | #endif 54 | #ifndef sei 55 | #define sei() __asm__ __volatile__ ("sei" ::) 56 | #endif 57 | 58 | // support for individual port pin naming in the mega128 59 | // see port128.h for details 60 | #ifdef __AVR_ATmega128__ 61 | // not currently necessary due to inclusion 62 | // of these defines in newest AVR-GCC 63 | // do a quick test to see if include is needed 64 | #ifndef PD0 65 | //#include "port128.h" 66 | #endif 67 | #endif 68 | 69 | // use this for packed structures 70 | // (this is seldom necessary on an 8-bit architecture like AVR, 71 | // but can assist in code portability to AVR) 72 | #define GNUC_PACKED __attribute__((packed)) 73 | 74 | // port address helpers 75 | #define DDR(x) ((x)-1) // address of data direction register of port x 76 | #define PIN(x) ((x)-2) // address of input register of port x 77 | 78 | // MIN/MAX/ABS macros 79 | #define MIN(a,b) ((ab)?(a):(b)) 81 | #define ABS(x) ((x>0)?(x):(-x)) 82 | 83 | // constants 84 | #define PI 3.14159265359 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /firmware/MPL3115A2_FIFO_example/i2c.h: -------------------------------------------------------------------------------- 1 | // This library provides the high-level functions needed to use the I2C 2 | // serial interface supported by the hardware of several AVR processors. 3 | #include 4 | #include 5 | #include "types.h" 6 | #include "defs.h" 7 | 8 | // TWSR values (not bits) 9 | // (taken from avr-libc twi.h - thank you Marek Michalkiewicz) 10 | // Master 11 | #define TW_START 0x08 12 | #define TW_REP_START 0x10 13 | // Master Transmitter 14 | #define TW_MT_SLA_ACK 0x18 15 | #define TW_MT_SLA_NACK 0x20 16 | #define TW_MT_DATA_ACK 0x28 17 | #define TW_MT_DATA_NACK 0x30 18 | #define TW_MT_ARB_LOST 0x38 19 | // Master Receiver 20 | #define TW_MR_ARB_LOST 0x38 21 | #define TW_MR_SLA_ACK 0x40 22 | #define TW_MR_SLA_NACK 0x48 23 | #define TW_MR_DATA_ACK 0x50 24 | #define TW_MR_DATA_NACK 0x58 25 | // Slave Transmitter 26 | #define TW_ST_SLA_ACK 0xA8 27 | #define TW_ST_ARB_LOST_SLA_ACK 0xB0 28 | #define TW_ST_DATA_ACK 0xB8 29 | #define TW_ST_DATA_NACK 0xC0 30 | #define TW_ST_LAST_DATA 0xC8 31 | // Slave Receiver 32 | #define TW_SR_SLA_ACK 0x60 33 | #define TW_SR_ARB_LOST_SLA_ACK 0x68 34 | #define TW_SR_GCALL_ACK 0x70 35 | #define TW_SR_ARB_LOST_GCALL_ACK 0x78 36 | #define TW_SR_DATA_ACK 0x80 37 | #define TW_SR_DATA_NACK 0x88 38 | #define TW_SR_GCALL_DATA_ACK 0x90 39 | #define TW_SR_GCALL_DATA_NACK 0x98 40 | #define TW_SR_STOP 0xA0 41 | // Misc 42 | #define TW_NO_INFO 0xF8 43 | #define TW_BUS_ERROR 0x00 44 | 45 | // defines and constants 46 | #define TWCR_CMD_MASK 0x0F 47 | #define TWSR_STATUS_MASK 0xF8 48 | 49 | // return values 50 | #define I2C_OK 0x00 51 | #define I2C_ERROR_NODEV 0x01 52 | 53 | #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask)) 54 | #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask)) 55 | 56 | #define WRITE_sda() DDRC = DDRC | 0b00010000 //SDA must be output when writing 57 | #define READ_sda() DDRC = DDRC & 0b11101111 //SDA must be input when reading - don't forget the resistor on SDA!! 58 | 59 | // functions 60 | 61 | //! Initialize I2C (TWI) interface 62 | void i2cInit(void); 63 | 64 | //! Set the I2C transaction bitrate (in KHz) 65 | void i2cSetBitrate(unsigned short bitrateKHz); 66 | 67 | // Low-level I2C transaction commands 68 | //! Send an I2C start condition in Master mode 69 | void i2cSendStart(void); 70 | //! Send an I2C stop condition in Master mode 71 | void i2cSendStop(void); 72 | //! Wait for current I2C operation to complete 73 | void i2cWaitForComplete(void); 74 | //! Send an (address|R/W) combination or a data byte over I2C 75 | void i2cSendByte(unsigned char data); 76 | //! Receive a data byte over I2C 77 | // ackFlag = TRUE if recevied data should be ACK'ed 78 | // ackFlag = FALSE if recevied data should be NACK'ed 79 | void i2cReceiveByte(unsigned char ackFlag); 80 | //! Pick up the data that was received with i2cReceiveByte() 81 | unsigned char i2cGetReceivedByte(void); 82 | //! Get current I2c bus status from TWSR 83 | unsigned char i2cGetStatus(void); 84 | void delay_ms(uint16_t x); 85 | 86 | // high-level I2C transaction commands 87 | 88 | //! send I2C data to a device on the bus (non-interrupt based) 89 | unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data); 90 | //! receive I2C data from a device on the bus (non-interrupt based) 91 | unsigned char i2cMasterReceiveNI(unsigned char deviceAddr, unsigned char length, unsigned char *data); 92 | 93 | /********************* 94 | ****I2C Functions**** 95 | *********************/ 96 | 97 | void i2cInit(void) 98 | { 99 | // set i2c bit rate to 40KHz 100 | i2cSetBitrate(100); 101 | // enable TWI (two-wire interface) 102 | sbi(TWCR, TWEN); // Enable TWI 103 | } 104 | 105 | void i2cSetBitrate(unsigned short bitrateKHz) 106 | { 107 | unsigned char bitrate_div; 108 | // set i2c bitrate 109 | // SCL freq = F_CPU/(16+2*TWBR)) 110 | cbi(TWSR, TWPS0); 111 | cbi(TWSR, TWPS1); 112 | 113 | //calculate bitrate division 114 | bitrate_div = ((F_CPU/4000l)/bitrateKHz); 115 | if(bitrate_div >= 16) 116 | bitrate_div = (bitrate_div-16)/2; 117 | outb(TWBR, bitrate_div); 118 | } 119 | 120 | void i2cSendStart(void) 121 | { 122 | WRITE_sda(); 123 | // send start condition 124 | TWCR = (1< 0 ; x--){ 184 | for ( y = 0 ; y < 90 ; y++){ 185 | for ( z = 0 ; z < 6 ; z++){ 186 | asm volatile ("nop"); 187 | } 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /firmware/MPL3115A2_FIFO_example/types.h: -------------------------------------------------------------------------------- 1 | //useful things to include in code 2 | 3 | #ifndef TYPES_H 4 | #define TYPES_H 5 | 6 | #ifndef WIN32 7 | // true/false defines 8 | #define FALSE 0 9 | #define TRUE -1 10 | #endif 11 | 12 | // datatype definitions macros 13 | typedef unsigned char u08; 14 | typedef signed char s08; 15 | typedef unsigned short u16; 16 | typedef signed short s16; 17 | typedef unsigned long u32; 18 | typedef signed long s32; 19 | typedef unsigned long long u64; 20 | typedef signed long long s64; 21 | 22 | /* use inttypes.h instead 23 | // C99 standard integer type definitions 24 | typedef unsigned char uint8_t; 25 | typedef signed char int8_t; 26 | typedef unsigned short uint16_t; 27 | typedef signed short int16_t; 28 | typedef unsigned long uint32_t; 29 | typedef signed long int32_t; 30 | typedef unsigned long uint64_t; 31 | typedef signed long int64_t; 32 | */ 33 | // maximum value that can be held 34 | // by unsigned data types (8,16,32bits) 35 | #define MAX_U08 255 36 | #define MAX_U16 65535 37 | #define MAX_U32 4294967295 38 | 39 | // maximum values that can be held 40 | // by signed data types (8,16,32bits) 41 | #define MIN_S08 -128 42 | #define MAX_S08 127 43 | #define MIN_S16 -32768 44 | #define MAX_S16 32767 45 | #define MIN_S32 -2147483648 46 | #define MAX_S32 2147483647 47 | 48 | #ifndef WIN32 49 | // more type redefinitions 50 | typedef unsigned char BOOL; 51 | typedef unsigned char BYTE; 52 | typedef unsigned int WORD; 53 | typedef unsigned long DWORD; 54 | 55 | typedef unsigned char UCHAR; 56 | typedef unsigned int UINT; 57 | typedef unsigned short USHORT; 58 | typedef unsigned long ULONG; 59 | 60 | typedef char CHAR; 61 | typedef int INT; 62 | typedef long LONG; 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /firmware/README.md: -------------------------------------------------------------------------------- 1 | This is example Arduino code that allows you to print the raw altitude and temperature values in meters. No libraries are needed and all the I2C communication is handeled using the built-in wire functions. 2 | 3 | [Creative Commons Attribution-ShareAlike](http://creativecommons.org/licenses/by-sa/3.0/) 4 | -------------------------------------------------------------------------------- /firmware/SparkFun_Simple_Sketch_MPL3115A2/SparkFun_Simple_Sketch_mpl3115a2.ino: -------------------------------------------------------------------------------- 1 | 2 | /****************************************************************************** 3 | 4 | 5 | 6 | 7 | 8 | Simple Sketch to get started. 9 | 10 | This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 11 | Distributed as-is; no warranty is given. 12 | */ 13 | 14 | // PIR example 15 | #include 16 | #include 17 | #include 18 | 19 | SoftwareSerial display(3, 2); 20 | 21 | //Create an instance of the object 22 | MPL3115A2 myPressure; 23 | 24 | char pastring[10]; 25 | char tmpstring[10]; 26 | 27 | float pressure; 28 | float temperature; 29 | 30 | int ipress; 31 | int itemp; 32 | 33 | void setup() 34 | { 35 | Wire.begin(); // Join i2c bus 36 | Serial.begin(9600); // Start serial for output 37 | 38 | myPressure.begin(); // Get sensor online 39 | 40 | myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa 41 | 42 | myPressure.setOversampleRate(7); // Set Oversample to the recommended 128 43 | myPressure.enableEventFlags(); // Enable all three pressure and temp event flags 44 | 45 | display.begin(9600); 46 | Serial.begin(9600); 47 | delay(500); 48 | 49 | display.write(254); // move cursor to beginning of first line 50 | display.write(128); 51 | 52 | display.write(" "); // clear display 53 | display.write(" "); 54 | } 55 | 56 | void loop() 57 | { 58 | pressure = myPressure.readPressure(); 59 | ipress = pressure; 60 | sprintf(pastring, "%3d", ipress); 61 | 62 | Serial.print("Pressure(Pa): "); 63 | Serial.print(pastring); 64 | 65 | display.write("Pres (Pa): "); 66 | display.write(pastring); 67 | 68 | temperature = myPressure.readTempF(); 69 | itemp = temperature; 70 | sprintf(tmpstring, "%3d", itemp); 71 | 72 | Serial.print(" Temp(f): "); 73 | Serial.print(temperature, 2); 74 | 75 | display.write("Temp (f): "); 76 | display.write(tmpstring); 77 | 78 | Serial.println(); 79 | 80 | display.write(254); // move cursor to beginning of first line 81 | display.write(128); 82 | 83 | delay(100); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /hardware/MPL3115A2_breakout.brd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | v11 124 | MPL3115A2 125 | Altitude 126 | GND 127 | VCC 128 | SDA 129 | SCL 130 | INT1 131 | INT2 132 | Sensor 133 | 134 | 135 | 136 | 137 | 138 | <b>CAPACITOR</b><p> 139 | chip 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | >NAME 150 | >VALUE 151 | 152 | 153 | 154 | 155 | 156 | <b>CAPACITOR</b><p> 157 | chip 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | >NAME 167 | >VALUE 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | >NAME 186 | >VALUE 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | <b>Stand Off</b><p> 275 | This is the mechanical footprint for a #4 phillips button head screw. Use the keepout ring to avoid running the screw head into surrounding components. SKU : PRT-00447 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | >NAME 329 | >VALUE 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | Released under the Creative Commons Attribution Share-Alike 3.0 License 339 | http://creativecommons.org/licenses/by-sa/3.0 340 | Designed by: 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | <h3>SparkFun Electronics' preferred foot prints</h3> 349 | In this library you'll find sensors- accelerometers, gyros, compasses, magnetometers, light sensors, imagers, temp sensors, etc.<br><br> 350 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. 351 | <br><br> 352 | <b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. 353 | 354 | 355 | <h4>LGA8 Package</h4> 356 | <ul><li> 5.0x3.0x1.2mm</li> 357 | <li>8-pad</li><br></ul> 358 | Used in MPL115A1 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | >Name 382 | >Value 383 | pin 1 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | <b>EAGLE Design Rules</b> 398 | <p> 399 | The default Design Rules have been set to cover 400 | a wide range of applications. Your particular design 401 | may have different requirements, so please make the 402 | necessary adjustments and save your customized 403 | design rules under a new name. 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | -------------------------------------------------------------------------------- /hardware/README.md: -------------------------------------------------------------------------------- 1 | # What Are these Files? 2 | 3 | The .sch and .brd files hare are Eagle CAD schematic and PCB design files for the MPL3115A2 Breakout. 4 | 5 | These files were created with Eagle 6.2.0. There is a free, lite, version of Eagle available from [cadsoftusa.com](cadsoftusa.com). 6 | 7 | [Creative Commons Attribution-ShareAlike](http://creativecommons.org/licenses/by-sa/3.0/) 8 | --------------------------------------------------------------------------------