利用ESP32来模拟BT蓝牙(BLE低功耗蓝牙后续也会进行测试)

C#利用32feet.NET库来实现蓝牙的使用。

(1)初始化扫描蓝牙设备写入选择框

(2)连接蓝牙设备,连接成功则开启监听线程

(3)监听线程接收到数据设置回调函数将接收到的内容显示在文本框上。

(4)点击发送按钮后将文本框的内容发送给接收端。

private async void Booth_Init()
{
    try
    {
        client = new BluetoothClient();
        // 使用 Task.Run 来在另一个线程中执行 DiscoverDevices
        devices = await Task.Run(() => client.DiscoverDevices());
        BoothChoose.Items.Clear();
        foreach (BluetoothDeviceInfo device in devices)
        {
            // 确保 UI 更新在 UI 线程上执行
            this.Invoke((MethodInvoker)delegate
            {
                BoothChoose.Items.Add(device.DeviceName);
            });

            Console.WriteLine(device.DeviceName);
        }

        // 确保在 UI 线程上修改 SelectedIndex
        this.Invoke((MethodInvoker)delegate
        {
            if (BoothChoose.Items.Count > 0)
            {
                BoothChoose.SelectedIndex = 0;
            }
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine("错误: " + ex.Message);
    }
}

初始化的代码是使用异步的方式扫描设备,并且将设备名称显示在选择控件上,之所以是采用异步的方式原因是不采用异步会占用UI线程导致UI线程无法使用。所以需要单独开线程来初始化,同时该函数也可以用于重新扫描设备。

蓝牙连接

private async void BoothConnect()
{
    try
    {
        if (BoothChoose.Items.Count != 0)
        {
            string selectedDeviceName = BoothChoose.SelectedItem.ToString();

            // 寻找匹配的设备
            BluetoothDeviceInfo deviceToConnect = devices.FirstOrDefault(d => d.DeviceName == selectedDeviceName);
            if (deviceToConnect != null)
            {
                // 连接到设备
                await Task.Run(() => client.Connect(deviceToConnect.DeviceAddress, BluetoothService.SerialPort));
                MessageBox.Show("连接成功", "信息");
                if (client.Connected)
                {
                    stream = client.GetStream();
                    StartListening(OnDataReceived); // 开始监听数据并指定回调
                }
            }
            else
            {
                MessageBox.Show("未找到选定的设备", "警告");
            }
        }
        else
        {
            MessageBox.Show("未检测到设备", "警告");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("蓝牙连接失败: " + ex.Message, "错误");
    }
}

连接蓝牙的代码,根据选择控件选择的蓝牙名称匹配对应的蓝牙设别,接着使用异步的方式来连接蓝牙,防止连接蓝牙的过程中导致UI线程卡顿无法使用。

并且使用一个Stream流变量来接收蓝牙传输的信息,调用StartListening函数来实现蓝牙设备的监听

监听函数

private void StartListening(Action<string> callback)
{
    Task.Run(() =>
    {
        byte[] buffer = new byte[1024]; // 数据缓冲区
        int bytes;

        try
        {
            while (client.Connected)
            {
                bytes = stream.Read(buffer, 0, buffer.Length);
                if (bytes > 0)
                {
                    string receivedData = Encoding.UTF8.GetString(buffer, 0, bytes);
                    this.Invoke((MethodInvoker)delegate
                    {
                        callback(receivedData); // 在UI线程上调用回调
                    });
                }
            }
        }
        catch (IOException ex)
        {
            // 连接丢失或读取错误
            this.Invoke((MethodInvoker)delegate
            {
                MessageBox.Show("读取数据错误: " + ex.Message, "错误");
            });
        }
    });
}

private void OnDataReceived(string data)
{
    if (Receive.InvokeRequired)
    {
        // 如果调用线程不是创建Receive控件的线程,则使用Invoke调用
        Receive.Invoke(new MethodInvoker(delegate
        {
            Receive.AppendText(data);
        }));
    }
    else
    {
        // 如果已经在UI线程,则直接更新
        Receive.AppendText(data);
    }
}

监听函数中我们异步监听数据,并且设置OnDataReceived回调函数处理接收到的数据。

发送数据

private void TransButton_Click(object sender, EventArgs e)
{
    try
    {
        // 获取要发送的文本
        string dataToSend = TransText.Text;
        if (NewLine.Checked)
        {
            dataToSend += Environment.NewLine;
        }
        if (client != null && client.Connected)
        {
            Stream stream = client.GetStream();
            if (stream.CanWrite)
            {
                // 将文本转换为字节数据
                byte[] buffer = Encoding.UTF8.GetBytes(dataToSend);
                // 发送数据
                stream.Write(buffer, 0, buffer.Length);
            }
        }
        else
        {
            MessageBox.Show("Bluetooth is not connected.");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error sending data: " + ex.Message);
    }
}