Aiden's blog Aiden's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • JavaScript教程
    • JavaScript高级程序设计
    • ES6 教程
    • Vue
    • Vue3.0
    • React
    • TypeScript 从零实现 axios
    • Git
    • TypeScript
    • JS设计模式总结
    • 小程序
    • 小程序云开发
    • Echarts
    • 微前端
    • H5
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 搜索引擎
  • ES系列
  • 经典面试题
  • 知识点总结
  • uni-app
  • 算法
  • Vue3实战
  • 小程序chatgpt
  • 小程序配网流程
  • 程序WIFI配网
  • 小程序WebSocket
  • H5 WebSocket
  • H5 TTS
  • Vue3实现OSS存储
  • 大文件分片上传
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Aiden Wu

前端界的小学生
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • JavaScript教程
    • JavaScript高级程序设计
    • ES6 教程
    • Vue
    • Vue3.0
    • React
    • TypeScript 从零实现 axios
    • Git
    • TypeScript
    • JS设计模式总结
    • 小程序
    • 小程序云开发
    • Echarts
    • 微前端
    • H5
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 搜索引擎
  • ES系列
  • 经典面试题
  • 知识点总结
  • uni-app
  • 算法
  • Vue3实战
  • 小程序chatgpt
  • 小程序配网流程
  • 程序WIFI配网
  • 小程序WebSocket
  • H5 WebSocket
  • H5 TTS
  • Vue3实现OSS存储
  • 大文件分片上传
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

  • 博客搭建

  • 搜索引擎

  • ES系列

  • 经典面试题

  • 知识点总结

  • uni-app

  • 算法

  • Vue3实战

  • 小程序chatgpt

  • 小程序WIFI配网

  • 小程序配网流程

    • 小程序配网流程
      • 蓝牙名称
      • Device UUID
      • Service UUID
      • characteristics UUID
      • BLE蓝牙配网(蓝牙传输协议)
        • 小程序端->设备端
        • 设备端->小程序端
      • BLE蓝牙配网(羊羊太空舱)
        • 小程序端->设备端
        • 设备端->小程序端
      • 小程序端蓝牙配网注意事项
        • 小程序->设备端
        • 设备端->小程序
  • 小程序WebSocket

  • H5 WebSocket

  • H5 TTS

  • Vue3实现OSS存储

  • 大文件分片上传

  • 技术
  • 小程序配网流程
wushengxin
2024-08-05
目录

小程序配网流程

# 小程序蓝牙配网

蓝牙低功耗是从蓝牙 4.0 起支持的协议,与经典蓝牙相比,功耗极低、传输速度更快,但传输数据量较小。常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。

# 蓝牙名称

蓝牙名称规范参考 (opens new window),作用是用于搜索蓝牙设备时能够搜索固定产品的蓝牙设备,要求名称命名具有唯一性

  • 命名规则
    • 产品线:使用英文缩写或全称,首字母大写。例如:XYY(喜羊羊)、SW(超飞)、EGGY(蛋仔)、NALOONG(奶龙)
    • 方案商:使用英文缩写或全称,首字母大写。例如:ES(ESP-32 乐鑫)、AN(Android)、AC(AC79XX 杰理)、STM(STM 意法半导体)
    • 特性版本:使用简短的英文单词或缩写表示产品的主要特性。例如:S(Standard标准版)、U(Ultra专业版)、L(Lite轻量版)、P(Plus增强版)
  • 蓝牙名称结构: 产品线-方案商-特性版本-SN , 例如:XYY-AC-S-AF1234766BQ103D

# Device UUID

  • Device UUID也可以被称作为DeviceID

  • Android 设备上扫描获取到的 deviceId 为外围设备的 MAC 地址,相对固定

  • iOS 设备上扫描获取到的 deviceId 是系统根据外围设备 MAC 地址及发现设备的时间生成的 UUID,是设备上的Core Bluetooth为该设备分配的标识符。对于已连接过的设备,UUID 会在一段时间内保持不变(正常是15-20分钟变化一次)。此外,UUID 也会在某些条件下可能会发生变化(如系统蓝牙模块重启、配对设备被忽略等),在不同的设备上获取到的 UUID 也是不同的。不同手机连接同一设备的uuid不是同一个。

# Service UUID

  • 蓝牙设备的ID,通过此ID可以进行连接蓝牙设备,连接成功之后可以获取serviceUUID,serviceUUID可以有多个,每个serviceUUID可以看作是服务,每个serviceUUID中可以定义多个characteristics uuid(特征值)
  • Service UUID已经有了很多特定的,也可以自己定义。特定的:{0000xxxx-0000-1000-8000-00805F9B34FB}
  • xxxx = 0x0000 ~ 0xFFFE

# characteristics UUID

  • characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容

# BLE蓝牙配网(蓝牙传输协议)

小程序与设备端蓝牙通讯协议以这个为标准:蓝牙传输协议 (opens new window)

# 小程序端->设备端

# 包结构

  • 包头(1字节):固定位0x55
  • 包类型(1字节):用于标识数据包的类型
  • 包序号(1字节):用于标识数据包的序号,下标从0开始,用于在接收端重组数据包。
  • 总包数(1字节):用于标识数据包总数,用于在接收端重组数据包。
  • 数据包长度(1字节):当前包有效载荷长度。
  • 数据包(可变长度,最大14字节):有效负载数据包。
  • 校验位(1字节):计算包头及有效载荷的校验值,用于接收端验证数据包的完整性。
    • 校验位计算:~(包类型+包序号+包总数+数据长度+数据包) & 0xFF
包头(1字节) 包类型(1字节) 包序号(1字节) 包总数(1字节) 数据长度(1字节) 数据包(可变长度) 校验位
Data0 Data1 Data2 Data3 Data4 Data5-N DataN+1
固定为0x55 请查看蓝牙传输协议 (opens new window) 下标从0开始 分包总数 负载包长度 1-14字节 ~(Data1+Data2+Data3+Data4+Data5+DataN) & 0xFF

# 配网步骤

  • 初始化蓝牙适配器
  • 通过DeviceID连接蓝牙设备
  • 连接蓝牙后获取设备的Service UUID,需要延迟一下,防止连接成功立即获取服务号获取不到**(延迟1s)**
  • Service UUID拿到后获取设备的characteristics UUID
  • 先监听蓝牙发送的内容notifyBLECharacteristicValueChange
  • 蓝牙监听成功后再发送数据writeBLECharacteristicValue
    • 小程序不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙 4.0 单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过 20 字节
    • 小程序需要发送数据
      • ssid:Wi-Fi名称
      • pwd:Wi-Fi密码
      • user_uuid:用户的UUID
  • 绑定成功后更新设备配置的deviceId才跳转到连接成功页面。作用: 用来存储当前绑定设备的deviceId,下次直接进入小程序首页已有蓝牙设备绑定直接通过deviceId建立连接

# 设备端->小程序端

# 包结构

  • 包头(1字节):固定位0x56。
  • 包类型(1字节) : 当前ACK包对应的包类型,参考包类型表
  • 状态码(1字节):状态码,由通用状态码和定制状态码组成
  • 包序号(1字节):发送端需要重发的数据包序号。
  • 校验位(1字节):计算包头及有效载荷的校验值,用于接收端验证数据包的完整性。
包头(1字节) 包类型(1字节) 状态码(1字节) 包序号(1字节) 校验位
Data0 Data1 Data2 Data3 Data4
固定为0x56 详情请查看下方通讯码表 请查看 通用状态码表 和 需要重发的数据包序号 ~(Data1+Data2+Data3) & 0xFF

# 配网步骤

  • 设备端需要设置一个固定的Service UUID,为后续能够获取特定的characteristics UUID做准备
  • Service UUID的属性isPrimary 需设置为true
  • Service UUID拿到后获取设备的characteristics UUID
    • 一个读的特征值UUID(readCharacteristic_UUID):属性值indicate、notify 、read 必须为true,小程序才能监听到设备的消息
    • 一个写的特征值UUID(writeCharacteristic_UUID):属性值write必须为true
  • 接收ssid、pwd、user_uuid,需要做以下表格相应信息的回复,小程序上相应的配网文案打勾交互才有反馈
  • 绑定成功后还需要做OTA更新结果上报

注意:OTA更新结果上报成功后才返回绑定成功状态码给到小程序

包名称 包类型值 状态码 描述
wifi_status 0x03 0x30 完整设备接收wifi账号密码
0x31 wifi信息错误 报错连接失败、账号密码错误
0x32 wifi连接中
0x33 连接网络成功
0x34 连接网络失败
wifi状态
uesr_binding_status 0x05 0x35 用户绑定成功
0x36 用户绑定失败
0x37 用户绑定中
用户绑定状态

# BLE蓝牙配网(羊羊太空舱)

# 小程序端->设备端

传递给设备的具体参数信息:

  • ssid:输入的WiFi名称

  • openid:用户的openid

  • pwd:输入的WiFi密码

  • accountBind:联网绑定字段,0=>关闭 1=>打开

具体规则如下

第一包包头(1字节) 中间包首包(1个字节) 包尾首包(1个字节) 数据包(可变长度)
Data0 Data1 Data2 Data3
固定为0x01 固定为0x02 固定为0x00 不足长度的包固定为0x00
const START_BYTE = 0x01
const CONTINUE_BYTE = 0x02
const END_BYTE = 0x00

// 字符串转二进制编码(羊羊太空舱)
export function textToBinary(strData) {
  try {
    const originData = unescape(encodeURIComponent(strData))
      .split('')
      .map((val) => val.charCodeAt())
    const MAX_SIZE = 18 // 分包最大发送数据包的长度
    const size = Math.ceil(originData.length / MAX_SIZE)
    const data = new Array(size)
    let start = 0
    let end = 0
    let index = 0

    while (index < size) {
      index++
      if (index === size) {
        data[index - 1] = new Uint8Array(MAX_SIZE + 1)
        data[index - 1][0] = END_BYTE
      } else if (index === 1) {
        data[index - 1] = new Uint8Array(MAX_SIZE + 1)
        data[index - 1][0] = START_BYTE
      } else {
        data[index - 1] = new Uint8Array(MAX_SIZE + 1)
        data[index - 1][0] = CONTINUE_BYTE
      }
      end = Math.min(start + MAX_SIZE, originData.length)
      data[index - 1].set(originData.slice(start, end), 1)
      start = end
    }

    return data
  } catch (e) {
    console.error(e)
  }
  return null
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 设备端->小程序端

  • 设备端需要设置一个固定的Service UUID,为后续能够获取特定的characteristics UUID做准备

  • Service UUID的属性isPrimary 需设置为true

  • Service UUID拿到后获取设备的characteristics UUID

    • 一个读的特征值UUID(readCharacteristic_UUID):属性值indicate、notify 、read 必须为true,小程序才能监听到设备的消息
    • 一个写的特征值UUID(writeCharacteristic_UUID):属性值write必须为true
  • 接收ssid、pwd、user_uuid,需要做以下表格相应信息的回复,小程序上相应的配网文案打勾交互才有反馈

  • 绑定成功后还需要做OTA更新结果上报

注意:OTA更新结果上报成功后才返回绑定成功状态码给到小程序

配网流程中发送以下类型的单个状态码包给小程序

状态码 描述
0x30 wifi信息错误 报错连接失败、账号密码错误
0x31 密码输入正确的时候需要进行校验
0x32 连接网络成功
0x33 连接网络失败
0x37 完整设备接收wifi账号密码
wifi状态
0x34 用户绑定成功
0x35 用户绑定失败
0x36 用户绑定成功(已用同wifi配过一次网返回该状态码)
用户绑定状态

# 小程序端蓝牙配网注意事项

  • 等待响应:很多情况下需要等待设备响应,尤其在IOS环境下,比如
    • 监听到蓝牙开启后,不能马上开始搜索,需要等待2秒
    • 连接蓝牙后获取设备的Service UUID,需要等待1秒,防止连接成功立即获取服务号获取不到
    • 开启notify以后,不能马上发送消息,需要等待1秒
  • Mac和UUID:安卓的MAC地址是可以获取到的所以设备的ID是固定的,但是IOS是获取不到MAC地址的,只能获取设备的UUID,而且是动态的,所以需要使用其他方法来查询。
  • IOS下只有搜索可以省略,如果你知道了设备的ID,服务ID和各种特征值ID,在安卓下可以直接连接,然后发送消息,省去搜索设备,搜索服务和搜索特征值的过程,但是在IOS下,只能指定设备ID连接,后面的过程是不能省略的**(搜索服务和搜索特征值的过程,不然连接不上设备的蓝牙**)。
  • 监听到的消息要进行过滤处理,有些设备会抽风一样的发送同样的消息,需要在处理逻辑里面去重。

# 小程序声波配网

  • 声波配网,即通过手机发出声波,将ssid、password等信息传给设备的一种配网方式。适用于没有触屏或触屏较小不易于信息输入,但是拥有麦克风的智能设备,如智能音箱、智能家庭助手等。其优点是配网速度快、可人耳感知,缺点是受环境干扰较大。

  • 声波配网案例 (opens new window)该库仅用于生成和分析从音频设备(扬声器、麦克风等)播放和捕获的原始波形。只要您提供用于音频样本排队和出队的回调,您就可以自由使用任何音频后端(例如 PulseAudio、ALSA 等)。

  • 实现声波配网,首先需要一套特定的算法库,算法库分小程序端和设备端两部分。小程序端算法库将ssid信息由字符串转化为声音信号,然后将声音信号通过音频模块播放出来。同时,设备端录下这一段声音,然后用同一套算法库将声音信息解析出来,还原成原来的ssid信息(字符串),最后用解析到的ssid信息用于连接wifi。

img

# 小程序->设备端

  • 一段声波最大发送140个字符,节省字符使用UTF-8进行 Base64编码

  • 播放完一轮声波后查询设备绑定状态,声波播放结束查询用户是否绑定成功,未绑定成功,则继续播放声波

传递给设备的具体参数信息

  • s为SSID:wifi名称
  • p为pwd:wifi密码
  • si为sessionId:抢占式配网(随机生成的6为uuid字符串)
  • u为uuid:小程序的unionId(用户的uuid)

发送方式

  • 使用 UTF-8 进行 Base64 编码
  • 分三个包进行发送
    • s
    • p、si
    • u
// 生成随机的唯一标识符
export function generateUniqueID(length) {
  let result = ''
  const characters =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length)
    result += characters.charAt(randomIndex)
  }

  return result
}

// 使用 UTF-8 进行 Base64 编码
export function _utf8_encode(str) {
  const utf8 = unescape(encodeURIComponent(str))
  const buffer = new ArrayBuffer(utf8.length)
  const view = new Uint8Array(buffer)
  for (let i = 0; i < utf8.length; i++) {
    view[i] = utf8.charCodeAt(i)
  }

  return uni.arrayBufferToBase64(buffer)
}

const deviceParams1 = {
  s: wifiForm.wifiSSID
}
const deviceParams2 = {
  p: wifiForm.wifiPWD,
  si: generateUniqueID(6)
}
const deviceParams3 = {
  u: uni.getStorageSync('userInfo').uuid
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 设备端->小程序

声波配网案例 (opens new window)该库仅用于生成和分析从音频设备(扬声器、麦克风等)播放和捕获的原始波形。

  • 接收三个包的数据,都获取到后执行绑定接口
    • s
    • p、si
    • u
  • 绑定成功后还需要做OTA更新结果上报

注意:OTA更新结果上报成功后才返回绑定成功状态码给到小程序

配网流程中发送以下类型的单个状态码包给小程序

状态码 描述
0x30 wifi信息错误 报错连接失败、账号密码错误
0x31 密码输入正确的时候需要进行校验
0x32 连接网络成功
0x33 连接网络失败
0x37 完整设备接收wifi账号密码
wifi状态
0x34 用户绑定成功
0x35 用户绑定失败
0x36 用户绑定成功(已用同wifi配过一次网返回该状态码)
用户绑定状态
编辑 (opens new window)
上次更新: 2024/08/05, 18:11:13
小程序WIFI配网
小程序WebSocket

← 小程序WIFI配网 小程序WebSocket→

最近更新
01
大文件分片上传
08-05
02
Vue3实现OSS存储
08-05
03
H5 TTS
08-05
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Aiden Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×