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

实验设备

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

DHT12 实物图

DHT12.jpg

端口连接

pinout-raspberrypi.png

获得 I2C 总线名称

PeripheralManagerService manager = new PeripheralManagerService();
List<String> 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)
    }
}

实验结果

result.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在使用单片机的过程中,I2C 通信可以说是最被广泛使用和采纳的协议之一,采用 I2C 协议可以占用更少的资源,链接...
    noparkinghere阅读 6,798评论 0 8
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,416评论 9 118
  • 写在前面的话:由于外设I/O涉及到GPIO、PWM、和串行通信三部分,而串行通信有讲了I2C(IIC)、SPI、U...
    化作春泥_阅读 7,514评论 0 6
  • IIC通信实验 IIC简介 I²C(Inter-Integrated Circuit)字面上的意思是集成电路之间,...
    btskyrmb阅读 6,046评论 0 2
  • 今天是八月十五,特别冷。 从姥姥家出来之后我和蕾姐也告别了,她需要回去照顾家人,我想去换一个新一点...
    0娜娜子0阅读 3,355评论 0 0