Verwenden Sie den Raspberry Pi 3, um Druck- und Temperaturinformationen vom Druck- und Temperatursensor BMP180 zu lesen. Wenn Sie den Meeresspiegeldruck angeben, wird die Höhe des Messpunkts basierend auf dem gemessenen Druck berechnet. Die Programmiersprache verwendet Java.
BMP180 |
---|
Verwenden Sie Pi4J, um den GPIO des Raspberry Pi von Java aus zu steuern. Informationen zur Pi4J-Umgebung finden Sie im folgenden Artikel unter "Installieren von Pi4J".
Da dieser Sensor mit I2C kommuniziert, ist die I2C-Kommunikationsfunktion von Raspberry Pi aktiviert (standardmäßig deaktiviert).
Um es über die Raspbian-Benutzeroberfläche zu aktivieren, öffnen Sie das Einstellungsfeld unter "Einstellungen" - "Raspberry Pi-Einstellungen" über die Schaltfläche "Menü" in der Taskleiste und wählen Sie die Registerkarte "Schnittstelle", um "I2C" zu aktivieren. Um es über die Befehlszeile zu aktivieren, geben Sie den Befehl sudo raspi-config ein, wählen Sie Schnittstellenoptionen> I2C und schließlich Ja.
Starten Sie nach dem Einstellen für alle Fälle neu.
Der Raspberry Pi und der BMP180 wurden wie folgt verbunden.
Dieser Sensor liest beim Ablesen des Drucks einen von vier Modi. Die Anzahl der Abtastwerte (Genauigkeit) und der Stromverbrauch hängen vom angegebenen Modus ab. Dieser Modus ist nur beim Ablesen des Drucks gültig und für das Ablesen der Temperatur irrelevant.
(Referenz) BMP180-Datenblatt
Das Programm besteht aus den folgenden zwei Dateien. BMP180Demo.java BMP180.java
Die Sensoradresse nimmt die Standardeinstellung 77H an. Geben Sie nach dem Anschließen des Sensors den folgenden Befehl ein. Wenn er an einer anderen Stelle als 77H erkannt wird, setzen Sie den Wert auf die in BMP180.java definierte Konstante I2C_ADRESS.
pi@raspberrypi:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77
pi@raspberrypi:~ $
BMP180Demo.java
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class BMP180Demo {
public static void main(String[] args) throws Exception {
BMP180 bmp180 = new BMP180(); // use I2C bus 1, standard mode
// BMP180 bmp180 = new BMP180(BMP180.ULTRAHIGHRES); // use I2C bus 1, ultra high resolution mode
// BMP180 bmp180 = new BMP180(BMP180.HIGHRES); // use I2C bus 1, high resolution mode
// BMP180 bmp180 = new BMP180(BMP180.STANDARD); // use I2C bus 1, standared mode
// BMP180 bmp180 = new BMP180(BMP180.ULTRALOWPOWER); // use I2C bus 1, ultra low power mode
while (true) {
System.out.println("Last valid input: " + new Date());
double temperature = bmp180.readTemperature();
System.out.printf("Temperature: %.2f C (%.1f F)\n",
temperature, BMP180.convertToFahrenheit(temperature));
double pressure = bmp180.readPressure();
System.out.printf("Pressure : %.2f hPa\n", pressure);
// bmp180.setStandardSeaLevelPressure(pressure); // specify sea level pressure in hPa
System.out.printf("Altitude : %.2f m\n\n", bmp180.readAltitude());
TimeUnit.SECONDS.sleep(1);
}
}
}
BMP180.java
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;
public class BMP180 {
// Hardware pressure sampling accuracy modes
public static final int ULTRALOWPOWER = 0;
public static final int STANDARD = 1;
public static final int HIGHRES = 2;
public static final int ULTRAHIGHRES = 3;
private int mode;
// Registers
private static final int CAL_AC1 = 0xAA;
private static final int CTRL_MEAS = 0xF4;
private static final int OUT_MSB = 0xF6;
// Commands
private static final byte CMD_READTEMP = 0x2E;
private static final byte CMD_READPRESSURE = 0x34;
private static final int I2C_BUS = I2CBus.BUS_1;
private static final int I2C_ADDRESS = 0x77;
private I2CDevice device;
private int AC1;
private int AC2;
private int AC3;
private int AC4;
private int AC5;
private int AC6;
private int B1 ;
private int B2 ;
private int MB ;
private int MC ;
private int MD ;
private double standardSeaLevelPressure = 1013.89; // avarage sea level pressure in Tokyo
public BMP180(int i2cBus, int i2cAddress, int mode) throws UnsupportedBusNumberException, IOException {
// Create I2C bus
I2CBus bus = I2CFactory.getInstance(i2cBus);
// Get I2C device
device = bus.getDevice(i2cAddress);
// Calibration Coefficients stored in EEPROM of the device
// Read 22 bytes of data from address 0xAA(170)
byte[] data = new byte[22];
device.read(CAL_AC1, data, 0, data.length);
// Convert the data
AC1 = INT (data[ 0], data[ 1]);
AC2 = INT (data[ 2], data[ 3]);
AC3 = INT (data[ 4], data[ 5]);
AC4 = UINT(data[ 6], data[ 7]);
AC5 = UINT(data[ 8], data[ 9]);
AC6 = UINT(data[10], data[11]);
B1 = INT (data[12], data[13]);
B2 = INT (data[14], data[15]);
MB = INT (data[16], data[17]);
MC = INT (data[18], data[19]);
MD = INT (data[20], data[21]);
this.mode = mode;
}
public BMP180(int mode) throws UnsupportedBusNumberException, IOException {
this(I2C_BUS, I2C_ADDRESS, mode);
}
public BMP180() throws UnsupportedBusNumberException, IOException {
this(BMP180.STANDARD);
}
private int readAndCalcB5() throws IOException, InterruptedException {
// Select measurement control register
// Enable temperature measurement
device.write(CTRL_MEAS, CMD_READTEMP);
TimeUnit.MILLISECONDS.sleep(5);
// Read 2 bytes of data from address 0xF6(246)
// temp msb, temp lsb
byte[] data = new byte[2];
device.read(OUT_MSB, data, 0, data.length);
// Convert the data
int UT = UINT(data[0], data[1]);
// Callibration for Temperature
int X1 = ((UT - AC6) * AC5) >> 15;
int X2 = (MC << 11) / (X1 + MD);
int B5 = X1 + X2;
return B5;
}
public double readTemperature() throws IOException, InterruptedException {
return ((readAndCalcB5() + 8) >> 4) / 10.0;
}
public static double convertToFahrenheit(double c) {
return c * 1.8 + 32.0;
}
public double readPressure() throws IOException, InterruptedException {
// Select measurement control register
// Enable pressure measurement
device.write(CTRL_MEAS, (byte)(CMD_READPRESSURE + (mode << 6)));
switch (mode) {
case ULTRALOWPOWER:
TimeUnit.MILLISECONDS.sleep(5);
break;
case STANDARD:
TimeUnit.MILLISECONDS.sleep(8);
break;
case HIGHRES:
TimeUnit.MILLISECONDS.sleep(14);
break;
default:
TimeUnit.MILLISECONDS.sleep(26); // ULTRAHIGHRES mode
break;
}
// Read 3 bytes of data from address 0xF6(246)
// pres msb1, pres msb, pres lsb
byte[] data = new byte[3];
device.read(OUT_MSB, data, 0, data.length);
int UP = UINT(data[0], data[1], data[2]) >> (8 - mode);
// Calibration for Pressure
int B6 = readAndCalcB5() - 4000;
int X1 = (B2 * (B6 * B6) >> 12) >> 11;
int X2 = (AC2 * B6) >> 11;
int X3 = X1 + X2;
int B3 = (((AC1 * 4 + X3) << mode) + 2) / 4;
X1 = (AC3 * B6) >> 13;
X2 = (B1 * ((B6 * B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
int B4 = (AC4 * (X3 + 32768)) >> 15;
int B7 = (UP - B3) * (50000 >> mode);
int p = B7 < 0x80000000 ? (B7 * 2) / B4 : (B7 / B4) * 2;
X1 = (p >> 8) * (p >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * p) >> 16;
p = p + ((X1 + X2 + 3791) >> 4);
return p / 100.0;
}
public void setStandardSeaLevelPressure(double standardSeaLevelPressure) {
this.standardSeaLevelPressure = standardSeaLevelPressure;
}
public double readAltitude() throws IOException, InterruptedException {
// Calculates the altitude in meters
double pressure = readPressure();
return 44330.0 * (1.0 - Math.pow(pressure / standardSeaLevelPressure, 0.1903));
}
private int INT(byte msb, byte lsb) {
int hi = msb & 0xFF;
return ((hi > 127 ? hi - 256 : hi) << 8) + (lsb & 0xFF);
}
private int UINT(byte msb, byte lsb) {
return ((msb & 0xFF) << 8) + (lsb & 0xFF);
}
private int UINT(byte msb, byte lsb, byte xlsb) {
return ((msb & 0xFF) << 16) + UINT(lsb, xlsb);
}
}
Legen Sie die beiden oben genannten Dateien in ein geeignetes Verzeichnis und kompilieren Sie sie.
pi@raspberrypi:~ $ pi4j -c BMP180Demo.java
--------------------------------------------
Pi4J - Compiling: BMP180Demo.java
--------------------------------------------
+ javac -classpath '.:classes:*:classes:/opt/pi4j/lib/*' -d . BMP180Demo.java
pi@raspberrypi:~ $
Führen Sie nach dem Kompilieren die Root-Berechtigungen aus. Liest und zeigt jede Sekunde Temperatur-, Druck- und Höhendaten an.
Für die Höhe wird durch vorherige Angabe des Meeresspiegeldrucks der Wert auf der Grundlage der Druckdifferenz vom Messort berechnet. Wenn kein Meeresspiegeldruck angegeben ist, wird standardmäßig der jährliche durchschnittliche Meeresspiegeldruck in Tokio verwendet. An Tagen mit hohem Druck kann er unter die Meeresoberfläche sinken.
Geben Sie Strg + C ein, um das Programm zu beenden.
pi@raspberrypi:~ $ sudo pi4j BMP180Demo
+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' BMP180Demo
Last valid input: Sun May 13 20:29:44 JST 2018
Temperature: 23.70 C (74.7 F)
Pressure : 1000.57 hPa
Altitude : 110.92 m
Last valid input: Sun May 13 20:29:45 JST 2018
Temperature: 23.60 C (74.5 F)
Pressure : 1000.73 hPa
Altitude : 109.57 m
Last valid input: Sun May 13 20:29:46 JST 2018
Temperature: 23.60 C (74.5 F)
Pressure : 1000.57 hPa
Altitude : 110.75 m
Last valid input: Sun May 13 20:29:47 JST 2018
Temperature: 23.60 C (74.5 F)
Pressure : 1000.69 hPa
Altitude : 110.08 m
^Cpi@raspberrypi:~ $
Alles, was Sie benötigen, um das Programm tatsächlich zu verwenden, ist die Datei BMP180.java. Hier erfahren Sie, wie Sie eine Instanz erstellen und welche Methoden Sie verwenden können.
Es gibt drei Möglichkeiten, die Parameter des Konstruktors der Klasse BMP180 anzugeben.
BMP180 bmp180 = new BMP180(); //I2C-Bus 1, Adresse 0x77, arbeitet im Standardmodus
BMP180 bmp180 = new BMP180(BMP180.ULTRAHIGHRES); //I2C-Bus 1, Adresse 0x77, arbeitet im Ultra High Resoluion-Modus
BMP180 bmp180 = new BMP180(2, 0x01, BMP180.STANDARD); //I2C-Bus 2, Adresse 0x01, arbeitet im Standardmodus
Geben Sie eine der folgenden Optionen an, um den Modus anzugeben.
BMP180.ULTRALOWPOWER //Ultra Low Power-Modus
BMP180.STANDARD //Standart Modus
BMP180.HIGHRES //Hochauflösender Modus
BMP180.ULTRAHIGHRES //Ultrahochauflösender Modus
Die folgenden Methoden stehen zur Verfügung.
Methoden und Merkmale |
---|
public double readTemperature() throws IOException, InterruptedException |
|
public static double convertToFahrenheit(double c) |
|
public double readPressure() throws IOException, InterruptedException |
|
public void setStandardSeaLevelPressure(double standardSeaLevelPressure) |
|
public double readAltitude() throws IOException, InterruptedException |
|
Recommended Posts