Android Things 教程:发现和链接 I²C 设备

在之前的文章中,我们创建了自己的 I²C 设备。这实际上是我们在尝试 I²C 的一个很酷的功能之前的必要的第一步,它支持在同一总线上连接多个从设备。现在我们有了一些 I²C 设备,让我们开始吧。

我们的 I²C 设备

我们将使用 3 种不同的设备:

  • SSD1306 OLED 显示器(驱动程序)
  • LCD 1602 与 PCF8574 I²C 适配器(驱动程序)
  • Arduino I²C 风扇(实现)

Android Things 主设备将以较低的速度启动风扇,将速度设置为中等,然后高,最后停止风扇。每当速度改变时,LCD 和 OLED 屏幕将显示新的状态,通过显示位图(对于 SSD1306)或一些文本(对于LCD1602)。

连接设备

您可以并行连接总线上的多个 I²C 设备。

以下是官方 I2C 文档的说明:

确定没有数据表的 I²C 地址

对于 I²C,即使总线只包含一个从器件,每个从器件也必须有一个地址。

因此,当您使用 Things Support Library 打开 I2C 设备时,必须指定 I²C 总线和设备地址:

val pioService = PeripheralManagerService()
val device = pioService.openI2cDevice(I2C_BUS_NAME, I2C_ADDRESS)

正如你猜测的那样,当多个设备连接到同一总线时,地址是有用的。每个器件都有自己的 I²C 地址,通常在器件数据表中提到。

如果您不知道设备的地址,则可以:

fun PeripheralManagerService.scanI2cAvailableAddresses(i2cName: String): List<int> {
    return (0..127).filter { address -&gt;
        openI2cDevice(i2cName, address).use { device -&gt;
            try {
                device.write(ByteArray(1), 1)
                true
            } catch (e: IOException) {
                false
            }
        }
    }
}

这个函数将循环每个地址,并尝试写入一个 “0” 字节。如果成功,则表示设备已连接。该功能将返回检测到的设备地址列表。

以下是如何调用它,并将设备地址写入日志中的代码:

Log.i(TAG, "Scanning I2C devices")
pioService.scanI2cAvailableAddresses(I2C_BUS_NAME)
    .map { String.format(Locale.US, "0x%02X", it) }
    .forEach { address -&gt; Log.i(TAG, "Found: $address") }
}

在您的 Android 日志中,您将获得以下信息:

Scanning I2C devices
Found: 0x3C
Found: 0x3F
Found: 0x42

发现 3 个地址:0x3C(OLED屏幕),0x3F(LCD屏幕)和 0x42(Arduino风扇)。

显示当前的风速

现在我们已经拥有了我们所需要的一切,来使用我们的 I²C 外设。

首先,我们为风扇速度定义一个枚举:

enum class Speed {
  LOW, MEDIUM, HIGH
}

然后,我们可以开始初始化我们的 I²C 外设:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    lcd = LcdPcf8574(I2C_PIN_NAME, I2C_ADDRESS_LCD).apply {
        begin(16, 2)
        setBacklight(true)
    }
    oled = Ssd1306(I2C_PIN_NAME, I2C_ADDRESS_OLED)
    fan = ArduinoFanI2C(I2C_PIN_NAME, I2C_ADDRESS_ARDUINO)
}

现在,我们可以写一些函数,来展示每个显示的速度:

fun LcdPcf8574.showSpeed(speed: Speed) {
    clear()
    print("Speed is ${speed.name}")
}

fun Ssd1306.showSpeed(speed: Speed, resources: Resources) {
    val resId = when (speed) {
        LOW -&gt; R.drawable.ssd1306_low
        MEDIUM -&gt; R.drawable.ssd1306_medium
        HIGH -&gt; R.drawable.ssd1306_high
    }

    clearPixels()
    val bmp = BitmapFactory.decodeResource(resources, resId)
    BitmapHelper.setBmpData(this, 0, 0, bmp, false)
    show()
}

以下是我们的资源文件:

资源文件

最后,我们可以添加下面的代码来启动风扇,遍历每个速度并停止风扇:

fan.start()

Speed.values().forEach { speed -&gt;
    fan.speed = speed
    lcd.showSpeed(speed)
    oled.showSpeed(speed, resources)
    wait1sec()
}

fan.stop()
lcd.clear()
oled.clearPixels()

视频

https://www.youtube.com/watch?v=Zh8MQJvvsh4

结论

与多个 I²C 从机通信非常简单。除了在总线上并行连接之外,你其实没有什么特别的事情要做。

你可以在 GitHub 上找到完整的源代码:

https://github.com/Nilhcem/i2cfun-androidthings/

原文链接:http://nilhcem.com/android-things/chaining-i2c-devices

尚未评分
您的评分将帮助我们做出更好的玩法

观光\评论区

Copyright © 2017 玩点什么. All Rights Reserved.