Lesen Sie Druck und Temperatur von Raspberry Pi 3 & BMP180 mit Java ab

Einführung

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

Vorbereitung

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".

Stellen Sie die Sensorinformationen von Raspberry Pi grafisch dar und bereiten Sie eine Umgebung vor, die mit einem Webbrowser überprüft werden kann

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.

BMP180_ブレッドボード.png

Sensorbetriebsart

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. BMP180_Datasheet.png

(Referenz) BMP180-Datenblatt

Programm

Verfassung

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:~ $

Quellcode

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);
    }
}

Kompilieren und ausführen

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:~ $

Vorsichtsmaßnahmen bei der Verwendung des Programms

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.

Instanz erstellen

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

Methode

Die folgenden Methoden stehen zur Verfügung.

Methoden und Merkmale
public double readTemperature() throws IOException, InterruptedException
Es liest die Temperatur vom Sensor und gibt diesen Wert zurück. Die Einheit ist Grad (Sätze).
public static double convertToFahrenheit(double c)
Wenn Sie für den Parameter einen Gradwert (in Grad Celsius) angeben, wird dieser in Grad (in Grad Celsius) konvertiert und zurückgegeben.
public double readPressure() throws IOException, InterruptedException
Es liest den Druck vom Sensor und gibt diesen Wert zurück. Die Einheit ist hPa (Hektopascal).
public void setStandardSeaLevelPressure(double standardSeaLevelPressure)
Stellen Sie den Meeresspiegeldruck ein, um die Höhenmessung vorzubereiten. Die Einheit wird durch hPa (Hektopascal) spezifiziert.
public double readAltitude() throws IOException, InterruptedException
Gibt die Höhe basierend auf dem vom Sensor abgelesenen Druck und dem voreingestellten Meeresspiegeldruck zurück. Die Einheit ist m (Meter).

Recommended Posts

Lesen Sie Druck und Temperatur von Raspberry Pi 3 & BMP180 mit Java ab
Lesen Sie Temperatur / Luftfeuchtigkeit von Raspberry Pi 3 & DHT11 mit Java ab
Zeigen Sie Zeichen auf dem I2C 1602 LCD mit Raspberry Pi 3 und Java an
Suchen Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java
Korrigieren Sie den Zeichencode in Java und lesen Sie von der URL
Konvertieren Sie Excel mit Java in Blob, speichern Sie es, lesen Sie es aus der Datenbank und geben Sie es als Datei aus!
Stellen Sie die Sensorinformationen von Raspberry Pi in Java grafisch dar und überprüfen Sie sie mit einem Webbrowser
Suchen und Ausführen einer Methode aus einer Instanz mit Verarbeitung (Java)
Verarbeiten Sie die vom menschlichen Sensor HC-SR501 erkannte Bewegung mit Raspberry Pi 3 & Java
Zeigen Sie benutzerdefinierte Zeichen auf dem I2C 1602 LCD mit Raspberry Pi 3 und Java an
Einfache Überwachung des Innenraumklimas - ⑩ Beziehen Sie Temperatur / Luftfeuchtigkeit / Druck von BME280 (Ersatz) mit Java (I2C / Pi4J) -
Verwenden Sie Java mit MSYS und Cygwin
Installieren Sie Java und Tomcat mit Ansible
Verwenden Sie JDBC mit Java und Scala.
PDF und TIFF mit Java 8 ausgeben
Arbeiten Sie mit Google-Tabellen aus Java
Mit Java verschlüsseln und mit C # entschlüsseln
Finden Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java [Abkochung Nr. 2]
[Java] Json von der URL mit der Standard-API (javax.script) abrufen und verarbeiten
Verwenden von Java mit AWS Lambda-Implementierungstipps - Abrufen des Instanznamens aus Reagion und Instanz-ID