利用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);
}
}