Lire la pression et la température de Raspberry Pi 3 et BMP180 avec Java

introduction

Utilisez le Raspberry Pi 3 pour lire les informations de pression et de température du capteur de pression et de température BMP180. Si vous spécifiez la pression au niveau de la mer, l'altitude du point de mesure sera calculée en fonction de la pression mesurée. Le langage de programmation utilise Java.

BMP180

Préparation

Utilisez Pi4J pour contrôler le GPIO du Raspberry Pi à partir de Java. Pour l'environnement Pi4J, reportez-vous à «Installation de Pi4J» dans l'article suivant.

Représentez graphiquement les informations du capteur de Raspberry Pi et préparez un environnement qui peut être vérifié avec un navigateur Web

De plus, puisque ce capteur communique via I2C, activez la fonction de communication I2C du Raspberry Pi (elle est désactivée par défaut).

Pour l'activer à partir de l'interface graphique Raspbian, ouvrez le panneau des paramètres depuis "Paramètres" - "Paramètres Raspberry Pi" depuis le bouton "Menu" de la barre des tâches, et sélectionnez l'onglet "Interface" pour activer "I2C". Pour l'activer à partir de la ligne de commande, entrez la commande sudo raspi-config, sélectionnez Options d'interfaçage> I2C, puis sélectionnez Oui.

Après le réglage, redémarrez au cas où.

Le Raspberry Pi et le BMP180 ont été connectés comme suit.

BMP180_ブレッドボード.png

Mode de fonctionnement du capteur

Ce capteur lit l'un des quatre modes lors de la lecture de la pression. Le nombre d'échantillons (précision) et la consommation électrique varient en fonction du mode spécifié. Ce mode n'est valable que lors de la lecture de la pression et n'est pas pertinent pour la lecture de la température. BMP180_Datasheet.png

(Référence) BMP180 Datasheet

programme

Constitution

Le programme se compose des deux fichiers suivants. BMP180Demo.java BMP180.java

L'adresse du capteur prend la valeur par défaut 77H. Après avoir connecté le capteur, entrez la commande suivante, et s'il est reconnu dans un endroit autre que 77H, définissez la valeur sur la constante I2C_ADRESS définie dans BMP180.java.

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

Code source

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

Compiler et exécuter

Placez les deux fichiers ci-dessus dans un répertoire approprié et compilez.

pi@raspberrypi:~ $ pi4j -c BMP180Demo.java
--------------------------------------------
Pi4J - Compiling: BMP180Demo.java
--------------------------------------------
+ javac -classpath '.:classes:*:classes:/opt/pi4j/lib/*' -d . BMP180Demo.java
pi@raspberrypi:~ $

Après la compilation, exécutez avec les privilèges root. Lit et affiche les données de température, de pression et d'altitude toutes les secondes.

Pour l'altitude, en spécifiant à l'avance la pression au niveau de la mer, la valeur est calculée en fonction de la différence de pression par rapport au lieu de mesure. Si aucune pression au niveau de la mer n'est spécifiée, la pression annuelle moyenne au niveau de la mer à Tokyo sera utilisée par défaut. Les jours où la pression est élevée, il peut descendre sous la surface de la mer.

Entrez Ctrl + C pour quitter le programme.

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

Précautions lors de l'utilisation du programme

Tout ce dont vous avez besoin pour utiliser réellement le programme est le fichier BMP180.java. Voici comment créer une instance et les méthodes que vous pouvez utiliser:

Créer une instance

Il existe trois façons de spécifier les paramètres du constructeur de la classe BMP180.

BMP180 bmp180 = new BMP180();                         //Bus I2C 1, adresse 0x77, fonctionnant en mode Standard

BMP180 bmp180 = new BMP180(BMP180.ULTRAHIGHRES);      //Bus I2C 1, adresse 0x77, fonctionnant en mode Ultra High Resoluion

BMP180 bmp180 = new BMP180(2, 0x01, BMP180.STANDARD); //Bus I2C 2, adresse 0x01, fonctionnant en mode Standard

Pour spécifier le mode, spécifiez l'une des options suivantes.

BMP180.ULTRALOWPOWER   //Mode ultra faible consommation
BMP180.STANDARD        //Mode standard
BMP180.HIGHRES         //Mode haute résolution
BMP180.ULTRAHIGHRES    //Mode ultra haute résolution

Méthode

Les méthodes suivantes sont disponibles.

Méthodes et fonctionnalités
public double readTemperature() throws IOException, InterruptedException
Il lit la température du capteur et renvoie cette valeur. L'unité est les degrés (ensembles).
public static double convertToFahrenheit(double c)
Si vous spécifiez une valeur de degrés (en degrés Celsius) pour le paramètre, il sera converti en degrés (en degrés Celsius) et renvoyé.
public double readPressure() throws IOException, InterruptedException
Il lit la pression du capteur et renvoie cette valeur. L'unité est hPa (hectopascal).
public void setStandardSeaLevelPressure(double standardSeaLevelPressure)
Réglez la pression au niveau de la mer en vue de mesurer l'altitude. L'unité est spécifiée par hPa (hectopascal).
public double readAltitude() throws IOException, InterruptedException
Renvoie l'altitude en fonction de la pression lue par le capteur et de la pression préréglée au niveau de la mer. L'unité est le m (mètres).

Recommended Posts

Lire la pression et la température de Raspberry Pi 3 et BMP180 avec Java
Lire la température / l'humidité avec Java de Raspberry Pi 3 & DHT11
Afficher les caractères sur l'écran LCD I2C 1602 avec Raspberry Pi 3 et Java
Trouvez la classe d'adresse et le type d'adresse à partir de l'adresse IP avec Java
Corrigez le code de caractère en Java et lisez à partir de l'URL
Convertissez Excel en Blob avec java, enregistrez-le, lisez-le à partir de DB et exportez-le sous forme de fichier!
Représentez graphiquement les informations du capteur de Raspberry Pi en Java et vérifiez-les avec un navigateur Web
Rechercher et exécuter une méthode à partir d'une instance avec traitement (java)
Traitez le mouvement détecté par le capteur humain HC-SR501 avec Raspberry Pi 3 et Java
Afficher les caractères définis par l'utilisateur sur l'écran LCD I2C 1602 avec Raspberry Pi 3 et Java
Surveillez facilement l'environnement intérieur - ⑩ Obtenez température / humidité / pression à partir du BME280 (substitut) avec Java (I2C / Pi4J) -
Utiliser java avec MSYS et Cygwin
Installez Java et Tomcat avec Ansible
Utilisez JDBC avec Java et Scala.
Sortie PDF et TIFF avec Java 8
Travailler avec des feuilles de calcul Google à partir de Java
Crypter avec Java et décrypter avec C #
Trouvez la classe d'adresse et le type d'adresse à partir de l'adresse IP avec Java [décoction n ° 2]
[Java] Obtenir et gérer Json à partir d'une URL avec une API standard (javax.script)
Utilisation de Java avec AWS Lambda-Implementation Tips - Obtenir le nom de l'instance à partir de la réaction et de l'ID d'instance