AndroidThings——连接 SHT20 传感器读取温湿度

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011133887/article/details/85242679

一些介绍AndroidThings(之后将简称ATs)的一些文章:
Android Things是什么
Android Things系统刷写
Android Things树莓派开发板没有显示器时如何连接
Android Things的日期和时间设置
这几篇文章都是同一个作者书写,都是非常有帮助的入门文章,下面我就不多废话了,进入咱们的主题:ATs(树莓派) 连接 SHT20 传感器读取温湿度。

连线

SHT20 传感器是通过 I2C 总线连接到树莓派上的,关于总线的概念我们就不叙述,对于我们软件工程师而言知道怎么用就行了。
树莓派引脚图

从上图我们可以看出,树莓派3B 的3号脚与5号脚为 I2C 总线的引脚,我们只需要将 SHT20 的 SDA 引脚与SCL引脚对应的接上即可。要注意 SHT20 的供电电压为 3.3V,其 VCC 引脚千万不要接到树莓派 GPIO 的5V 供电引脚,否则会烧坏传感器。

编码

完成电路连接之后我们开始书写代码,代码部分很简单,我会在其中注释,以方便大家理解。

/**
 * @Author Junerver
 * @Date 2018/12/24-16:48
 * @Email [email protected]
 * @Version v1.0
 * @Description
 */
object Sht2xUtil:AutoCloseable {

    private val I2C_DEVICE_NAME = "I2C1" // I2C总线名称
    private val I2C_ADDRESS = 0x40  // I2C 设备地址
    private val SHT20_CMD_R_T = 0xF3    // 从机模式测温指令
    private val SHT20_CMD_R_RH = 0xF5   // 从机模式测湿度指令
    private val SHT20_CMD_RESET = 0xFE  // 软重置指令
    private lateinit var device: I2cDevice  // I2C 设备


    override fun close() {
        //设备使用完毕后关闭总线设备
        if (this::device.isInitialized) {
            device.close()
        }
    }

    fun open() {
        //通过总线名称与设备地址打开设备
        if (!this::device.isInitialized) {
            device = PeripheralManager.getInstance().openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS)
        }
    }

    fun reset() {
        //软重置指令
        if (this::device.isInitialized) {
            val ba = byteArrayOf(SHT20_CMD_RESET.toByte())
            device.write(ba, ba.size)
            SystemClock.sleep(150)
        }else {
            throw RuntimeException()
        }
    }

    fun getTemp():String {
        if (this::device.isInitialized) {
            //像设备写入指令,设置模式为温度
            val ba = byteArrayOf(SHT20_CMD_R_T.toByte())
            device.write(ba, ba.size)
            //写入指令后延时
            SystemClock.sleep(150)
            // 初始化一个byte数组 用于从寄存器中读取数据
            val data = ByteArray(2) { 0 }
		  // 网上还有一种读取数据的方式  device.readRegBuffer(0x00, data, data.size)  但是不适用与sht20这个传感器
            device.read(data, data.size)
            //将读取到的字节数组首先转成16进制然后转成10进制数
            val bb = ByteUtils.hexStr2decimal(ByteUtils.bytes2HexStr(data))
            //sht20读取温度原始数据转化成摄氏度的算法
            var result = -46.85 + 175.72 * (bb / pow(2.0, 16.0))
            return result.toString().substring(0..3)
        }else {
            throw RuntimeException()
        }
    }

    fun getHumi(): String {
        if (this::device.isInitialized) {
            //设置模式为湿度
            val ba = byteArrayOf(SHT20_CMD_R_RH.toByte())
            device.write(ba, ba.size)
            SystemClock.sleep(150)
            val data = ByteArray(2) { 0 }
            device.read(data, data.size)
            val bb = ByteUtils.hexStr2decimal(ByteUtils.bytes2HexStr(data))
            //sht20读取湿度原始数据转化成相对湿度
            var result = -6 + 125 * (bb / pow(2.0, 16.0))
            //仅截取前两位
            return result.toString().substring(0..1)
        } else {
            throw RuntimeException()
        }
    }

    fun getTempAndHumi(): Pair<String, String> {
        if (this::device.isInitialized) {
            var result: Pair<String, String>
            val temp = getTemp()
            SystemClock.sleep(150)
            val humi = getHumi()
            result = Pair(temp, humi)
            return result
        }else {
            throw RuntimeException()
        }
    }
}

注意:在写入测量模式指令之后必须要延时适当时间再从设备中读取,否则将会在读取指令位置出现如下异常:

Error on I2C API
    com.google.android.things.pio.PioException: android.os.ServiceSpecificException: I/O error (code 5)
        at com.google.android.things.pio.I2cDeviceImpl.read(I2cDeviceImpl.java:75)
        at com.example.androidthings.simpleui.Sht2xUtil.getTemp(Sht2xUtil.kt:60)
        at com.example.androidthings.simpleui.Sht2xUtil.getTempAndHumi(Sht2xUtil.kt:88)
        at com.example.androidthings.simpleui.SimpleUiActivity$readRunnable$1.run(SimpleUiActivity.kt:125)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: android.os.ServiceSpecificException: I/O error (code 5)
        at android.os.Parcel.readException(Parcel.java:2027)
        at android.os.Parcel.readException(Parcel.java:1959)
        at com.google.android.things.pio.IPeripheralManagerClient$Stub$Proxy.I2cRead(IPeripheralManagerClient.java:1282)
        at com.google.android.things.pio.I2cDeviceImpl.read(I2cDeviceImpl.java:73)
        at com.example.androidthings.simpleui.Sht2xUtil.getTemp(Sht2xUtil.kt:60) 
        at com.example.androidthings.simpleui.Sht2xUtil.getTempAndHumi(Sht2xUtil.kt:88) 
        at com.example.androidthings.simpleui.SimpleUiActivity$readRunnable$1.run(SimpleUiActivity.kt:125) 
        at android.os.Handler.handleCallback(Handler.java:790) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

使用的时候也很简单,在适当的实际调用 open() 函数,在需要读取数据的位置调用 getXX()函数即可。

猜你喜欢

转载自blog.csdn.net/u011133887/article/details/85242679