Android 平板 APP 蓝牙控制美容仪器设备

更新日期: 2024-06-26 阅读次数: 585 字数: 587 分类: Android

在 Android 平板 APP 上增加了控制空调功能之后,又要蓝牙控制美容仪器,这真是变成了一个万能遥控器。

本以为一两个小时就能搞定,没想到 android 上 kotlin 处理多个 bit 位组合异常麻烦,最终整整耗费了一个下午才搞定。今天的计划彻底被打乱了。

TODO

  • [x] 新 fragment 页面。增加一个调试页面
  • [x] 扩充蓝牙 MTU 字节数,及读取的字节数。这里犯了一个错误,忽略了 0 号寄存器位,导致拉取的时候,少读取了一个字节,怪不得最后一个字节总是跟预期不符,数值乱跳,原来是读到了校验位。
  • [x] 控制字段的解析。界面数值显示
  • [x] 美容功能的控制按钮。点击事件处理
  • [x] 蓝牙控制指令发送

为了减少传输的蓝牙数据包,协议中使用了大量的bit位组合,例如 3,4,7 个 bit 代表一个设置值,而非用一个字节表示。用 kotlin 解析起来就得注意,多做单元测试。

这里记录一下:

控制协议的解析

两个字节中,每四个 bit 位解析为一个数值。

以下为 Android Koltin 测试代码:

fun extractBits(byte: Byte): Pair<Int, Int> {
    // 取出前四个 bit. shr 是右移位
    val firstFourBits = (byte.toInt() and 0b11110000) shr 4
    
    // 取出后四个 bit
    val lastFourBits = byte.toInt() and 0b00001111
    
    return Pair(firstFourBits, lastFourBits)
}

fun main() {
	val byte: Byte = 0b10101111.toByte()
	val (firstFour, lastFour) = extractBits(byte)
	println("First four bits: $firstFour")  // 10
	println("Last four bits: $lastFour")    // 15
}

注意,val byte: Byte = 0b10101111.toByte() 在定义 byte 时,需要将数值通过 toByte 转换位 byte 类型,否则会报错

The integer literal does not conform to the expected type Byte

控制协议的拼装

将一个字节中高四位,或者低四位修改为某个整数。

以下为 Android Koltin 测试代码:

fun setHighFourBits(byte: Byte, value: Int): Int {
    return (byte.toInt() and 0b00001111) or (value shl 4)
}

fun setLowFourBits(byte: Byte, value: Int): Int {
    return (byte.toInt() and 0b11110000) or value
}


fun main() { 
    val originalByte: Byte = 0b10101010.toByte()

	// 修改高四位为 0b1110
	val newByte1 = setHighFourBits(originalByte, 0b1110)
    println("0b${newByte1.toString(2)}")  // 0b11101010

	// 修改低四位为 0b1011
	val newByte2 = setLowFourBits(originalByte, 0b1011)
    println("0b${newByte2.toString(2)}")  // 0b10101011
}

微信关注我哦 👍

大象工具微信公众号

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式