Android Things使用Android打开物联网的大门——Android Things开发

Android Things:用户驱动-传感器

2017-05-01  本文已影响82人  1024工场

一、传感器简介


Android传感器框架支持多种传感器类型来测量物理环境的状况,并且从应用程序读取原始数据。使用传感器驱动,你的应用可以扩展框架,并且添加新的通过Peripheral I/O连接的传感器设备;
和Android内置的传感器一样,来自这些传感器的数据通过相同的SensorManager API进行分发。你的应用可以实现一个驱动程序来连接一个已知类型的新传感器,如加速度计,或者一个Android目前没有定义的传感器类型,如血糖传感器。

二、使用步骤


要实现我们自己的传感器驱动,有如下步骤:
1. 继承UserSensorDriver类并且覆盖read():

UserSensorDriver mDriver = new UserSensorDriver() {
    // Sensor data values
    float x, y, z;
    @Override
    public UserSensorReading read() {
        try {
            // ...read the sensor hardware...

            // Return a new reading
            return new UserSensorReading(new float[]{x, y, z});
        } (catch Exception e) {
            // Error occurred reading the sensor hardware
            throw new IOException("Unable to read sensor");
        }
    }
};
UserSensorDriver mDriver = new UserSensorDriver() {
    ... ... 
    // Called by the framework to toggle low power modes
    @Override
    public void setEnabled(boolean enabled) {
        if (enabled) {
            // Exit low power mode
        } else {
            // Enter low power mode
        }
    }
};

注意:没有低功耗模式的传感器仍然可以使用此回调来增加或减少数据的报告频率以管理功耗;

2. 描述传感器:
向Android框架添加一个新的传感器驱动:

UserSensor accelerometer = UserSensor.builder()
        .setName("GroveAccelerometer")
        .setVendor("Seeed")
        .setType(Sensor.TYPE_ACCELEROMETER)
        .setDriver(mDriver)
        .build();
UserSensor custom = UserSensor.builder()
        .setName("MySensor")
        .setVendor("MyCompany")
        .setCustomType(Sensor.TYPE_DEVICE_PRIVATE_BASE,
                "com.example.mysensor",
                Sensor.REPORTING_MODE_CONTINUOUS)
        .setDriver(mDriver)
        .build();

3. 注册传感器

public class SensorDriverService extends Service {
    UserSensor mAccelerometer;
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        UserDriverManager manager = UserDriverManager.getManager();

        // Create a new driver implementation
        mAccelerometer = ...;
        // Register the new driver with the framework
        manager.registerSensor(mAccelerometer);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ...
        UserDriverManager manager = UserDriverManager.getManager();
        // Unregister the driver when finished
        manager.unregisterSensor(mAccelerometer);
    }
}
public class SensorDriverService extends Service implements SensorEventListener {
    private SensorManager mSensorManager;

    @Override
    public void onCreate() {
        super.onCreate();
        ...
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerDynamicSensorCallback(new SensorCallback());
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        ...
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        ...
    }

    // Listen for registration events from the sensor driver
    private class SensorCallback extends SensorManager.DynamicSensorCallback {
        @Override
        public void onDynamicSensorConnected(Sensor sensor) {
            Log.i(TAG, sensor.getName() + " has been connected");

            // Begin listening for sensor readings
            mSensorManager.registerListener(SensorDriverService.this, sensor,
                    SensorManager.SENSOR_DELAY_NORMAL);
        }

        @Override
        public void onDynamicSensorDisconnected(Sensor sensor) {
            Log.i(TAG, sensor.getName() + " has been disconnected");

            // Stop receiving sensor readings
            mSensorManager.unregisterListener(SensorDriverService.this);
        }
    }
}

三、案例展示


下面我们就以如何实现HCSR40超声波传感器为例,为大家演示如何实现自己的传感器驱动。

1. 硬件要求

2. 搭建电路

电路图

3. 代码编写
SensorDemo\app\src\main\java\com\chengxiang\sensordemo\Hcsr04.java

public class Hcsr04 implements AutoCloseable {
    private static final String TAG = Hcsr04.class.getSimpleName();
    private Gpio trigGpio, echoGpio;
    private Handler handler = new Handler();
    private static final int pauseInMicro = 10;

    private long startTime, ellapsedTime;
    private float distanceInCm;

    public Hcsr04(String trigPin, String echoPin) throws IOException {
        try {
            PeripheralManagerService service = new PeripheralManagerService();
            trigGpio = service.openGpio(trigPin);
            echoGpio = service.openGpio(echoPin);
            configureGpio(trigGpio, echoGpio);
        } catch (IOException e) {
            throw e;
        }
    }

    @Override
    public void close() throws Exception {
        handler.removeCallbacks(startTrigger);
        try {
            trigGpio.close();
            echoGpio.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void configureGpio(Gpio trigGpio, Gpio echoGpio) throws IOException {
        try {
            trigGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
            echoGpio.setDirection(Gpio.DIRECTION_IN);

            trigGpio.setActiveType(Gpio.ACTIVE_HIGH);
            echoGpio.setActiveType(Gpio.ACTIVE_HIGH);
            echoGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
            handler.post(startTrigger);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Runnable startTrigger = new Runnable() {
        @Override
        public void run() {
            try {
                trigGpio.setValue(!trigGpio.getValue());
                busyWaitMicros(pauseInMicro);
                trigGpio.setValue(!trigGpio.getValue());
                while (!echoGpio.getValue())
                    startTime = System.nanoTime();
                while (echoGpio.getValue())
                    ellapsedTime = System.nanoTime() - startTime;
                ellapsedTime = TimeUnit.NANOSECONDS.toMicros(ellapsedTime);
                distanceInCm = ellapsedTime / 58;
                Log.i(TAG,"distanceInCm = " + distanceInCm);
                handler.postDelayed(startTrigger, 1000);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    public float[] getProximityDistance() {
        return new float[]{distanceInCm};
    }

    public static void busyWaitMicros(long micros) {
        long waitUntil = System.nanoTime() + (micros * 1_000);
        while (waitUntil > System.nanoTime()) {
            ;
        }
    }
}

SensorDemo\app\src\main\java\com\chengxiang\sensordemo\Hcsr04UltrasonicDriver.java

public class Hcsr04UltrasonicDriver implements AutoCloseable {

    private static final String TAG = Hcsr04UltrasonicDriver.class.getSimpleName();
    private static final int DRIVER_VERSION = 1;
    private static final String DRIVER_NAME = "HC-SR04 Ultrasonic Sensor";

    private UserSensor userSensor;
    private Hcsr04 device;

    public Hcsr04UltrasonicDriver(String trigPin, String echoPin) throws IOException {
        device = new Hcsr04(trigPin, echoPin);
    }

    @Override
    public void close() throws Exception {
        unregister();
        if (device != null) {
            try {
                device.close();
            } finally {
                device = null;
            }
        }
    }

    public void register() {
        if (device == null) {
            throw new IllegalStateException("cannot registered closed driver");
        }
        if (userSensor == null) {
            userSensor = build(device);
            UserDriverManager.getManager().registerSensor(userSensor);
        }
    }

    public void unregister() {
        if (userSensor != null) {
            UserDriverManager.getManager().unregisterSensor(userSensor);
            userSensor = null;
        }
    }

    private static UserSensor build(final Hcsr04 hcsr04) {
        return UserSensor.builder()
                .setName(DRIVER_NAME)
                .setVersion(DRIVER_VERSION)
                .setType(Sensor.TYPE_PROXIMITY)
                .setDriver(new UserSensorDriver() {
                    @Override
                    public UserSensorReading read() throws IOException {
                        float[] distance = hcsr04.getProximityDistance();
                        return new UserSensorReading(distance);
                    }
                })
                .build();
    }
}

SensorDemo\app\src\main\java\com\chengxiang\sensordemo\MainActivity.java

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    private static final String TAG = "Sensor";

    private TextView textView;
    private Hcsr04UltrasonicDriver hcsr04UltrasonicDriver;
    private SensorManager mSensorManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textview1);
        try {
            hcsr04UltrasonicDriver = new Hcsr04UltrasonicDriver("BCM20", "BCM21");

            mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            mSensorManager.registerDynamicSensorCallback(new Hcsr04SensorCallback());

            hcsr04UltrasonicDriver.register();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        textView.setText("distanceInCm = " + sensorEvent.values[0] + "cm");
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    private class Hcsr04SensorCallback extends SensorManager.DynamicSensorCallback {
        @Override
        public void onDynamicSensorConnected(Sensor sensor) {
            Log.i(TAG, sensor.getName() + " has been connected");
            mSensorManager.registerListener(MainActivity.this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
        }

        @Override
        public void onDynamicSensorDisconnected(Sensor sensor) {
            Log.i(TAG, sensor.getName() + " has been disconnected");
            mSensorManager.unregisterListener(MainActivity.this);
        }
    }
}

4. 运行结果
按照上面的电路图,搭建电路如下:

搭建电路

程序运行后,通过传感器检测到障碍物距离,显示在屏幕上:

显示温度

1.抛弃各种找元器件的烦恼,来“1024工场”旗舰店,一次性买到你所想要的:树莓派套装—专为Android Things打造。

树莓派套装
电脑用户,点击如下链接进入淘宝宝贝页面:
https://item.taobao.com/item.htm?spm=686.1000925.0.0.3f11c9ed68fPu7&id=549263158263
手机用户,打开淘宝客户端扫描二维码:
宝贝二维码
2.完整和持续更新的《使用Android打开物联网开发大门——Andoid Thigns开发》文档,欢迎大家阅读!
https://www.kancloud.cn/workshop1024/android_things_develop/360773
这里写图片描述
3.新技术,新未来!欢迎大家关注“1024工场”微信服务号,时刻关注我们的最新的技术讯息。(甭客气!尽情的扫描或者长按!)
服务号
4.加入“Android Things开发”QQ讨论群,一起学习一起Hi。(甭客气!尽情的扫描或者长按!)
qq群
上一篇 下一篇

猜你喜欢

热点阅读