20211124_ZNZT_upperpc/WpfBleApp/CommPage.xaml.cs

263 lines
8.4 KiB
C#
Raw Normal View History

2023-02-03 00:31:48 +00:00
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=100end=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;
}
}
}