0. 前言
  这两天刚好了解了一下微信小程序的蓝牙功能。主要用于配网功能。发现微信的小程序蓝牙API已经封装的很好了。编程起来很方便。什么蓝牙知识都不懂的情况下,不到两天就晚上数据的收发了,剩下的就是数据帧格式的定义,当然这部分就不是本次博客的重点。
1. 准备硬件
  这里我准备了CH341SER这个作为USB转串口。用sscom5.13.1 串口工具。由于我不太懂硬件开发。硬件部分都是由公司其他人开发的。我只是负责把环境搭建起来。然后负责我的微信小程序开发。

2. 开发小程序简单讲解
  onLoad 这个一方面是用来获取当前连接的WiFi名称,减少用户输入,另一方面也是用来判断当前是否开启GPS功能。对于Android用户,是需要打开GPS蓝牙功能才能搜索到周围的蓝牙设备。

  1. onLoad: function(options) {
  2. var that = this;
  3. wx.startWifi({
  4. success(res) {
  5. console.log(res.errMsg)
  6. wx.getConnectedWifi({
  7. success: function(res) {
  8. console.log(res);
  9. that.setData({
  10. ssid: res.wifi.SSID
  11. })
  12. },
  13. fail: function(res) {
  14. if(res.errCode == 12006){
  15. wx.showModal({
  16. title: '请打开GPS定位',
  17. content: 'Android手机不打开GPS定位,无法搜索到蓝牙设备.',
  18. showCancel: false
  19. })
  20. }
  21. console.log(res);
  22. }
  23. })
  24. }
  25. })
  26. },

  搜索蓝牙设备相关代码

  1. searchBleEvent: function(ret){
  2. var ssid = this.data.ssid;
  3. var pass = this.data.pass;
  4. console.log(ssid, pass);
  5. if (util.isEmpty(ssid) || util.isEmpty(pass)) {
  6. util.toastError('请输入WiFi名称及密码');
  7. return;
  8. }
  9. this.initBLE();
  10. },

  初始化蓝牙适配器

  1. initBLE: function() {
  2. this.printLog("启动蓝牙适配器, 蓝牙初始化")
  3. var that = this;
  4. wx.openBluetoothAdapter({
  5. success: function(res) {
  6. console.log(res);
  7. that.findBLE();
  8. },
  9. fail: function(res) {
  10. util.toastError('请先打开蓝牙');
  11. }
  12. })
  13. },

  定义搜索设备任务

  1. findBLE: function() {
  2. this.printLog("打开蓝牙成功.")
  3. var that = this
  4. wx.startBluetoothDevicesDiscovery({
  5. allowDuplicatesKey: false,
  6. interval: 0,
  7. success: function(res) {
  8. wx.showLoading({
  9. title: '正在搜索设备',
  10. })
  11. console.log(res);
  12. delayTimer = setInterval(function(){
  13. that.discoveryBLE() //3.0 //这里的discovery需要多次调用
  14. }, 1000);
  15. setTimeout(function () {
  16. if (isFound) {
  17. return;
  18. } else {
  19. wx.hideLoading();
  20. console.log("搜索设备超时");
  21. wx.stopBluetoothDevicesDiscovery({
  22. success: function (res) {
  23. console.log('连接蓝牙成功之后关闭蓝牙搜索');
  24. }
  25. })
  26. clearInterval(delayTimer)
  27. wx.showModal({
  28. title: '搜索设备超时',
  29. content: '请检查蓝牙设备是否正常工作,Android手机请打开GPS定位.',
  30. showCancel: false
  31. })
  32. util.toastError("搜索设备超时,请打开GPS定位,再搜索")
  33. return
  34. }
  35. }, 15000);
  36. },
  37. fail: function(res) {
  38. that.printLog("蓝牙设备服务发现失败: " + res.errMsg);
  39. }
  40. })
  41. },

  搜索设备回调

  1. discoveryBLE: function() {
  2. var that = this
  3. wx.getBluetoothDevices({
  4. success: function(res) {
  5. var list = res.devices;
  6. console.log(list);
  7. if(list.length <= 0){
  8. return ;
  9. }
  10. var devices = [];
  11. for (var i = 0; i < list.length; i++) {   
  12. //that.data.inputValue:表示的是需要连接的蓝牙设备ID,
  13. //简单点来说就是我想要连接这个蓝牙设备,
  14. //所以我去遍历我搜索到的蓝牙设备中是否有这个ID
  15. var name = list[i].name || list[i].localName;
  16. if(util.isEmpty(name)){
  17. continue;
  18. }
  19. if(name.indexOf('JL') >= 0 && list[i].RSSI != 0){
  20. console.log(list[i]);
  21. devices.push(list[i]);
  22. }
  23. }
  24. console.log('总共有' + devices.length + "个设备需要设置")
  25. if (devices.length <= 0) {
  26. return;
  27. }
  28. that.connectBLE(devices);
  29. },
  30. fail: function() {
  31. util.toastError('搜索蓝牙设备失败');
  32. }
  33. })
  34. },

  设置可以进行连接的设备

  1. connectBLE: function(devices){
  2. this.printLog('总共有' + devices.length + "个设备需要设置")
  3. var that = this;
  4. wx.hideLoading();
  5. isFound = true;
  6. clearInterval(delayTimer);
  7. wx.stopBluetoothDevicesDiscovery({
  8. success: function (res) {
  9. that.printLog('连接蓝牙成功之后关闭蓝牙搜索');
  10. }
  11. })
  12. //两个的时候需要选择
  13. var list = [];
  14. for (var i = 0; i < devices.length; i++) {
  15. var name = devices[i].name || devices[i].localName;
  16. list.push(name + "[" + devices[i].deviceId + "]")
  17. }
  18. this.setData({
  19. deviceArray: list
  20. })
  21. //默认选择
  22. this.setData({
  23. currDeviceID: list[0]
  24. })
  25. },

  选择设备,然后点击对应的配网按钮,创建BLE连接

  1. createBLE: function(deviceId){
  2. this.printLog("连接: [" + deviceId+"]");
  3. var that = this;
  4. this.closeBLE(deviceId, function(res){
  5. console.log("预先关闭,再打开");
  6. setTimeout(function(){
  7. wx.createBLEConnection({
  8. deviceId: deviceId,
  9. success: function (res) {
  10. that.printLog("设备连接成功");
  11. that.getBLEServiceId(deviceId);
  12. },
  13. fail: function (res) {
  14. that.printLog("设备连接失败" + res.errMsg);
  15. }
  16. })
  17. }, 2000)
  18. });
  19. },

  获取蓝牙设备提供的服务UUID(本项目由于只会提供一个服务,就默认选择,实际项目,会自定义这个UUID的前缀或者后缀规则,定义多个不同的服务)

  1. //获取服务UUID
  2. getBLEServiceId: function(deviceId){
  3. this.printLog("获取设备[" + deviceId + "]服务列表")
  4. var that = this;
  5. wx.getBLEDeviceServices({
  6. deviceId: deviceId,
  7. success: function(res) {
  8. console.log(res);
  9. var services = res.services;
  10. if (services.length <= 0){
  11. that.printLog("未找到主服务列表")
  12. return;
  13. }
  14. that.printLog('找到设备服务列表个数: ' + services.length);
  15. if (services.length == 1){
  16. var service = services[0];
  17. that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary);
  18. that.getBLECharactedId(deviceId, service.uuid);
  19. }else{ //多个主服务
  20. //TODO
  21. }
  22. },
  23. fail: function(res){
  24. that.printLog("获取设备服务列表失败" + res.errMsg);
  25. }
  26. })
  27. },

  获取服务下的特征值(由于这个例子,是包含两个特征值,一个用于读,一个用于写,实际项目,跟上面的服务一样,要定义好特征量UUID的规则)

  1. getBLECharactedId: function(deviceId, serviceId){
  2. this.printLog("获取设备特征值")
  3. var that = this;
  4. wx.getBLEDeviceCharacteristics({
  5. deviceId: deviceId,
  6. serviceId: serviceId,
  7. success: function(res) {
  8. console.log(res);
  9. //这里会获取到两个特征值,一个用来写,一个用来读
  10. var chars = res.characteristics;
  11. if(chars.length <= 0){
  12. that.printLog("未找到设备特征值")
  13. return ;
  14. }
  15. that.printLog("找到设备特征值个数:" + chars.length);
  16. if(chars.length == 2){
  17. for(var i=0; i<chars.length; i++){
  18. var char = chars[i];
  19. that.printLog("特征值[" + char.uuid + "]")
  20. var prop = char.properties;
  21. if(prop.notify == true){
  22. that.printLog("该特征值属性: Notify");
  23. that.recvBLECharacterNotice(deviceId, serviceId, char.uuid);
  24. }else if(prop.write == true){
  25. that.printLog("该特征值属性: Write");
  26. that.sendBLECharacterNotice(deviceId, serviceId, char.uuid);
  27. }else{
  28. that.printLog("该特征值属性: 其他");
  29. }
  30. }
  31. }else{
  32. //TODO
  33. }
  34. },
  35. fail: function(res){
  36. that.printLog("获取设备特征值失败")
  37. }
  38. })
  39. },

  recv 接收设备发送过来数据

  1. recvBLECharacterNotice: function(deviceId, serviceId, charId){
  2. //接收设置是否成功
  3. this.printLog("注册Notice 回调函数");
  4. var that = this;
  5. wx.notifyBLECharacteristicValueChange({
  6. deviceId: deviceId,
  7. serviceId: serviceId,
  8. characteristicId: charId,
  9. state: true, //启用Notify功能
  10. success: function(res) {
  11. wx.onBLECharacteristicValueChange(function(res){
  12. console.log(res);
  13. that.printLog("收到Notify数据: " + that.ab2hex(res.value));
  14. //关闭蓝牙
  15. wx.showModal({
  16. title: '配网成功',
  17. content: that.ab2hex(res.value),
  18. showCancel: false
  19. })
  20. });
  21. },
  22. fail: function(res){
  23. console.log(res);
  24. that.printLog("特征值Notice 接收数据失败: " + res.errMsg);
  25. }
  26. })
  27. },

  send 小程序发送数据到设备

  1. sendBLECharacterNotice: function (deviceId, serviceId, charId){
  2. //发送ssid/pass
  3. this.printLog("延时1秒后,发送SSID/PASS");
  4. var that = this;
  5. var cell = {
  6. "ssid": this.data.ssid,
  7. "pass": this.data.pass
  8. }
  9. var buffer = this.string2buffer(JSON.stringify(cell));
  10. setTimeout(function(){
  11. wx.writeBLECharacteristicValue({
  12. deviceId: deviceId,
  13. serviceId: serviceId,
  14. characteristicId: charId,
  15. value: buffer,
  16. success: function(res) {
  17. that.printLog("发送SSID/PASS 成功");
  18. },
  19. fail: function(res){
  20. console.log(res);
  21. that.printLog("发送失败." + res.errMsg);
  22. },
  23. complete: function(){
  24.  
  25. }
  26. })
  27.  
  28. }, 1000);
  29. },

  手机端可以同时连接多个蓝牙设备,但是同一个蓝牙设备不能被多次连接,所以需要在每次连接前关闭BLE连接

  1. closeBLE: function(deviceId, callback){
  2. var that = this;
  3. wx.closeBLEConnection({
  4. deviceId: deviceId,
  5. success: function(res) {
  6. that.printLog("断开设备[" + deviceId + "]成功.");
  7. console.log(res)
  8. },
  9. fail: function(res){
  10. that.printLog("断开设备成功.");
  11. },
  12. complete: callback
  13. })
  14. },

  说明:接收数据和发送数据时,注意BLE限制了发送数据包的大小,现在20byte。具体参考微信小程序官方文档: https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth-ble/wx.writeBLECharacteristicValue.html

3. 蓝牙相关的所有JS代码

  1. // pages/bluetoothconfig/bluetoothconfig.js
  2. const util = require('../../utils/util.js')
  3.  
  4. var delayTimer; //用来控制是否持续服务发现
  5. var isFound = false;
  6.  
  7. Page({
  8. /**
  9. * 页面的初始数据
  10. */
  11. data: {
  12. ssid: '',
  13. pass: '',
  14. logs: [],
  15. deviceArray: [],
  16. currDeviceID: '请选择...'
  17. },
  18. onLoad: function(options) {
  19. var that = this;
  20. wx.startWifi({
  21. success(res) {
  22. console.log(res.errMsg)
  23. wx.getConnectedWifi({
  24. success: function(res) {
  25. console.log(res);
  26. that.setData({
  27. ssid: res.wifi.SSID
  28. })
  29. },
  30. fail: function(res) {
  31. if(res.errCode == 12006){
  32. wx.showModal({
  33. title: '请打开GPS定位',
  34. content: 'Android手机不打开GPS定位,无法搜索到蓝牙设备.',
  35. showCancel: false
  36. })
  37. }
  38. console.log(res);
  39. }
  40. })
  41. }
  42. })
  43. },
  44. bindPickerChange: function(ret){
  45. var array = this.data.deviceArray;
  46. console.log(array[ret.detail.value]);
  47. this.setData({
  48. currDeviceID: array[ret.detail.value]
  49. })
  50. },
  51. searchBleEvent: function(ret){
  52. var ssid = this.data.ssid;
  53. var pass = this.data.pass;
  54. console.log(ssid, pass);
  55. if (util.isEmpty(ssid) || util.isEmpty(pass)) {
  56. util.toastError('请输入WiFi名称及密码');
  57. return;
  58. }
  59. this.initBLE();
  60. },
  61. bleConfigEvent: function (ret) {
  62. var deviceID = this.data.currDeviceID;
  63. console.log("选中:" + deviceID);
  64. if (util.isEmpty(deviceID) || deviceID == "请选择..."){
  65. util.toastError("请先搜索设备");
  66. return ;
  67. }
  68. var device = deviceID.split('[');
  69. if(device.length <= 1){
  70. util.toastError("请先搜索设备");
  71. return ;
  72. }
  73. var id = device[device.length - 1].replace("]", "");
  74. console.log(id);
  75. util.toastError("连接" + id);
  76. this.createBLE(id);
  77. },
  78.  
  79. initBLE: function() {
  80. this.printLog("启动蓝牙适配器, 蓝牙初始化")
  81. var that = this;
  82. wx.openBluetoothAdapter({
  83. success: function(res) {
  84. console.log(res);
  85. that.findBLE();
  86. },
  87. fail: function(res) {
  88. util.toastError('请先打开蓝牙');
  89. }
  90. })
  91. },
  92. findBLE: function() {
  93. this.printLog("打开蓝牙成功.")
  94. var that = this
  95. wx.startBluetoothDevicesDiscovery({
  96. allowDuplicatesKey: false,
  97. interval: 0,
  98. success: function(res) {
  99. wx.showLoading({
  100. title: '正在搜索设备',
  101. })
  102. console.log(res);
  103. delayTimer = setInterval(function(){
  104. that.discoveryBLE() //3.0 //这里的discovery需要多次调用
  105. }, 1000);
  106. setTimeout(function () {
  107. if (isFound) {
  108. return;
  109. } else {
  110. wx.hideLoading();
  111. console.log("搜索设备超时");
  112. wx.stopBluetoothDevicesDiscovery({
  113. success: function (res) {
  114. console.log('连接蓝牙成功之后关闭蓝牙搜索');
  115. }
  116. })
  117. clearInterval(delayTimer)
  118. wx.showModal({
  119. title: '搜索设备超时',
  120. content: '请检查蓝牙设备是否正常工作,Android手机请打开GPS定位.',
  121. showCancel: false
  122. })
  123. util.toastError("搜索设备超时,请打开GPS定位,再搜索")
  124. return
  125. }
  126. }, 15000);
  127. },
  128. fail: function(res) {
  129. that.printLog("蓝牙设备服务发现失败: " + res.errMsg);
  130. }
  131. })
  132. },
  133. discoveryBLE: function() {
  134. var that = this
  135. wx.getBluetoothDevices({
  136. success: function(res) {
  137. var list = res.devices;
  138. console.log(list);
  139. if(list.length <= 0){
  140. return ;
  141. }
  142. var devices = [];
  143. for (var i = 0; i < list.length; i++) {   
  144. //that.data.inputValue:表示的是需要连接的蓝牙设备ID,
  145. //简单点来说就是我想要连接这个蓝牙设备,
  146. //所以我去遍历我搜索到的蓝牙设备中是否有这个ID
  147. var name = list[i].name || list[i].localName;
  148. if(util.isEmpty(name)){
  149. continue;
  150. }
  151. if(name.indexOf('JL') >= 0 && list[i].RSSI != 0){
  152. console.log(list[i]);
  153. devices.push(list[i]);
  154. }
  155. }
  156. console.log('总共有' + devices.length + "个设备需要设置")
  157. if (devices.length <= 0) {
  158. return;
  159. }
  160. that.connectBLE(devices);
  161. },
  162. fail: function() {
  163. util.toastError('搜索蓝牙设备失败');
  164. }
  165. })
  166. },
  167. connectBLE: function(devices){
  168. this.printLog('总共有' + devices.length + "个设备需要设置")
  169. var that = this;
  170. wx.hideLoading();
  171. isFound = true;
  172. clearInterval(delayTimer);
  173. wx.stopBluetoothDevicesDiscovery({
  174. success: function (res) {
  175. that.printLog('连接蓝牙成功之后关闭蓝牙搜索');
  176. }
  177. })
  178. //两个的时候需要选择
  179. var list = [];
  180. for (var i = 0; i < devices.length; i++) {
  181. var name = devices[i].name || devices[i].localName;
  182. list.push(name + "[" + devices[i].deviceId + "]")
  183. }
  184. this.setData({
  185. deviceArray: list
  186. })
  187. //默认选择
  188. this.setData({
  189. currDeviceID: list[0]
  190. })
  191. },
  192.  
  193. createBLE: function(deviceId){
  194. this.printLog("连接: [" + deviceId+"]");
  195. var that = this;
  196. this.closeBLE(deviceId, function(res){
  197. console.log("预先关闭,再打开");
  198. setTimeout(function(){
  199. wx.createBLEConnection({
  200. deviceId: deviceId,
  201. success: function (res) {
  202. that.printLog("设备连接成功");
  203. that.getBLEServiceId(deviceId);
  204. },
  205. fail: function (res) {
  206. that.printLog("设备连接失败" + res.errMsg);
  207. }
  208. })
  209. }, 2000)
  210. });
  211. },
  212. //获取服务UUID
  213. getBLEServiceId: function(deviceId){
  214. this.printLog("获取设备[" + deviceId + "]服务列表")
  215. var that = this;
  216. wx.getBLEDeviceServices({
  217. deviceId: deviceId,
  218. success: function(res) {
  219. console.log(res);
  220. var services = res.services;
  221. if (services.length <= 0){
  222. that.printLog("未找到主服务列表")
  223. return;
  224. }
  225. that.printLog('找到设备服务列表个数: ' + services.length);
  226. if (services.length == 1){
  227. var service = services[0];
  228. that.printLog("服务UUID:["+service.uuid+"] Primary:" + service.isPrimary);
  229. that.getBLECharactedId(deviceId, service.uuid);
  230. }else{ //多个主服务
  231. //TODO
  232. }
  233. },
  234. fail: function(res){
  235. that.printLog("获取设备服务列表失败" + res.errMsg);
  236. }
  237. })
  238. },
  239. getBLECharactedId: function(deviceId, serviceId){
  240. this.printLog("获取设备特征值")
  241. var that = this;
  242. wx.getBLEDeviceCharacteristics({
  243. deviceId: deviceId,
  244. serviceId: serviceId,
  245. success: function(res) {
  246. console.log(res);
  247. //这里会获取到两个特征值,一个用来写,一个用来读
  248. var chars = res.characteristics;
  249. if(chars.length <= 0){
  250. that.printLog("未找到设备特征值")
  251. return ;
  252. }
  253. that.printLog("找到设备特征值个数:" + chars.length);
  254. if(chars.length == 2){
  255. for(var i=0; i<chars.length; i++){
  256. var char = chars[i];
  257. that.printLog("特征值[" + char.uuid + "]")
  258. var prop = char.properties;
  259. if(prop.notify == true){
  260. that.printLog("该特征值属性: Notify");
  261. that.recvBLECharacterNotice(deviceId, serviceId, char.uuid);
  262. }else if(prop.write == true){
  263. that.printLog("该特征值属性: Write");
  264. that.sendBLECharacterNotice(deviceId, serviceId, char.uuid);
  265. }else{
  266. that.printLog("该特征值属性: 其他");
  267. }
  268. }
  269. }else{
  270. //TODO
  271. }
  272. },
  273. fail: function(res){
  274. that.printLog("获取设备特征值失败")
  275. }
  276. })
  277. },
  278. recvBLECharacterNotice: function(deviceId, serviceId, charId){
  279. //接收设置是否成功
  280. this.printLog("注册Notice 回调函数");
  281. var that = this;
  282. wx.notifyBLECharacteristicValueChange({
  283. deviceId: deviceId,
  284. serviceId: serviceId,
  285. characteristicId: charId,
  286. state: true, //启用Notify功能
  287. success: function(res) {
  288. wx.onBLECharacteristicValueChange(function(res){
  289. console.log(res);
  290. that.printLog("收到Notify数据: " + that.ab2hex(res.value));
  291. //关闭蓝牙
  292. wx.showModal({
  293. title: '配网成功',
  294. content: that.ab2hex(res.value),
  295. showCancel: false
  296. })
  297. });
  298. },
  299. fail: function(res){
  300. console.log(res);
  301. that.printLog("特征值Notice 接收数据失败: " + res.errMsg);
  302. }
  303. })
  304. },
  305. sendBLECharacterNotice: function (deviceId, serviceId, charId){
  306. //发送ssid/pass
  307. this.printLog("延时1秒后,发送SSID/PASS");
  308. var that = this;
  309. var cell = {
  310. "ssid": this.data.ssid,
  311. "pass": this.data.pass
  312. }
  313. var buffer = this.string2buffer(JSON.stringify(cell));
  314. setTimeout(function(){
  315. wx.writeBLECharacteristicValue({
  316. deviceId: deviceId,
  317. serviceId: serviceId,
  318. characteristicId: charId,
  319. value: buffer,
  320. success: function(res) {
  321. that.printLog("发送SSID/PASS 成功");
  322. },
  323. fail: function(res){
  324. console.log(res);
  325. that.printLog("发送失败." + res.errMsg);
  326. },
  327. complete: function(){
  328.  
  329. }
  330. })
  331.  
  332. }, 1000);
  333. },
  334.  
  335. closeBLE: function(deviceId, callback){
  336. var that = this;
  337. wx.closeBLEConnection({
  338. deviceId: deviceId,
  339. success: function(res) {
  340. that.printLog("断开设备[" + deviceId + "]成功.");
  341. console.log(res)
  342. },
  343. fail: function(res){
  344. that.printLog("断开设备成功.");
  345. },
  346. complete: callback
  347. })
  348. },
  349.  
  350. printLog: function(msg){
  351. var logs = this.data.logs;
  352. logs.push(msg);
  353. this.setData({ logs: logs })
  354. },
  355. /**
  356. * 将字符串转换成ArrayBufer
  357. */
  358. string2buffer(str) {
  359. if (!str) return;
  360. var val = "";
  361. for (var i = 0; i < str.length; i++) {
  362. val += str.charCodeAt(i).toString(16);
  363. }
  364. console.log(val);
  365. str = val;
  366. val = "";
  367. let length = str.length;
  368. let index = 0;
  369. let array = []
  370. while (index < length) {
  371. array.push(str.substring(index, index + 2));
  372. index = index + 2;
  373. }
  374. val = array.join(",");
  375. // 将16进制转化为ArrayBuffer
  376. return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
  377. return parseInt(h, 16)
  378. })).buffer
  379. },
  380. /**
  381. * 将ArrayBuffer转换成字符串
  382. */
  383. ab2hex(buffer) {
  384. var hexArr = Array.prototype.map.call(
  385. new Uint8Array(buffer),
  386. function (bit) {
  387. return ('00' + bit.toString(16)).slice(-2)
  388. }
  389. )
  390. return hexArr.join('');
  391. },
  392. inputSSID: function(res) {
  393. var ssid = res.detail.value;
  394. this.setData({
  395. ssid: ssid
  396. })
  397. },
  398. inputPASS: function(res) {
  399. var pass = res.detail.value;
  400. this.setData({
  401. pass: pass
  402. })
  403. }
  404.  
  405. })

//补充util.js

  1. const formatTime = date => {
  2. const year = date.getFullYear()
  3. const month = date.getMonth() + 1
  4. const day = date.getDate()
  5. const hour = date.getHours()
  6. const minute = date.getMinutes()
  7. const second = date.getSeconds()
  8.  
  9. return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
  10. }
  11.  
  12. const formatNumber = n => {
  13. n = n.toString()
  14. return n[1] ? n : '0' + n
  15. }
  16.  
  17. const isEmpty = function(str){
  18. if(str == null || str == undefined || str == ""){
  19. return true;
  20. }
  21. return false;
  22. }
  23.  
  24. const randomWord = function(range){
  25. var str = "",
  26. arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
  27. // 随机产生
  28. for (var i = 0; i < range; i++) {
  29. var pos = Math.round(Math.random() * (arr.length - 1));
  30. str += arr[pos];
  31. }
  32. return str;
  33. }
  34.  
  35. const toastServerError = function(){
  36. wx.showToast({
  37. title: '服务器异常,请稍后重试!',
  38. icon: 'none',
  39. duration: 1200,
  40. mask: true
  41. })
  42. }
  43. const toastError = function(info){
  44. wx.showToast({
  45. title: info,
  46. icon: 'none',
  47. duration: 1200,
  48. mask: true
  49. })
  50. }
  51.  
  52. module.exports = {
  53. formatTime: formatTime,
  54. isEmpty: isEmpty,
  55. toastServerError: toastServerError,
  56. toastError: toastError,
  57. randomWord: randomWord
  58. }

//补充分包代码

  1. /* 统一发送数据,带分包 */
  2. sendBLEData: function (deviceId, serviceId, charId, array){
  3. var that = this;
  4. if(array.length <= 0){
  5. that.printLog("发送SSID/PASS 完成");
  6. return;
  7. }
  8. var list = array.splice(0, 20);
  9. var buffer = new Uint8Array(list).buffer;
  10.  
  11. wx.writeBLECharacteristicValue({
  12. deviceId: deviceId,
  13. serviceId: serviceId,
  14. characteristicId: charId,
  15. value: buffer,
  16. success: function (res) {
  17. that.printLog("发送SSID/PASS 分包发送");
  18. that.sendBLEData(deviceId, serviceId, charId, array);
  19. },
  20. fail: function (res) {
  21. console.log(res);
  22. that.printLog("发送失败." + res.errMsg);
  23. },
  24. complete: function () {
  25.  
  26. }
  27. })
  28. },

4. 运行时截图

  

工具下载地址:

  https://files.cnblogs.com/files/wunaozai/sscom5.13.1.zip

  https://files.cnblogs.com/files/wunaozai/CH341SER_64bit.zip

源代码下载 :

  https://files.cnblogs.com/files/wunaozai/bluetoothconfig.rar

参考资料:

  https://www.cnblogs.com/guhonghao/p/9947144.html

本文地址:

  https://www.cnblogs.com/wunaozai/p/11512874.html

微信小程序开发-蓝牙功能开发的更多相关文章

  1. 微信小程序调用蓝牙功能控制车位锁

    第一次学用微信小程序,项目需要,被逼着研究了一下,功能是调用微信小程序的蓝牙功能,连接上智能车位锁,控制升降,大概步骤及调用的小程序接口API如下: 1.打开蓝牙模块 wx.openBluetooth ...

  2. 微信小程序之蓝牙开发(详细读数据、写数据、附源码)

    本文将详细介绍微信小程序的蓝牙开发流程(附源码)准备:微信只支持低功耗蓝牙也就是蓝牙4.0,普通的蓝牙模块是用不了的,一定要注意. 蓝牙可以连TTL接到电脑上,再用XCOM调试 一开始定义的变量 va ...

  3. 微信小程序购物商城系统开发系列-工具篇

    微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将 ...

  4. 微信小程序购物商城系统开发系列

    微信小程序购物商城系统开发系列 微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统. ...

  5. 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...

  6. 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...

  7. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  8. 微信小程序购物商城系统开发系列-目录结构

    上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的 ...

  9. 从微信小程序到鸿蒙js开发【11】——页面路由

    目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...

随机推荐

  1. React: 研究React的组件化

    一.简介大概 在以往的Web开发中,会把web页面所有的复杂控件作为一个单一的整体进行开发,由于控件之间需要进行通信,因此不同的组件之间的耦合度会很多,由于开发一个控件的时候要考虑到控件与控件之间的联 ...

  2. IT兄弟连 HTML5教程 HTML和CSS的关系

    HTML是描述网页的标记语言,是将内容放到网页上,虽然HTML本身也自带一些样式功能,通过自身的属性,来实现一些特定的效果,制作出来的只能是一个网页,而不是一个美观的网页.最主要的是在HTML里面,一 ...

  3. linux学习之Ubuntu

    查看自己的ubuntu版本,输入以下命令(我的都是在root用户下的,在普通用户要使用sudo)第一行的lsb是因为没有安装LSB,安装之后就不会出现这个东西.LSB(Linux Standards ...

  4. win7系统下安装Ubuntu18.04组成双系统

    最近在闲鱼上花了350大洋淘到了一台tinkpad sl510,这大概是一台发布于2009年的一台电脑了吧,处理器是酷睿二t440,2Gddr3的显卡,让我有点意外的是这台电脑的硬盘是7200转的32 ...

  5. What is Java virtual machine?

    Java Virtual Machine (JVM) is a specification that provides runtime environment in which java  bytec ...

  6. make 命令与 Makefile

    make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...

  7. iota: Golang 中优雅的常量

    阅读约 11 分钟 注:该文作者是 Katrina Owen,原文地址是 iota: Elegant Constants in Golang 有些概念有名字,并且有时候我们关注这些名字,甚至(特别)是 ...

  8. 易优CMS:volist的基础应用

      [基础用法] 名称:volist 功能:数据/记录循环输出标签 语法: {eyou:channel type='top'}            {eyou:volist name='$field ...

  9. windows下dubbo-admin2.6.x之后版本的安装

    安装zookeeper(单机) 下载bin.tar.gz的版本,解压 conf下的zoo_sample.cfg改zoo.cfg zoo.cfg里添加配置 dataDir=G:/zookeeper-/d ...

  10. Shadow broker=>fuzzbunch+metasploit 攻击外网测试以及metasploit大批量扫描目标IP

    0x01 前言 4月14日,影子经纪人在steemit.com上公开了一大批NSA(美国国家安全局)“方程式组织” (Equation Group)使用的极具破坏力的黑客工具,其中包括可以远程攻破全球 ...