263 lines
8.4 KiB
C#
263 lines
8.4 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Data;
|
||
using System.Windows.Documents;
|
||
using System.Windows.Input;
|
||
using System.Windows.Markup;
|
||
using System.Windows.Media;
|
||
using System.Windows.Media.Imaging;
|
||
using System.Windows.Navigation;
|
||
using System.Windows.Shapes;
|
||
using System.Windows.Threading;
|
||
using Windows.Devices.Bluetooth.GenericAttributeProfile;
|
||
using WpfBleApp.Ble;
|
||
using WpfBleApp.Model;
|
||
using WpfBleApp.Utils;
|
||
|
||
namespace WpfBleApp
|
||
{
|
||
/// <summary>
|
||
/// 蓝牙通信页面
|
||
/// </summary>
|
||
public partial class CommPage : Page
|
||
{
|
||
private readonly CommPageViewModel ViewModel = new CommPageViewModel();
|
||
private readonly ObservableCollection<string> Logs = new ObservableCollection<string>();
|
||
private int LogCount;
|
||
|
||
bool isSending = false;
|
||
|
||
public CommPage()
|
||
{
|
||
InitializeComponent();
|
||
|
||
listBoxLog.ItemsSource = Logs;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接设备
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void buttonConnect_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
if (ViewModel.BleDevice.IsConnected)
|
||
{
|
||
ViewModel.BleDevice.Disconnect();
|
||
}
|
||
else
|
||
{
|
||
ViewModel.BleDevice.Connect();
|
||
}
|
||
}
|
||
|
||
int[] result = GetRandom(50);
|
||
/// <summary>
|
||
/// 发送数据
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private async void buttonSend_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
if (buttonSend.Content.ToString() == "发送")
|
||
{
|
||
byte[] data = IntArrToByteArr(result);
|
||
|
||
//byte[] data = ViewModel.TxDataHex.ToData();//待发送的数据
|
||
//bool success = await ViewModel.BleDevice.Write(data);
|
||
int time = 2;//间隔
|
||
isSending = true;
|
||
Time_Send(time, data);
|
||
buttonSend.Content = "停止";
|
||
}
|
||
else if (buttonSend.Content.ToString() == "停止")
|
||
{
|
||
isSending = false;
|
||
buttonSend.Content = "发送";
|
||
}
|
||
|
||
|
||
//byte[] data = ViewModel.TxDataHex.ToData();//待发送的数据
|
||
//bool success = await ViewModel.BleDevice.Write(data);
|
||
|
||
//for (int i = 0; i < data.Length; i++)
|
||
//{
|
||
// Console.WriteLine(data[i]);
|
||
//}
|
||
//if (success)
|
||
//{
|
||
// AddLog("发送成功 >>> " + data.ToHex());
|
||
//}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 定时发送数据
|
||
/// </summary>
|
||
/// <param name="time"></param>
|
||
/// <param name="message"></param>
|
||
private async void Time_Send(int time, byte[] message)
|
||
{
|
||
while (isSending)
|
||
{
|
||
//调用发送的那个方法
|
||
bool success = await ViewModel.BleDevice.Write(message);
|
||
if (success)
|
||
{
|
||
AddLog("发送成功 >>> " + message.ToHex());
|
||
}
|
||
//间隔
|
||
await Task.Delay(1000 * time);
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 收到的数据
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="args"></param>
|
||
private void BleDevice_CharacteristicValueChanged(GattCharacteristic sender, byte[] args)
|
||
{
|
||
AddLog($"收到数据 <<< {args.ToHex()}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取设备名称
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private async void buttonRead_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
byte[] data = await ViewModel.BleDevice.Read(Uuids.GenericAccess, Uuids.DeviceName);
|
||
if (data != null)
|
||
{
|
||
AddLog($"读取的设备名称: {Encoding.UTF8.GetString(data)}");
|
||
}
|
||
}
|
||
|
||
public CommPage(BleDevice device) : this()
|
||
{
|
||
ViewModel.BleDevice = device;
|
||
ViewModel.BleDevice.CharacteristicValueChanged += BleDevice_CharacteristicValueChanged;
|
||
ViewModel.BleDevice.ConnectionStateChanged += BleDevice_ConnectionStateChanged;
|
||
DataContext = ViewModel;
|
||
device.Connect();
|
||
}
|
||
|
||
private void BleDevice_ConnectionStateChanged(BleDevice sender, bool args)
|
||
{
|
||
if (args)
|
||
{
|
||
AddLog("连接成功!");
|
||
}
|
||
else
|
||
{
|
||
AddLog("连接已断开!");
|
||
}
|
||
UpdateConnectButton(args);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新连接按钮状态信息
|
||
/// </summary>
|
||
/// <param name="connected"></param>
|
||
private void UpdateConnectButton(bool connected)
|
||
{
|
||
buttonConnect.Dispatcher.Invoke(delegate
|
||
{
|
||
if (connected)
|
||
{
|
||
buttonConnect.Content = "断开连接";
|
||
buttonConnect.Background = new SolidColorBrush(Color.FromRgb(199, 0, 6));
|
||
buttonConnect.Foreground = new SolidColorBrush(Colors.White);
|
||
}
|
||
else
|
||
{
|
||
buttonConnect.Content = "连接设备";
|
||
buttonConnect.Background = new SolidColorBrush(Colors.LightGray);
|
||
buttonConnect.Foreground = new SolidColorBrush(Colors.Black);
|
||
}
|
||
});
|
||
}
|
||
private void AddLog(string msg)
|
||
{
|
||
listBoxLog.Dispatcher.Invoke(delegate
|
||
{
|
||
if (LogCount > 500)
|
||
{
|
||
Logs.RemoveAt(0);
|
||
}
|
||
Logs.Add($"{DateTime.Now:HH:mm:ss.fff} - {msg}");
|
||
LogCount++;
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// int数组转化为byte数组
|
||
/// </summary>
|
||
/// <param name="intArr"></param>
|
||
/// <returns></returns>
|
||
public static byte[] IntArrToByteArr(int[] intArr)
|
||
{
|
||
int intSize = sizeof(int) * intArr.Length;
|
||
byte[] bytArr = new byte[intSize];
|
||
//申请一块非托管内存
|
||
IntPtr ptr = Marshal.AllocHGlobal(intSize);
|
||
//复制int数组到该内存块
|
||
Marshal.Copy(intArr, 0, ptr, intArr.Length);
|
||
//复制回byte数组
|
||
Marshal.Copy(ptr, bytArr, 0, bytArr.Length);
|
||
//释放申请的非托管内存
|
||
Marshal.FreeHGlobal(ptr);
|
||
return bytArr;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得无重复随机数组
|
||
/// </summary>
|
||
/// <param name="n">上限n</param>
|
||
/// <returns>返回随机数组</returns>
|
||
static int[] GetRandom(int n)
|
||
{
|
||
//容器A和B
|
||
int[] arryA = new int[n];
|
||
int[] arryB = new int[n];
|
||
//填充容器a
|
||
for (int i = 0; i < arryA.Length; i++)
|
||
{
|
||
arryA[i] = i + 1;
|
||
}
|
||
//随机对象
|
||
Random r = new Random();
|
||
//最后一个元素的索引 如n=100,end=99
|
||
int end = n - 1;
|
||
for (int i = 0; i < n; i++)
|
||
{
|
||
//生成随机数 因为随机的是索引 所以从0到100取,end=100
|
||
//一个大于等于 minValue 且小于 maxValue 的 32 位带符号整数,即:返回的值范围包括 minValue 但不包括 maxValue。
|
||
//如果 minValue 等于 maxValue,则返回 minValue
|
||
int minValue = 0;
|
||
int maxValue = end + 1;
|
||
int ranIndex = r.Next(minValue, maxValue);
|
||
//把随机数放在容器B中
|
||
arryB[i] = arryA[ranIndex];
|
||
//用最后一个元素覆盖取出的元素
|
||
arryA[ranIndex] = arryA[end];
|
||
//缩减随机数生成的范围
|
||
end--;
|
||
}
|
||
//返回生成的随机数组
|
||
return arryB;
|
||
}
|
||
}
|
||
}
|