小程序蓝牙通信例子
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.6 KiB

  1. const app = getApp()
  2. function inArray(arr, key, val) {
  3. for (let i = 0; i < arr.length; i++) {
  4. if (arr[i][key] === val) {
  5. return i;
  6. }
  7. }
  8. return -1;
  9. }
  10. // ArrayBuffer转16进度字符串示例
  11. function ab2hex(buffer) {
  12. var hexArr = Array.prototype.map.call(
  13. new Uint8Array(buffer),
  14. function (bit) {
  15. return ('00' + bit.toString(16)).slice(-2)
  16. }
  17. )
  18. return hexArr.join('');
  19. }
  20. Page({
  21. data: {
  22. devices: [],
  23. connected: false,
  24. chs: [],
  25. },
  26. openBluetoothAdapter() {
  27. wx.openBluetoothAdapter({
  28. success: (res) => {
  29. console.log('openBluetoothAdapter success', res)
  30. this.startBluetoothDevicesDiscovery()
  31. },
  32. fail: (res) => {
  33. if (res.errCode === 10001) {
  34. wx.onBluetoothAdapterStateChange(function (res) {
  35. console.log('onBluetoothAdapterStateChange', res)
  36. if (res.available) {
  37. this.startBluetoothDevicesDiscovery()
  38. }
  39. })
  40. }
  41. }
  42. })
  43. },
  44. getBluetoothAdapterState() {
  45. wx.getBluetoothAdapterState({
  46. success: (res) => {
  47. console.log('getBluetoothAdapterState', res)
  48. if (res.discovering) {
  49. this.onBluetoothDeviceFound()
  50. } else if (res.available) {
  51. this.startBluetoothDevicesDiscovery()
  52. }
  53. }
  54. })
  55. },
  56. startBluetoothDevicesDiscovery() {
  57. if (this._discoveryStarted) {
  58. return
  59. }
  60. this._discoveryStarted = true
  61. wx.startBluetoothDevicesDiscovery({
  62. allowDuplicatesKey: true,
  63. success: (res) => {
  64. console.log('startBluetoothDevicesDiscovery success', res)
  65. this.onBluetoothDeviceFound()
  66. },
  67. })
  68. },
  69. stopBluetoothDevicesDiscovery() {
  70. wx.stopBluetoothDevicesDiscovery()
  71. },
  72. onBluetoothDeviceFound() {
  73. wx.onBluetoothDeviceFound((res) => {
  74. res.devices.forEach(device => {
  75. if (!device.name && !device.localName) {
  76. return
  77. }
  78. const foundDevices = this.data.devices
  79. const idx = inArray(foundDevices, 'deviceId', device.deviceId)
  80. const data = {}
  81. if (idx === -1) {
  82. data[`devices[${foundDevices.length}]`] = device
  83. } else {
  84. data[`devices[${idx}]`] = device
  85. }
  86. this.setData(data)
  87. })
  88. })
  89. },
  90. createBLEConnection(e) {
  91. const ds = e.currentTarget.dataset
  92. const deviceId = ds.deviceId
  93. const name = ds.name
  94. wx.createBLEConnection({
  95. deviceId,
  96. success: (res) => {
  97. this.setData({
  98. connected: true,
  99. name,
  100. deviceId,
  101. })
  102. this.getBLEDeviceServices(deviceId)
  103. }
  104. })
  105. this.stopBluetoothDevicesDiscovery()
  106. },
  107. closeBLEConnection() {
  108. wx.closeBLEConnection({
  109. deviceId: this.data.deviceId
  110. })
  111. this.setData({
  112. connected: false,
  113. chs: [],
  114. canWrite: false,
  115. })
  116. },
  117. getBLEDeviceServices(deviceId) {
  118. wx.getBLEDeviceServices({
  119. deviceId,
  120. success: (res) => {
  121. for (let i = 0; i < res.services.length; i++) {
  122. if (res.services[i].isPrimary) {
  123. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
  124. return
  125. }
  126. }
  127. }
  128. })
  129. },
  130. getBLEDeviceCharacteristics(deviceId, serviceId) {
  131. wx.getBLEDeviceCharacteristics({
  132. deviceId,
  133. serviceId,
  134. success: (res) => {
  135. console.log('getBLEDeviceCharacteristics success', res.characteristics)
  136. for (let i = 0; i < res.characteristics.length; i++) {
  137. let item = res.characteristics[i]
  138. if (item.properties.read) {
  139. wx.readBLECharacteristicValue({
  140. deviceId,
  141. serviceId,
  142. characteristicId: item.uuid,
  143. })
  144. }
  145. if (item.properties.write) {
  146. this.setData({
  147. canWrite: true
  148. })
  149. this._deviceId = deviceId
  150. this._serviceId = serviceId
  151. this._characteristicId = item.uuid
  152. this.writeBLECharacteristicValue()
  153. }
  154. if (item.properties.notify || item.properties.indicate) {
  155. wx.notifyBLECharacteristicValueChange({
  156. deviceId,
  157. serviceId,
  158. characteristicId: item.uuid,
  159. state: true,
  160. })
  161. }
  162. }
  163. },
  164. fail(res) {
  165. console.error('getBLEDeviceCharacteristics', res)
  166. }
  167. })
  168. // 操作之前先监听,保证第一时间获取数据
  169. wx.onBLECharacteristicValueChange((characteristic) => {
  170. const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
  171. const data = {}
  172. if (idx === -1) {
  173. data[`chs[${this.data.chs.length}]`] = {
  174. uuid: characteristic.characteristicId,
  175. value: ab2hex(characteristic.value)
  176. }
  177. } else {
  178. data[`chs[${idx}]`] = {
  179. uuid: characteristic.characteristicId,
  180. value: ab2hex(characteristic.value)
  181. }
  182. }
  183. // data[`chs[${this.data.chs.length}]`] = {
  184. // uuid: characteristic.characteristicId,
  185. // value: ab2hex(characteristic.value)
  186. // }
  187. this.setData(data)
  188. })
  189. },
  190. writeBLECharacteristicValue() {
  191. // 向蓝牙设备发送一个0x00的16进制数据
  192. let buffer = new ArrayBuffer(1)
  193. let dataView = new DataView(buffer)
  194. dataView.setUint8(0, Math.random() * 255 | 0)
  195. wx.writeBLECharacteristicValue({
  196. deviceId: this._deviceId,
  197. serviceId: this._deviceId,
  198. characteristicId: this._characteristicId,
  199. value: buffer,
  200. })
  201. },
  202. closeBluetoothAdapter() {
  203. wx.closeBluetoothAdapter()
  204. this._discoveryStarted = false
  205. },
  206. })