在 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 聊聊, 查看更多联系方式