Created
June 17, 2014 18:08
-
-
Save ibaca/5b7cd346837619e8ee7e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package javaapplication1; | |
import tempbarosensor.I2CSensor; | |
public class MPL115A2 extends I2CSensor { | |
private static final int ADDRESS = 0x60; | |
private final double a0; | |
private final double b1; | |
private final double b2; | |
private final double c12; | |
public MPL115A2() { | |
super(ADDRESS); | |
// Read coefficients | |
this.a0 = REGISTER_A0.read(this); | |
this.b1 = REGISTER_B1.read(this); | |
this.b2 = REGISTER_B2.read(this); | |
this.c12 = REGISTER_C12.read(this); | |
} | |
/** Returns a tuple of (pressure, temperature) as measured by the sensor. */ | |
public double[] getPT() { | |
// Instruct the sensor to begin data conversion. | |
writeOneByte(0x12, (byte) 0x00); | |
// Wait until conversion has finished. The datasheet says "3ms". We'll wait 5ms just to be sure. | |
try { | |
Thread.sleep(5); | |
} catch (InterruptedException ignore) {} | |
// Read the raw values. | |
double padc = REGISTER_PADC.read(this); | |
double tadc = REGISTER_TADC.read(this); | |
// Calculate compensated pressure value (Pcomp = a0 + (b1 * c12 * Tadc) * Padc * b(c)) | |
double pcomp = a0 + (b1 + c12 * tadc) * padc + b2 * tadc; | |
/* | |
* Calculate final values. The formula for pressure is from section 3.2 of the datasheet. The formula for | |
* temperature is basically magic: http://www.adafruit.com/forums/viewtopic.php?f=19&t=41347 | |
*/ | |
double pressure = pcomp * ((115. - 50.) / 1023.) + 50.; | |
double temperature = (tadc - 498.) / -5.35 + 25.; | |
return new double[] { pressure, temperature }; | |
} | |
/** Pressure in kPa. */ | |
public double getPressure() { | |
return getPT()[0]; | |
} | |
/** */ | |
public double getTemperature() { | |
return getPT()[1]; | |
} | |
/** From the section 3.1 table. */ | |
//@formatter:off address bits | |
// total sign frac dec.zero.pad | |
public static Register REGISTER_PADC = new Register("Padc", 0x00, 10, 0, 0, 0); | |
public static Register REGISTER_TADC = new Register("Tadc", 0x02, 10, 0, 0, 0); | |
public static Register REGISTER_A0 = new Register("A0", 0x04, 16, 1, 3, 0); | |
public static Register REGISTER_B1 = new Register("B1", 0x06, 16, 1, 13, 0); | |
public static Register REGISTER_B2 = new Register("B2", 0x08, 16, 1, 14, 0); | |
public static Register REGISTER_C12 = new Register("C12", 0x0A, 14, 1, 13, 9); | |
//@formatter:on | |
public static class Register { | |
private final String name; | |
private final int address; | |
private final int totalBits; | |
private final int signBits; | |
private final int fractionalBits; | |
private final int decimalZeroPadding; | |
/** | |
* Each register is two bytes wide, with the values left-aligned in the register. | |
* | |
* @param totalBits gives the total number of data bits (and is used to calculate how much right shifting is | |
* needed to eliminate the padding). | |
* @param signBits is the number of bits reserved for sign information and determines whether the value is read | |
* as a signed or unsigned number. | |
* @param fractionalBits gives the number of bits that should be considered to follow the decimal point. | |
* @param decimalZeroPadding gives the number of additional zero bits that should be considered to exist between | |
* the decimal point and the first data bit. | |
*/ | |
public Register(String name, int address, int totalBits, int signBits, int fractionalBits, | |
int decimalZeroPadding) { | |
this.name = name; | |
this.address = address; | |
this.totalBits = totalBits; | |
this.signBits = signBits; | |
this.fractionalBits = fractionalBits; | |
this.decimalZeroPadding = decimalZeroPadding; | |
} | |
public double read(I2CSensor i2c) { | |
// Get the data from the register | |
final int rawValue = i2c.readOneWord(this.address); | |
final double apply = apply(rawValue); | |
System.out.println("read(" + name + "): " + apply + "[0x" + Integer.toHexString(rawValue) + "]"); | |
return apply; | |
} | |
public double apply(int rawValue) { | |
// Negative values are stored in two's-complement | |
if (signBits == 1 && (rawValue & 0x8000) != 0) rawValue = rawValue ^ 0xFFFF * -1; | |
// Apply the bit parameters | |
return ((double) (rawValue >> (16 - totalBits))) / Math.pow(2, (fractionalBits + decimalZeroPadding)); | |
} | |
/* Power method with base x and power y (i.e., x^y) */ | |
int pow(int x, int y) { | |
int z = x; | |
for (int i = 1; i < y; i++) | |
z *= x; | |
return z; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment