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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|