Skip to content

Instantly share code, notes, and snippets.

@ibaca
Created June 17, 2014 18:08
Show Gist options
  • Save ibaca/5b7cd346837619e8ee7e to your computer and use it in GitHub Desktop.
Save ibaca/5b7cd346837619e8ee7e to your computer and use it in GitHub Desktop.
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