Easily monitor the indoor environment-② Catch the Bluetooth LE advertisement signal with Java (Bluetooth LE / bluez-dbus)-

Introduction

Since I chose Java / Raspberry Pi 3B as the platform, I will look for a Java library that communicates with various sensors in this environment.

First of all, about Bluetooth LE. In recent years, devices that can acquire sensor data via BLE communication have appeared. This time, I chose the major Texas Instruments SensorTag CC2650. CC2650 is a button battery-powered BLE device of about 5 cm x 4 cm that can measure temperature, humidity, illuminance, barometric pressure, angular velocity, acceleration, and magnetism.

The usage of CC2650 is as follows.

  1. Turn on the power of CC2650 (peripheral) and send an advertisement signal.
  2. Central catches the advertisement signal and connects to CC2650 (CC2650 stops the advertisement signal)
  3. Central acquires sensor data from CC2650 using BLE GATT profile

In addition, CC2650 automatically turns off the power if it is not connected from anywhere within 3 minutes after starting to transmit the advertisement signal. So you need to turn it on again to prepare for the connection. This time, we adopted bluez-dbus as a Java library that supports BLE communication when catching advertisement signals with Java.

I used to write code in Java to get sensor data from CC2650 on a trial basis. At that time, bluez-dbus was not yet available, and it was just around the time when Intel TinyB was released as another library for BLE communication with Java. did. However, TinyB, which had just been released, was unstable, and at that time, the Notification function of BLE could not be used. Above all, the dbus I / F definition file published by bluez is automatically converted to C / C ++ code (more than 10,000 lines of code are automatically generated), and TinyB is created by further modifying this. I felt that the maintainability was very low.

When using BLE with dbus I / F, dbus itself is defined on a UNIX domain socket, so essentially only this UNIX domain socket part is written in JNI and defined on it. I thought that the dbus protocol for bluez was simple to implement by calling this JNI.

At that time, I had no choice but to write Java code that links various bluez commands as a resident process, and I surpassed it. It's a complicated architecture, and I thought it was awkward. I forgot the code at that time, but this crappy impression still remains.

The days have passed since then, and now a library called bluez-dbus that supports BLE has been released. When I read the developer motives written on Github, it's just like I thought. (Well, I think so ...)

So, this time, I wrote the code privately with a simple architecture that adopted bluez-dbus. The introduction is longer, but the text is shorter. Basically, it is exactly what you wrote in Github. See the code for details.

OS installation

Raspbian Buster Lite OS (2019-07-10) is used as the OS of Raspberry Pi 3B. This OS includes BlueZ 5.50, which is supported by bluez-dbus, from the beginning, so there is no need to build BlueZ again.

Java installation

I think there are some Java for ARM version Linux, but I changed jdk11 of BELLSOFT to apt-get. I put it in .com /).

# wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | apt-key add -
# echo "deb [arch=armhf] https://apt.bell-sw.com/ stable main" | tee /etc/apt/sources.list.d/bellsoft.list
# apt-get update
# apt-get install bellsoft-java11

What is bluetooth-scanner?

This module is for catching BLE advertisement signals. The purpose is to dynamically recognize that a BLE device has entered the range of central BLE communication. Specifically, the CC2650 approaches and Central recognizes its existence and triggers it to connect.

In addition, the connected CC2650 goes out of the communication range of Central, BLE communication is disconnected (the advertisement signal is restarted), and then it approaches again, Central catches the advertisement signal and automatically switches to CC2650 It is also supposed to be a trigger to reconnect.

** bluetooth-scanner ** The key to processing is dbus-java Prepare a class that is ʻextends of ʻAbstractPropertiesChangedHandler.java provided by, and implementpublic void handle (PropertiesChanged properties). See the code on Github for more information. Below is a sample of how to use ** bluetooth-scanner **. Implement ʻIScanHandlerʻinterface to create an instance of ScanProcess.java and call start ().

import com.github.hypfvieh.bluetooth.DiscoveryFilter;
import com.github.hypfvieh.bluetooth.DiscoveryTransport;
import com.github.hypfvieh.bluetooth.wrapper.BluetoothDevice;

import io.github.s5uishida.iot.bluetooth.scanner.IScanHandler;
import io.github.s5uishida.iot.bluetooth.scanner.ScanData;
import io.github.s5uishida.iot.bluetooth.scanner.ScanProcess;

public class MyScan {
    public static void main(String[] args) throws IOException, InterruptedException {
        Map<DiscoveryFilter, Object> filter = new HashMap<DiscoveryFilter, Object>();
        filter.put(DiscoveryFilter.Transport, DiscoveryTransport.LE);
        
        ScanProcess scanProcess = new ScanProcess("hci0", new MyScanHandler(), filter);
        scanProcess.start();
    }
}

class MyScanHandler implements IScanHandler {
    private static final Logger LOG = LoggerFactory.getLogger(MyScanHandler.class);
    
    @Override
    public void handle(BluetoothDevice device, ScanData data) {
        LOG.info(device.toString());
        LOG.info(data.toString());
    }
}

An example of the execution log is as follows. The beginning of the line is omitted.

MyScanHandler handle - BluetoothDevice [device=org.bluez:/org/bluez/hci0/dev_24_71_89_06_9D_82:interface org.bluez.Device1, adapter=/org/bluez/hci0, getBluetoothType()=DEVICE, getDbusPath()=/org/bluez/hci0/dev_24_71_89_06_9D_82] 
MyScanHandler handle - [hci0] 24:71:89:06:9D:82 name:CC2650 SensorTag rssi:-63 txPower:0 date:2019-09-03 22:40:25.483

A series of articles

This series consists of the following articles:

  1. Motivation and Concept
  2. ** Catch Bluetooth LE advertisement signal with Java (Bluetooth LE / bluez-dbus) (this time) ** The related Github is here.
  3. Get temperature / humidity / illuminance etc. from TI SensorTag CC2650 with Java (Bluetooth LE / bluez-dbus) The related Github is here.
  4. Obtain CO2 concentration from MH-Z19B with Java (serial communication / jSerialComm) The related Github is here.
  5. Get PM2.5 concentration from PPD42NS in Java (GPIO / Pi4J) The related Github is here.
  6. Getting operational information of industrial automation equipment in Java (OPC-UA / Eclipse Milo) The related Github is here.
  7. Collect in a simple tool The related Github is here.
  8. Postscript

Postscript

[2019.11.16] For the latest information on simple tools, please refer to here.

Recommended Posts

Easily monitor the indoor environment-② Catch the Bluetooth LE advertisement signal with Java (Bluetooth LE / bluez-dbus)-
Easily monitor the indoor environment ~ ③ Get temperature / humidity / illuminance etc. from TI SensorTag CC2650 with Java (Bluetooth LE / bluez-dbus) ~
Easily monitor the indoor environment-⑪ Obtain the illuminance with Java from BH1750FVI (substitute)-(I2C / Pi4J)-
Easily monitor the indoor environment ~ ⑧ Postscript ~
Easily monitor the indoor environment-⑤ Obtain PM2.5 concentration from PPD42NS with Java (GPIO / Pi4J)-
Easily monitor the indoor environment- (1) Motivation and concept-
Easily monitor the indoor environment-⑩ Obtain temperature / humidity / atmospheric pressure from BME280 (substitute) with Java (I2C / Pi4J)-
Easily monitor the indoor environment ~ ⑨ Get motion detection (HC-SR501 / RCWL-0516) in Java (GPIO / Pi4J) ~
Easily monitor the indoor environment-⑦ Summarize in a simple tool-
Easily monitor the indoor environment-⑥ Acquire operation information of industrial automation equipment in Java (OPC-UA / Eclipse Milo)-
Monitor the internal state of Java programs with Kubernetes
Prepare the environment for java11 and javaFx with Ubuntu 18.4