Continuous updates with sensor driver

Similar to what happened with the button input driver, when we use classes that integrate deeply with the operating system, we need special permissions. Any time we want to create new sensor drivers we need to add the MANAGE_SENSOR_DRIVERS permission to the manifest:

<uses-permission android:name="com.google.android.things.permission.MANAGE_SENSOR_DRIVERS" />

Using a sensor driver is more complicated than reading directly from the peripheral. Let's split the code into two parts: the initialization of the sensor driver, and the callbacks and listeners. Initialization looks similar to what we did for button input drivers:

class TemperatureSensorDriverActivity : Activity() {

lateinit var sensorManager : SensorManager
lateinit var sensorDriver : Bmx280SensorDriver

override fun onCreate(savedInstanceState: Bundle?) {
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensorManager.registerDynamicSensorCallback(sensorCallback)

super.onCreate(savedInstanceState)
sensorDriver = RainbowHat.createSensorDriver()
sensorDriver.registerTemperatureSensor();
}

[....]
}

Initialization of the sensor driver comes in two steps. First we register a dynamic sensor callback with the SensorManagerThis listener will be invoked when a new sensor is connected. When this happens, we register the temperature sensor into the system. This step will add the sensor to the list of sensors available.

Let's take a look into the callbacks now:

    val sensorCallback = object : SensorManager.DynamicSensorCallback() {
override fun onDynamicSensorConnected(sensor: Sensor?) {
if (sensor?.type == Sensor.TYPE_AMBIENT_TEMPERATURE) {
sensorManager.registerListener(
temperatureSensorListener,
sensor,
SensorManager.SENSOR_DELAY_NORMAL)
}
}
}

val temperatureSensorListener = object : SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
Log.i(TAG, "Temperature changed: " + event.values[0])
}

override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
Log.i(TAG, "accuracy changed: $accuracy")
}
}

The dynamic sensor callback receives onDynamicSensorConnected when the new sensor is connected. Then, inside the method, we check if the sensor is of type TYPE_AMBIENT_TEMPERATURE and, if so, we register a SensorEventListener to get updates from this sensor.

The registration includes the listener, the sensor, and the sampling rate.

The last part is the SensorEventListener itself. We only care about the calls to onSensorChanged, which will return us a list of values with the sensor readings. In our case, this list has just one value.

SensorEvent contains an array of values. This makes sense because SensorEventListener is used by all sensors, including complex ones such as accelerometers, magnetometers, and so on.

Finally, let's look at the cleanup:

    override fun onDestroy() {
super.onDestroy()
sensorManager.unregisterListener(temperatureSensorListener)
sensorDriver.unregisterTemperatureSensor()
sensorDriver.close()
}

In a similar way as the one to initialize the sensor, the cleanup inside onDestroy consists of the unregistration of the sensor listener and the unregistration of the sensor with the system. The dynamic sensor callback is irrelevant at this time, so we can choose not to unregister, but you can do that as well to have everything tidied up.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.102.112