返回

如何连接蓝牙串行链路:查找、打开和读取数据

windows

## 蓝牙标准串行链路:查找、连接和读取数据

寻找标准串行蓝牙链路 COM 端口

蓝牙技术广泛应用于无线数据传输,蓝牙模块可以通过标准串行链路在设备之间进行通信。要建立连接,第一步是找到计算机上的标准串行蓝牙链路 COM 端口。

Windows 系统提供了一种方法来识别这些端口:使用 SetupDiGetClassDevs 函数获取设备信息集,并根据特定硬件 ID 筛选出标准串行蓝牙链路 COM 端口。这个硬件 ID 是:

BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000

确定发送 COM 端口

一旦找到所有标准串行蓝牙链路 COM 端口,下一步是确定哪个端口是发送端口。发送端口是蓝牙模块用来传输数据的端口。

要确定发送端口,需要检查每个端口的注册表项。具体来说,需要查找名为 PortName 的注册表值。该值将包含 COM 端口号。

打开端口并读取数据

确定发送端口后,可以使用 Windows API 函数 CreateFile 打开该端口。然后,可以通过 ReadFile 函数读取端口中的数据。

示例代码

以下是 C 语言的示例代码,用于查找标准串行蓝牙链路 COM 端口,并从发送端口读取数据:

#include <stdio.h>
#include <windows.h>

#define GUID_DEVINTERFACE_COMPORT  \
    {0x86e0d1e0,0x8089,0x11d0,{0x9c,0xe4,0x08,0x00,0x2b,0xe1,0x03,0x18}}

int main()
{
    HDEVINFO hDevInfo;
    SP_DEVICE_INTERFACE_DATA devInterfaceData;
    DWORD dwIndex = 0;
    DWORD dwSize;
    HKEY hKey;
    DWORD dwType;
    BYTE lpData[255];
    DWORD dwBytesRead;
    HANDLE hComPort;

    // 获取设备信息集
    hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        printf("SetupDiGetClassDevs failed: %d\n", GetLastError());
        return 1;
    }

    // 遍历设备信息集
    while (SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_COMPORT, dwIndex, &devInterfaceData)) {
        // 获取设备的详细信息
        dwSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, NULL, 0, &dwSize, NULL);
        SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(dwSize);
        devInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, devInterfaceDetailData, dwSize, NULL, NULL);

        // 检查设备的硬件 ID
        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInterfaceData, SPDRP_HARDWAREID, &dwType, lpData, sizeof(lpData), &dwBytesRead)) {
            if (strcmp((char *)lpData, "BTHENUM\\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000") == 0) {
                // 这是标准串行蓝牙链路 COM 端口
                printf("找到标准串行蓝牙链路 COM 端口:%s\n", devInterfaceDetailData->DevicePath);

                // 打开注册表项
                if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, devInterfaceDetailData->DevicePath, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
                    // 读取 PortName 值
                    dwSize = sizeof(lpData);
                    if (RegQueryValueEx(hKey, "PortName", NULL, &dwType, lpData, &dwSize) == ERROR_SUCCESS) {
                        // 这是发送 COM 端口
                        printf("找到发送 COM 端口:%s\n", lpData);

                        // 打开 COM 端口
                        hComPort = CreateFile((char *)lpData, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
                        if (hComPort == INVALID_HANDLE_VALUE) {
                            printf("CreateFile failed: %d\n", GetLastError());
                            return 1;
                        }

                        // 读取 COM 端口中的数据
                        ReadFile(hComPort, lpData, sizeof(lpData), &dwBytesRead, NULL);
                        printf("读取到的数据:%s\n", lpData);

                        // 关闭 COM 端口
                        CloseHandle(hComPort);
                    }

                    // 关闭注册表项
                    RegCloseKey(hKey);
                }
            }
        }

        // 释放设备详细信息
        free(devInterfaceDetailData);

        // 继续遍历
        dwIndex++;
    }

    // 关闭设备信息集
    SetupDiDestroyDeviceInfoList(hDevInfo);

    return 0;
}

常见问题解答

1. 我找不到任何标准串行蓝牙链路 COM 端口,怎么办?

  • 确保蓝牙模块已连接到计算机并已打开。
  • 检查模块的硬件 ID 是否与上面提供的 ID 匹配。
  • 尝试重新安装蓝牙驱动程序。

2. 我找到了标准串行蓝牙链路 COM 端口,但找不到发送端口,怎么办?

  • 检查注册表中的 PortName 值是否不存在或为空。
  • 尝试使用不同的蓝牙模块或计算机。

3. 我成功打开了 COM 端口,但无法读取数据,怎么办?

  • 确保蓝牙模块正在发送数据。
  • 检查端口设置是否正确(波特率、数据位、停止位、奇偶校验)。
  • 尝试使用不同的蓝牙软件或应用程序。

4. 我可以同时连接到多个蓝牙设备吗?

  • 是的,Windows 系统支持同时连接到多个蓝牙设备。

5. 蓝牙传输数据的最大距离是多少?

  • 蓝牙的传输距离取决于蓝牙模块的类型和环境条件,通常在 10 到 100 米之间。