[Android Things] 通过 I2C 读取温湿度

实验设备

Raspberry Pi 3 with Android Things
DHT12 温湿度传感器

DHT12 实物图

[Android Things] 通过 I2C 读取温湿度_第1张图片
DHT12.jpg

端口连接

[Android Things] 通过 I2C 读取温湿度_第2张图片
pinout-raspberrypi.png

获得 I2C 总线名称

PeripheralManagerService manager = new PeripheralManagerService();
List deviceList = manager.getI2cBusList();
if (deviceList.isEmpty()) {
    Log.i(TAG, "No I2C bus available on this device.");
} else {
    Log.i(TAG, "List of available devices: " + deviceList);
}

得到如下输出

List of available devices: I2C1

通信协议

本实验中, DHT12 的 I2C 地址为 0x5C ,读取到的数据格式如下:

BYTE ADDR Desc.
0x00 湿度整数位
0x01 湿度小数位
0x02 温度整数位
0x03 温度小数位
0x04 校验和
  • 若前四位之和等于最后一位的校验和,则读取到的数据无误;
  • 温度小数位(即 0x03 )的最高位代表温度的正负。若其为 0 ,温度为正值;若其为 1 ,温度为负值。

实验代码(Kotlin)

package cn.anguiao.things

import android.app.Activity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import com.google.android.things.pio.I2cDevice
import com.google.android.things.pio.PeripheralManagerService
import java.io.IOException

class MainActivity : Activity() {

    companion object {
        private val TAG = "MainActivity"
        private val I2C_DEVICE_NAME = "I2C1"
        private val I2C_ADDRESS = 0x5C
    }

    private val handler = Handler()

    private lateinit var device: I2cDevice

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            // 获得串口服务
            val service = PeripheralManagerService()
            // 打开相应的I2C设备
            device = service.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS)

            // 采集数据
            handler.post(readRunnable)
        } catch (e: IOException) {
            Log.e(TAG, "Error on I2C API", e)
        }
    }

    override fun onDestroy() {
        super.onDestroy()

        handler.removeCallbacks(readRunnable)

        try {
            device.close()
        } catch (e: IOException) {
            Log.e(TAG, "Error on I2C API", e)
        }
    }

    private val readRunnable = object : Runnable {
        override fun run() {
            try {
                // 采集数据并输出到 logcat
                val data = readHumidityAndTemperature()
                Log.d(TAG, data.joinToString())
            } catch (e: IOException) {
                Log.e(TAG, "Error on I2C API", e)
            }

            // 延时一秒,再次采集
            handler.postDelayed(this, 1000)
        }
    }

    private fun readHumidityAndTemperature(): DoubleArray {
        // 初始化 byte 数组
        val data = ByteArray(5, { 0 })
        // 读取数据
        device.readRegBuffer(0x00, data, data.size)

        // 校验数据
        if ((data[0] + data[1] + data[2] + data[3]) % 256 != data[4].toInt()) {
            return doubleArrayOf(0.0, 0.0)
        }

        // 处理湿度数据
        val humidity = (data[0].toString() + "." + data[1].toString()).toDouble()

        // 处理温度数据
        val temperature = if (data[3] < 128) {
            (data[2].toString() + "." + data[3].toString()).toDouble()
        } else {
            -(data[2].toString() + "." + (data[3] - 128).toString()).toDouble()
        }

        // 返回数据
        return doubleArrayOf(humidity, temperature)
    }
}

实验结果

[Android Things] 通过 I2C 读取温湿度_第3张图片
result.png

你可能感兴趣的:([Android Things] 通过 I2C 读取温湿度)