uniapp小程序连接蓝牙设备实战指南‌

一、引言

在许多物联网(IoT)应用场景中,如智能手环、蓝牙耳机、智能家居、传感器设备等,通过蓝牙与设备通信是必不可少的环节。微信/支付宝小程序如果想与 BLE(Bluetooth Low Energy)设备交互,需要借助对应平台提供的蓝牙 API。uniapp 作为一个跨端开发框架,将这些 API 进行了统一封装,让你能用一套代码同时支持多端环境。

本指南将带你从零开始,学习如何在 uniapp 小程序中:

  1. 初始化蓝牙模块(检查适配器状态)
  2. 扫描附近可用设备
  3. 连接指定蓝牙设备
  4. 发现设备服务与特征
  5. 开启特征消息订阅并读写数据
  6. 断开与销毁连接
  7. 处理异常与边界情况

内容同时配备ASCII 流程图与详细代码示例,让你更容易理解蓝牙流程背后的原理。在开始之前,请确保你的蓝牙设备为 BLE(低功耗蓝牙)协议,且已正确打开,并与手机配对或处于可被扫描状态。


二、蓝牙通信基础

2.1 BLE(Bluetooth Low Energy)概念

  • BLE(低功耗蓝牙):主要用于短距离、低功耗的数据交换,适合物联网设备。
  • BLE 设备由 服务(Service)特征(Characteristic) 组成:

    • Service:一组相关特征的集合,比如“心率服务”中包含多个“心率测量特征”。
    • Characteristic:可读或可写的具体数据项,比如“心率值”、“电池电量”等。

在小程序中,常见的 BLE 流程为:

  1. 打开蓝牙模块 → 2. 扫描设备 → 3. 连接指定设备 → 4. 获取服务列表 → 5. 获取特征列表 → 6. 读写/订阅特征 → 7. 断开连接 → 8. 关闭蓝牙模块(可选)

2.2 小程序蓝牙适配与 uniapp 封装

不同平台(微信小程序、支付宝小程序、百度小程序等)对蓝牙的原生 API 稍有差异,但 uniapp 在运行时会映射到对应平台。本文所有示例均以微信小程序为主,支付宝小程序模式下也基本一致,只需将 uni 替换为 my(支付宝)或 swan(百度)即可。

在 uniapp 中,一些常用核心方法包括:

  • uni.openBluetoothAdapter()
  • uni.onBluetoothAdapterStateChange(callback)
  • uni.startBluetoothDevicesDiscovery(options)
  • uni.onBluetoothDeviceFound(callback)
  • uni.createBLEConnection(options)
  • uni.getBLEDeviceServices(options)
  • uni.getBLEDeviceCharacteristics(options)
  • uni.notifyBLECharacteristicValueChange(options)
  • uni.onBLECharacteristicValueChange(callback)
  • uni.writeBLECharacteristicValue(options)
  • uni.closeBLEConnection(options)
  • uni.closeBluetoothAdapter()

本指南后续会依序介绍每个步骤的使用方法与细节。


三、环境准备与权限配置

3.1 app.json / manifest.json 配置

在小程序中使用蓝牙,需要在 app.json(或对应页面的 json 配置)里声明使用蓝牙模块权限。以微信小程序为例,app.json 中应该包含:

// app.json
{
  "pages": [
    "pages/index/index",
    "pages/bluetooth/bluetooth"
  ],
  "window": {
    "navigationBarTitleText": "蓝牙示例"
  },
  // 在 "permission" 节点中声明蓝牙权限(仅微信小程序 2.10.0+ 支持)
  "permission": {
    "scope.userLocation": {
      "desc": "您的地理位置将用于搜索附近的蓝牙设备" 
    }
  }
}

说明

  1. 扫描蓝牙 可能需要打开设备定位权限,尤其是在 iOS 设备上,否则无法扫描到 BLE 设备。
  2. 在支付宝/百度小程序,可参考它们的权限要求,无需额外在 app.json 中声明,但用户会在首次使用时被弹窗授权。

3.2 兼容性检查

在真正调用蓝牙 API 前,需要检查当前环境是否支持蓝牙。常见做法:

// utils/bluetooth.js
export function checkBluetoothAdapter() {
  return new Promise((resolve, reject) => {
    uni.openBluetoothAdapter({
      success(res) {
        console.log('蓝牙适配器已启动', res);
        resolve(res);
      },
      fail(err) {
        console.error('打开蓝牙适配器失败', err);
        uni.showToast({ title: '请检查手机蓝牙或系统版本是否支持', icon: 'none' });
        reject(err);
      }
    });
  });
}
  • 调用时机:建议在页面 onLoad 或用户点击“连接蓝牙”按钮时调用,以免小程序启动即打开蓝牙,影响性能。

四、蓝牙扫描与发现设备

4.1 打开蓝牙适配器

  1. 在页面的 methodsonLoad 里调用 uni.openBluetoothAdapter(),启动本机蓝牙模块。
  2. 监听蓝牙状态变化,若用户关闭蓝牙或设备离线,可及时提示。
<script>
export default {
  data() {
    return {
      isAdapterOpen: false
    };
  },
  onLoad() {
    this.initBluetooth();
  },
  methods: {
    initBluetooth() {
      uni.openBluetoothAdapter({
        success: (res) => {
          console.log('openBluetoothAdapter success', res);
          this.isAdapterOpen = true;

          // 监听蓝牙适配器状态变化
          uni.onBluetoothAdapterStateChange((adapterState) => {
            console.log('adapterState changed', adapterState);
            this.isAdapterOpen = adapterState.available;
            if (!adapterState.available) {
              uni.showToast({ title: '蓝牙已关闭', icon: 'none' });
            }
          });
        },
        fail: (err) => {
          console.error('openBluetoothAdapter fail', err);
          uni.showToast({ title: '请先打开手机蓝牙', icon: 'none' });
        }
      });
    }
  }
};
</script>
  • uni.onBluetoothAdapterStateChange(callback) 会实时回调蓝牙模块的 available(是否可用)和 discovering(是否正在扫描)等状态。
  • 如果用户在小程序后台或其他地方关闭蓝牙,需要通过该监听及时更新 UI 并停止相关操作。

4.2 开始扫描蓝牙设备

  1. 在确认适配器可用后,调用 uni.startBluetoothDevicesDiscovery() 开始扫描。
  2. 可通过传入 services(要搜索的服务 UUID 列表)参数进行定向扫描;如果想搜索所有设备则无需传入。
  3. 监听 uni.onBluetoothDeviceFound(callback),在回调里获取到附近每个新发现的设备信息。
<template>
  <view class="container">
    <button @click="startScan">开始扫描</button>
    <text v-if="isScanning">扫描中...</text>
    <view class="device-list">
      <view 
        v-for="(dev, index) in devices" 
        :key="dev.deviceId" 
        class="device-item"
        @click="connectDevice(dev)"
      >
        <text>{{ dev.name || '未知设备' }} ({{ dev.deviceId }})</text>
        <text>RSSI: {{ dev.RSSI }}</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isAdapterOpen: false,
      isScanning: false,
      devices: [] // 已发现设备列表
    };
  },
  onLoad() {
    this.initBluetooth();
  },
  methods: {
    initBluetooth() {
      uni.openBluetoothAdapter({
        success: () => {
          this.isAdapterOpen = true;
          uni.onBluetoothAdapterStateChange((state) => {
            this.isAdapterOpen = state.available;
            this.isScanning = state.discovering;
          });
        },
        fail: () => {
          uni.showToast({ title: '请先打开手机蓝牙', icon: 'none' });
        }
      });
    },
    startScan() {
      if (!this.isAdapterOpen) {
        uni.showToast({ title: '蓝牙未初始化', icon: 'none' });
        return;
      }
      this.devices = [];
      uni.startBluetoothDevicesDiscovery({
        // allowDuplicatesKey: false, // 微信小程序可选,是否重复上报同一设备
        success: (res) => {
          console.log('start discovery success', res);
          this.isScanning = true;

          // 监听新设备发现事件
          uni.onBluetoothDeviceFound((res) => {
            // res.devices 为数组
            res.devices.forEach((device) => {
              // 过滤已经存在的设备
              const exists = this.devices.findIndex((d) => d.deviceId === device.deviceId) !== -1;
              if (!exists) {
                this.devices.push(device);
              }
            });
          });
        },
        fail: (err) => {
          console.error('start discovery fail', err);
          uni.showToast({ title: '扫描失败', icon: 'none' });
        }
      });
    },
    stopScan() {
      uni.stopBluetoothDevicesDiscovery({
        success: () => {
          this.isScanning = false;
          console.log('停止扫描');
        }
      });
    },
    connectDevice(device) {
      // 点击设备后停止扫描
      this.stopScan();
      // 跳转到连接页面或执行连接逻辑
      uni.navigateTo({
        url: `/pages/bluetoothDetail/bluetoothDetail?deviceId=${device.deviceId}&name=${device.name}`
      });
    }
  },
  onUnload() {
    // 页面卸载时停止扫描以节省资源
    this.stopScan();
  }
};
</script>

<style>
.container {
  padding: 20px;
}
button {
  margin-bottom: 10px;
}
.device-list {
  margin-top: 10px;
}
.device-item {
  padding: 10px;
  border-bottom: 1px solid #eee;
}
</style>

核心说明

  • uni.startBluetoothDevicesDiscovery():开始扫描附近 BLE 设备。
  • uni.onBluetoothDeviceFound(callback):监听到新设备时回调,返回如 { devices: [{ deviceId, name, RSSI, advertisData, advertisServiceUUIDs }] }
  • device.deviceId:唯一标识每个 BLE 设备,用于后续连接。
  • 过滤重复设备:微信小程序会多次上报同一设备,需自行去重(如示例中使用 deviceId)。

4.3 停止扫描

  • 一旦找到目标设备并准备连接,应及时调用 uni.stopBluetoothDevicesDiscovery() 停止扫描,否则会一直消耗手机资源和电量。
  • 在页面 onUnload 或用户后退时,也应调用停止扫描,避免扫码界面卸载后仍在后台扫描。

五、连接蓝牙设备并发现服务

扫描到目标设备后,接下来要与该设备建立 BLE 连接,然后发现其提供的服务和特征。

5.1 创建 BLE 连接

进入设备详情页(例如 bluetoothDetail.vue),在页面 onLoad 中获取从列表页传来的 deviceIdname,然后调用 uni.createBLEConnection() 建立连接。

<template>
  <view class="container">
    <text>连接设备:{{ name }}</text>
    <text v-if="connected">已连接</text>
    <text v-else>正在连接...</text>
    <button v-if="connected" @click="getServices">获取服务</button>
    <view v-for="svc in services" :key="svc.uuid" class="service-item">
      <text>服务 UUID:{{ svc.uuid }}</text>
      <button @click="getCharacteristics(svc.uuid)">获取特征</button>
      <view v-for="char in characteristicsList[svc.uuid] || []" :key="char.uuid" class="char-item">
        <text>特征 UUID:{{ char.uuid }}</text>
        <text>properties:{{ JSON.stringify(char.properties) }}</text>
        <!-- 可根据 properties 选择读写/订阅 -->
        <button v-if="char.properties.read" @click="readCharacteristic(svc.uuid, char.uuid)">读取</button>
        <button v-if="char.properties.write" @click="writeCharacteristic(svc.uuid, char.uuid)">写入</button>
        <button v-if="char.properties.notify" @click="notifyCharacteristic(svc.uuid, char.uuid)">订阅通知</button>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      deviceId: '',
      name: '',
      connected: false,
      services: [],
      characteristicsList: {} // 以 serviceUUID 为 key 存储特征列表
    };
  },
  onLoad(options) {
    // options.deviceId 和 options.name 来自扫描页
    this.deviceId = options.deviceId;
    this.name = options.name || '未知设备';
    this.createConnection();
  },
  methods: {
    createConnection() {
      uni.createBLEConnection({
        deviceId: this.deviceId,
        success: (res) => {
          console.log('createBLEConnection success', res);
          this.connected = true;

          // 监听连接状态变化
          uni.onBLEConnectionStateChange((data) => {
            console.log('连接状态 change:', data);
            if (!data.connected) {
              this.connected = false;
              uni.showToast({ title: '设备已断开', icon: 'none' });
            }
          });
        },
        fail: (err) => {
          console.error('createBLEConnection fail', err);
          uni.showToast({ title: '连接失败', icon: 'none' });
        }
      });
    },
    getServices() {
      uni.getBLEDeviceServices({
        deviceId: this.deviceId,
        success: (res) => {
          console.log('getBLEDeviceServices', res);
          this.services = res.services;
        },
        fail: (err) => {
          console.error('getBLEDeviceServices fail', err);
        }
      });
    },
    getCharacteristics(serviceId) {
      uni.getBLEDeviceCharacteristics({
        deviceId: this.deviceId,
        serviceId,
        success: (res) => {
          console.log('getBLEDeviceCharacteristics', res);
          this.$set(this.characteristicsList, serviceId, res.characteristics);
        },
        fail: (err) => {
          console.error('getBLEDeviceCharacteristics fail', err);
        }
      });
    },
    readCharacteristic(serviceId, charId) {
      uni.readBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId,
        characteristicId: charId,
        success: (res) => {
          console.log('read success', res);
          // 监听数据返回
          uni.onBLECharacteristicValueChange((charRes) => {
            console.log('characteristic change', charRes);
            // charRes.value 为 ArrayBuffer
            const data = this.ab2hex(charRes.value);
            console.log('读取到的数据(16进制)', data);
          });
        },
        fail: (err) => {
          console.error('read fail', err);
        }
      });
    },
    writeCharacteristic(serviceId, charId) {
      // 示例:写入一个 0x01 0x02 的 ArrayBuffer 数据到特征
      const buffer = new ArrayBuffer(2);
      const dataView = new DataView(buffer);
      dataView.setUint8(0, 0x01);
      dataView.setUint8(1, 0x02);
      uni.writeBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId,
        characteristicId: charId,
        value: buffer,
        success: (res) => {
          console.log('write success', res);
        },
        fail: (err) => {
          console.error('write fail', err);
        }
      });
    },
    notifyCharacteristic(serviceId, charId) {
      // 开启低功耗设备特征 notifications
      uni.notifyBLECharacteristicValueChange({
        state: true, // true: 启用通知;false: 关闭通知
        deviceId: this.deviceId,
        serviceId,
        characteristicId: charId,
        success: (res) => {
          console.log('notify change success', res);
        },
        fail: (err) => {
          console.error('notify change fail', err);
        }
      });
      // 需监听 onBLECharacteristicValueChange 事件
      uni.onBLECharacteristicValueChange((charRes) => {
        console.log('notify char change', charRes);
        const data = this.ab2hex(charRes.value);
        console.log('notify 数据(16进制)', data);
      });
    },
    // ArrayBuffer 转 hex 字符串,便于调试
    ab2hex(buffer) {
      const hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        (byte) => byte.toString(16).padStart(2, '0')
      );
      return hexArr.join(' ');
    },
    disconnect() {
      uni.closeBLEConnection({
        deviceId: this.deviceId,
        success: () => {
          console.log('已断开连接');
          this.connected = false;
        }
      });
    }
  },
  onUnload() {
    // 页面卸载时断开连接
    if (this.connected) {
      this.disconnect();
    }
  }
};
</script>

<style>
.container {
  padding: 20px;
}
.service-item, .char-item {
  margin-top: 10px;
  padding: 10px;
  border: 1px solid #eee;
}
button {
  margin-top: 5px;
}
</style>

关键说明

  1. uni.createBLEConnection({ deviceId }):对指定 deviceId 建立 BLE 连接,连接成功后才能读写。
  2. uni.onBLEConnectionStateChange(callback):实时监听设备连接状态,如果对方设备断电或超出范围会触发此回调。
  3. uni.getBLEDeviceServices({ deviceId }):获取该设备上所有公开的服务(返回 services: [{ uuid, isPrimary }])。
  4. uni.getBLEDeviceCharacteristics({ deviceId, serviceId }):获取指定服务下的所有特征(返回 characteristics: [{ uuid, properties: { read, write, notify, indicate } }])。
  5. 读写特征

    • 读取:调用 uni.readBLECharacteristicValue({ deviceId, serviceId, characteristicId }) 后,需要再使用 uni.onBLECharacteristicValueChange(callback) 回调才能拿到数据。
    • 写入:调用 uni.writeBLECharacteristicValue({ value: ArrayBuffer });注意写入数据必须是 ArrayBuffer
  6. 订阅特征通知:调用 uni.notifyBLECharacteristicValueChange({ state: true, ... }),然后在 uni.onBLECharacteristicValueChange 中获得服务器推送的变化。
  7. 断开连接uni.closeBLEConnection({ deviceId }),断开后需要调用 uni.closeBluetoothAdapter() 释放蓝牙模块资源(可选)。

六、完整蓝牙流程 ASCII 图解

┌─────────────────────────────────────────────────┐
│               用户打开“蓝牙页”                  │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   1. uni.openBluetoothAdapter()                │
│   └──> 初始化蓝牙模块,开启本机 BLE 适配器      │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   2. uni.startBluetoothDevicesDiscovery()      │
│   └──> 开始扫描附近 BLE 设备                   │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   3. uni.onBluetoothDeviceFound(callback)      │
│   └──> 回调返回扫描到的设备列表 devices[]       │
│       devices 包含 deviceId、name、RSSI 等      │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│       用户从列表中点击 “连接” 某设备            │
│       → 调用 uni.stopBluetoothDevicesDiscovery │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   4. uni.createBLEConnection({ deviceId })     │
│   └──> 与目标设备建立 BLE 连接                  │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   5. uni.onBLEConnectionStateChange(callback)  │
│   └──> 监听连接状态,如断开会触发                │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   6. uni.getBLEDeviceServices({ deviceId })    │
│   └──> 获取设备所有 Service 列表                │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   7. uni.getBLEDeviceCharacteristics({        │
│         deviceId, serviceId })                │
│   └──> 获取该 service 下的所有 Characteristic  │
│           { uuid, properties: { read, write, notify, ... } } │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   8. 读/写/订阅 特征                            │
│   ├─ uni.readBLECharacteristicValue(...)      │
│   │     └─ onBLECharacteristicValueChange     │
│   ├─ uni.writeBLECharacteristicValue(...)     │
│   └─ uni.notifyBLECharacteristicValueChange(..│
│         └─ onBLECharacteristicValueChange     │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│   9. uni.closeBLEConnection({ deviceId })      │
│   └──> 断开与设备连接                           │
└─────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────┐
│  10. uni.closeBluetoothAdapter() (可选)         │
│  └──> 关闭本机蓝牙模块,释放系统资源            │
└─────────────────────────────────────────────────┘

七、常见问题与注意事项

  1. iOS 扫描需打开定位权限

    • iOS 系统要求在使用 BLE 扫描前,必须打开地理位置权限,否则将无法扫描到任何设备。务必在 app.json 中声明 scope.userLocation 并在运行时调用 uni.authorize({ scope: 'scope.userLocation' })
    • 示例:

      uni.authorize({
        scope: 'scope.userLocation',
        success: () => {
          // 已授权,继续扫描
          this.startScan();
        },
        fail: () => {
          uni.showModal({
            title: '提示',
            content: '需要开启定位权限才能扫描蓝牙设备',
            showCancel: false
          });
        }
      });
  2. 重连机制

    • 如果设备断开连接,可监听 uni.onBLEConnectionStateChange,在监听到 connected: false 时尝试重连:

      uni.onBLEConnectionStateChange((res) => {
        if (!res.connected) {
          this.createConnection(); // 最简单的重连策略
        }
      });
    • 注意避免无限重连导致阻塞,可做一定次数或时延后重试。
  3. 写入数据长度限制

    • BLE 单次写入的数据包长度有限制,通常最大约 20 字节(具体取决于设备 MTU)。如果需要写入更大数据,需要自行分包。
    • 示例分包:

      function writeInChunks(deviceId, serviceId, charId, dataBuffer) {
        const mtu = 20; // 一次最大写入 20 字节
        let offset = 0;
        while (offset < dataBuffer.byteLength) {
          const length = Math.min(mtu, dataBuffer.byteLength - offset);
          const chunk = dataBuffer.slice(offset, offset + length);
          uni.writeBLECharacteristicValue({
            deviceId,
            serviceId,
            characteristicId: charId,
            value: chunk
          });
          offset += length;
        }
      }
  4. 订阅特征通知前必须先启用 notify

    • 如果在调用 uni.onBLECharacteristicValueChange 前未调用 uni.notifyBLECharacteristicValueChange({ state: true }),则不会收到变化回调。
  5. 关闭蓝牙时先断开再关闭适配器

    • 调用 uni.closeBLEConnection 后再调用 uni.closeBluetoothAdapter(),否则可能无法正常断开连接。
  6. 不同平台 API 差异

    • 支付宝小程序:方法名为 my.openBluetoothAdaptermy.startBluetoothDevicesDiscovery 等,与微信小程序一致;
    • 百度小程序:对应 swan.openBluetoothAdapterswan.startBluetoothDevicesDiscovery 等;
    • 在 uniapp 中使用 uni.* 封装后自动映射,通常无需区分。
  7. 断电、超距断开提醒

    • 当设备主动断电或超出 BLE 范围时,会触发 onBLEConnectionStateChange,需及时在 UI 上提示用户重新连接。
  8. RSSI(信号强度)过滤

    • onBluetoothDeviceFound 返回的 device.RSSI(信号强度)可以进行过滤,只展示接近的设备:

      if (device.RSSI > -70) {
        // 信号较强的设备,才加入列表
        this.devices.push(device);
      }

八、总结

本文详细介绍了在 uniapp 小程序 中连接 BLE 设备的完整实战流程,从打开蓝牙适配器扫描设备连接设备发现服务与特征、到读写订阅特征断开连接的每一个环节,并提供了丰富的代码示例与 ASCII 流程图,帮助你更清晰地理解蓝牙通信的原理与步骤。

关键要点回顾:

  1. 初始化蓝牙适配器uni.openBluetoothAdapter() 并监听 onBluetoothAdapterStateChange,确保蓝牙可用。
  2. 扫描设备uni.startBluetoothDevicesDiscovery() + uni.onBluetoothDeviceFound,将多个蓝牙设备信息收集到列表,并去重。
  3. 建立 BLE 连接uni.createBLEConnection({ deviceId }),并监听 onBLEConnectionStateChange
  4. 发现服务与特征uni.getBLEDeviceServicesuni.getBLEDeviceCharacteristics,拿到可读写、可订阅的特征。
  5. 数据通信

    • 读取uni.readBLECharacteristicValue() + uni.onBLECharacteristicValueChange
    • 写入uni.writeBLECharacteristicValue(),注意分包;
    • 订阅通知uni.notifyBLECharacteristicValueChange({ state: true }) + uni.onBLECharacteristicValueChange
  6. 断开与清理:页面卸载或用户退出时,先 uni.closeBLEConnection 断开连接,再 uni.closeBluetoothAdapter 关闭适配器,避免资源泄漏。
  7. 权限与异常处理:iOS 需授权定位才能扫描,蓝牙关闭或超距会触发回调;写入需要分包,二维码扫描时也同理。

评论已关闭

推荐阅读

DDPG 模型解析,附Pytorch完整代码
2024年11月24日
DQN 模型解析,附Pytorch完整代码
2024年11月24日
AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日