利用ESP32來模擬BT藍牙(BLE低功耗藍牙后續也會進行測試)
這個界面基本也是搬運至前面的串口助手界面,目前制作了發送和接收界面。并且代碼邏輯也比較簡單,還需要有很大的修改。(3)監聽線程接收到數據設置回調函數將接收到的內容顯示在文本框上。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);
}
}
該文章在 2024/1/31 15:49:23 編輯過