-
参考: https://blog.csdn.net/shengfakun1234/article/details/110928783
-
参考: https://blog.csdn.net/code_long/article/details/105636398?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control
-
参考: https://docs.microsoft.com/zh-cn/windows/uwp/devices-sensors/gatt-client?redirectedfrom=MSDN
-
参考: https://github.com/NaBian/HandyControl
-
当进行穿戴设备的调试的时候, 往往需要从穿戴设备采集数据, 使用手机采集数据然后导入到电脑上, 在调试的时候总是感觉不太方便, 于是有了这个的出现;
-
成品:
-
Nuget:
+XAML:
<hc:Window x:Class="SystemManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:d3="clr-namespace:InteractiveDataDisplay.WPF;assembly=InteractiveDataDisplay.WPF"
mc:Ignorable="d"
Title="BltReceivedDataShow"
WindowStartupLocation="CenterScreen"
Style="{StaticResource WindowWin10}"
ShowTitle="True"
Height="700"
Width="1200"
FontFamily="Consolas-with-Yahei" FontStyle="Italic">
<Grid>
<hc:TabControl x:Name="MainWindowsTabControl_Handle"
IsAnimationEnabled="True"
ShowCloseButton="False"
IsDraggable="False"
IsTabFillEnabled="True"
SelectionChanged="TabControl_SelectionChanged">
<hc:TabItem x:Name="TabItemListBltDevicesPage" Header="Devices">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Button x:Name="FirstTabFindBltButton" hc:BorderElement.CornerRadius="5"
Height="30" Width="300"
Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="5"
Content="Find"
Click="FirstTabFindBleDevicesButton_Click"
Visibility="Visible" />
<ListView x:Name="FirstTabShowBltDevicesListView"
ItemsSource="{Binding DataList}"
Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="5" Grid.RowSpan="12"
PreviewMouseLeftButtonDown="ListViewItem_PreviewMouseLeftButtonDown"
PreviewMouseDoubleClick="ListViewItem_PreviewMouseDoubleClick"
Visibility="Visible">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding="{Binding Path=DevicesName}" Header="DevicesName" Width="350"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=DevicesMac}" Header="DevicesMac" Width="500"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</hc:TabItem>
<hc:TabItem x:Name="TabItemListBleDevicesServicesPage" Header="Services">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<ListView x:Name="SecTabShowBltDevicesServicesListView"
ItemsSource="{Binding DataList}"
Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="5" Grid.RowSpan="6"
PreviewMouseLeftButtonDown="ServicesListViewItem_PreviewMouseLeftButtonDown"
PreviewMouseDoubleClick="ServicesListViewItem_PreviewMouseDoubleClick"
Visibility="Visible">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding="{Binding Path=ServicesName}" Header="ServicesName" Width="350"/>
</GridView>
</ListView.View>
</ListView>
<ListView x:Name="SecTabShowServicesCharacteristicsListView"
ItemsSource="{Binding DataList}"
Grid.Column="1" Grid.Row="8" Grid.ColumnSpan="5" Grid.RowSpan="6"
PreviewMouseLeftButtonDown="CharacteristicsListViewItem_PreviewMouseLeftButtonDown"
PreviewMouseDoubleClick="CharacteristicsListViewItem_PreviewMouseDoubleClick"
Visibility="Visible">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Employee Information">
<GridViewColumn DisplayMemberBinding="{Binding Path=CharacteristicsName}" Header="CharacteristicsName" Width="350"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=PropertiesVal}" Header="PropertiesVal" Width="500"/>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="SecTabSettingWriteChaButton" hc:BorderElement.CornerRadius="15"
Height="30" Width="200"
Grid.Column="6" Grid.Row="9" Grid.ColumnSpan="1"
Content="Setting Write"
Click="SecTabSettingWriteChaButton_Click"
Visibility="Visible" />
<Button x:Name="SecTabSettingReadChaButton" hc:BorderElement.CornerRadius="15"
Height="30" Width="200"
Grid.Column="6" Grid.Row="10" Grid.ColumnSpan="5"
Content="Setting Read"
Click="SecTabSettingReadChaButton_Click"
Visibility="Visible" />
<Button x:Name="SecTabSettingNotifiedChaButton" hc:BorderElement.CornerRadius="15"
Height="30" Width="200"
Grid.Column="6" Grid.Row="11" Grid.ColumnSpan="5"
Content="Setting Notified"
Click="SecTabSettingNotifiedChaButton_Click"
Visibility="Visible" />
</Grid>
</hc:TabItem>
<hc:TabItem x:Name="TabItemBleWriteAndNotifiedDataPage" Header="Communication">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TextBox x:Name="SendMsgToDevices_TextBox"
Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="1"
Height="30"
Style="{StaticResource TextBoxExtend}"
hc:InfoElement.Title="Data :"
hc:InfoElement.TitlePlacement="Left"
VerticalAlignment="Center"
Cursor="IBeam"
Visibility="Visible"/>
<Button x:Name="SendMsgToDevices_Button1" hc:BorderElement.CornerRadius="5"
Height="30" Width="300"
Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="Check Send"
Click="SendMsgToDevicesButton1_Click"
Visibility="Visible" />
<TextBlock x:Name="ShowBleReceivedDataTextBox"
Grid.Column="0" Grid.Row="15" Grid.ColumnSpan="7" Grid.RowSpan="1"
hc:InfoElement.TitlePlacement="Left"
VerticalAlignment="Center"
Visibility="Visible"/>
<Button x:Name="DisableBleNotified_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="0" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="Disabled Notified"
Click="DisableBleNotifiedButton_Click"
Visibility="Visible" />
<Button x:Name="EnableBleNotified_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="1" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="Enabled Notified"
Click="EnableBleNotifiedButton_Click"
Visibility="Visible" />
<Button x:Name="AxisOpenGseDataShowMode_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="3" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="AllowAxisGseData"
Click="AxisOpenGseDataShowModeButton_Click"
Visibility="Visible" />
<Button x:Name="AxisOpenPpgGreDataShowMode_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="4" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="AllowAxisPpgGreData"
Click="AxisOpenPpgGreDataShowModeButton_Click"
Visibility="Visible" />
<Button x:Name="AxisOpenPpgRedDataShowMode_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="5" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="AllowAxisPpgRedData"
Click="AxisOpenPpgRedDataShowModeButton_Click"
Visibility="Visible" />
<Button x:Name="AxisOpenEcgDataShowMode_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="6" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="AllowAxisEcgData"
Click="AxisOpenEcgDataShowModeButton_Click"
Visibility="Visible" />
<Button x:Name="AxisOpenPwttDataShowMode_Button" hc:BorderElement.CornerRadius="5"
Height="30" Width="150"
Grid.Column="6" Grid.Row="7" Grid.ColumnSpan="1" Grid.RowSpan="1"
Content="AllowAxisPwttData"
Click="AxisOpenPwttDataShowModeButton_Click"
Visibility="Visible" />
<d3:Chart x:Name="GseDataPlotAxis" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="13" Visibility="Collapsed">
<Grid Name="GseDataPlotAxisN"/>
</d3:Chart>
<d3:Chart x:Name="PpgGreDataPlotAxis" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="13" Visibility="Collapsed">
<Grid Name="PpgGreDataPlotAxisN"/>
</d3:Chart>
<d3:Chart x:Name="PpgRedIrdAmbDataPlotAxis" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="13" Visibility="Collapsed">
<Grid Name="PpgRedIrdAmbDataPlotAxisN"/>
</d3:Chart>
<d3:Chart x:Name="EcgDataPlotAxis" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="13" Visibility="Collapsed">
<Grid Name="EcgDataPlotAxisN"/>
</d3:Chart>
<d3:Chart x:Name="PwttEcgDataPlotAxis" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="6" Visibility="Visible">
<Grid Name="PwttEcgDataPlotAxisN"/>
</d3:Chart>
<d3:Chart x:Name="PwttPpgDataPlotAxis" Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="6" Grid.RowSpan="6" Visibility="Visible">
<Grid Name="PwttPpgDataPlotAxisN"/>
</d3:Chart>
</Grid>
</hc:TabItem>
</hc:TabControl>
<hc:ScrollViewer
VerticalScrollBarVisibility="Auto" HorizontalAlignment="left" IsHitTestVisible="False">
<StackPanel
hc:Growl.Token="SuccessMsg"
hc:Growl.GrowlParent="True" VerticalAlignment="Bottom" Margin="0,10,10,10" />
</hc:ScrollViewer>
<hc:ScrollViewer
VerticalScrollBarVisibility="Auto" HorizontalAlignment="left" IsHitTestVisible="False">
<StackPanel
hc:Growl.Token="InfoMsg"
hc:Growl.GrowlParent="True" VerticalAlignment="Bottom" Margin="0,10,10,10" />
</hc:ScrollViewer>
<hc:ScrollViewer
VerticalScrollBarVisibility="Auto" HorizontalAlignment="left" IsHitTestVisible="False">
<StackPanel
hc:Growl.Token="WarningMsg"
hc:Growl.GrowlParent="True" VerticalAlignment="Bottom" Margin="0,10,10,10" />
</hc:ScrollViewer>
<hc:ScrollViewer
VerticalScrollBarVisibility="Auto" HorizontalAlignment="left" IsHitTestVisible="False">
<StackPanel
hc:Growl.Token="ErrorMsg"
hc:Growl.GrowlParent="True" VerticalAlignment="Bottom" Margin="0,10,10,10" />
</hc:ScrollViewer>
</Grid>
</hc:Window>
- c#:
using System;
using System.IO;
using System.Data;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Runtime.InteropServices;
using HandyControl.Controls;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using InteractiveDataDisplay.WPF;
using System.Collections;
using System.ComponentModel;
using System.Windows.Data;
using System.Diagnostics;
using InTheHand.Net.Sockets;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.IrDA;
using InTheHand.Net.Mime;
using InTheHand.Net.Ports;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using System.Linq;
using Windows.Foundation;
using System.Windows.Media;
using Windows.Networking;
using Windows.Networking.Proximity;
using Windows.Networking.Sockets;
using Windows.Security.Cryptography;
using Windows.Storage.Streams;
using Windows.Devices.Bluetooth.Advertisement;
delegate object obj_delegate();
namespace SystemManager
{
public partial class MainWindow
{
public struct AllDevicesMac
{
public int ID { get; set; }
public string DevicesMacToSave { get; set; }
}
public struct AllDevicesServices
{
public int ID { get; set; }
public GattDeviceService ServicesToSave { get; set; }
}
public struct AllCharacteristics
{
public int ID { get; set; }
public GattCharacteristic CharacteristicsToSave { get; set; }
}
private BluetoothLEAdvertisementWatcher deviceWatcher;
private int characteristics_current_select_index = 0;
public BluetoothLEDevice CurrentDevice { get; set; }
public GattDeviceService CurrentService { get; set; }
public GattCharacteristic SaveToWriteCharac { get; set; }
public GattCharacteristic SaveToReadCharac { get; set; }
public GattCharacteristic SaveToNotifiedCharac { get; set; }
int gse_chart_need_refresh_flag = 0;
int ppggre_chart_need_refresh_flag = 0;
int ppgred_chart_need_refresh_flag = 0;
const int ecg_data_len = 512 * 6;
const int ppg_data_len = 50 * 6;
const int gse_data_len = 50 * 6;
float[] gse_data_x = new float[gse_data_len];
float[] gsex_data = new float[gse_data_len];
float[] gsey_data = new float[gse_data_len];
float[] gsez_data = new float[gse_data_len];
float[] ppg_data_x = new float[ppg_data_len];
float[] ppggre1_data = new float[ppg_data_len];
float[] ppggre2_data = new float[ppg_data_len];
float[] ppggre3_data = new float[ppg_data_len];
float[] ppgred1_data = new float[ppg_data_len];
float[] ppgred2_data = new float[ppg_data_len];
float[] ppgired_data = new float[ppg_data_len];
float[] ppgambi_data = new float[ppg_data_len];
LineGraph gsex_lg = new LineGraph();
LineGraph gsey_lg = new LineGraph();
LineGraph gsez_lg = new LineGraph();
LineGraph ppggre1_lg = new LineGraph();
LineGraph ppggre2_lg = new LineGraph();
LineGraph ppggre3_lg = new LineGraph();
LineGraph ppgred1_lg = new LineGraph();
LineGraph ppgred2_lg = new LineGraph();
LineGraph ppgired_lg = new LineGraph();
LineGraph ppgambi_lg = new LineGraph();
List<Windows.Devices.Bluetooth.BluetoothLEDevice> DeviceList = new List<Windows.Devices.Bluetooth.BluetoothLEDevice>();
List<AllDevicesMac> DevicesMacListSaveToCompare = new List<AllDevicesMac>();
AllDevicesMac snap_save_all_devicesmac_s = new AllDevicesMac();
List<AllDevicesServices> ServicesListSaveToChoose = new List<AllDevicesServices>();
//AllDevicesMac snap_save_all_devicesmac_s = new AllDevicesMac();
List<AllCharacteristics> CharacteristicsListSaveToChoose = new List<AllCharacteristics>();
public MainWindow()
{
InitializeComponent();
gse_chart_need_refresh_flag = 0;
ppggre_chart_need_refresh_flag = 0;
GseData_PlotInit();
GseData_PlotLineStart();
PpgGreData_PlotInit();
PpgGreData_PlotLineStart();
PpgRedData_PlotInit();
PpgRedData_PlotLineStart();
GseDataPlotAxis.Visibility = Visibility.Visible;
PpgGreDataPlotAxis.Visibility = Visibility.Collapsed;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Collapsed;
EcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttEcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttPpgDataPlotAxis.Visibility = Visibility.Collapsed;
DataContext = this;
}
public void GseData_PlotInit()
{
for (int i = 0; i < gse_data_len; i++)
{
gse_data_x[i] = i - 299.0f;
}
GseDataPlotAxisN.Children.Add(gsex_lg);
GseDataPlotAxisN.Children.Add(gsey_lg);
GseDataPlotAxisN.Children.Add(gsez_lg);
gsex_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
gsex_lg.Description = String.Format("GseX");
gsex_lg.StrokeThickness = 2;
gsex_lg.Plot(gse_data_x, gsex_data);
gsey_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
gsey_lg.Description = String.Format("GseY");
gsey_lg.StrokeThickness = 2;
gsey_lg.Plot(gse_data_x, gsey_data);
gsez_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 200, 200, 200));
gsez_lg.Description = String.Format("GseZ");
gsez_lg.StrokeThickness = 2;
gsez_lg.Plot(gse_data_x, gsez_data);
}
public void GseData_PlotLineStart()
{
Task.Run(() =>
{
while (gse_chart_need_refresh_flag == 1)
{
//Thread.Sleep(1000);
gse_chart_need_refresh_flag = 0;
Application.Current.Dispatcher.Invoke(() =>
{
//更新纵坐标数据
gsex_lg.Plot(gse_data_x, gsex_data);
gsey_lg.Plot(gse_data_x, gsey_data);
gsez_lg.Plot(gse_data_x, gsez_data);
});
}
});
}
public void PpgGreData_PlotInit()
{
for (int i = 0; i < ppg_data_len; i++)
{
ppg_data_x[i] = i - 299.0f;
}
PpgGreDataPlotAxisN.Children.Add(ppggre1_lg);
PpgGreDataPlotAxisN.Children.Add(ppggre2_lg);
PpgGreDataPlotAxisN.Children.Add(ppggre3_lg);
ppggre1_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
ppggre1_lg.Description = String.Format("Gre1");
ppggre1_lg.StrokeThickness = 2;
ppggre1_lg.Plot(ppg_data_x, ppggre1_data);
ppggre2_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
ppggre2_lg.Description = String.Format("Gre2");
ppggre2_lg.StrokeThickness = 2;
ppggre2_lg.Plot(ppg_data_x, ppggre2_data);
ppggre3_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 200, 200, 200));
ppggre3_lg.Description = String.Format("Gre3");
ppggre3_lg.StrokeThickness = 2;
ppggre3_lg.Plot(ppg_data_x, ppggre3_data);
}
public void PpgGreData_PlotLineStart()
{
Task.Run(() =>
{
while (ppggre_chart_need_refresh_flag == 1)
{
//Thread.Sleep(1000);
ppggre_chart_need_refresh_flag = 0;
Application.Current.Dispatcher.Invoke(() =>
{
//更新纵坐标数据
ppggre1_lg.Plot(ppg_data_x, ppggre1_data);
ppggre2_lg.Plot(ppg_data_x, ppggre2_data);
ppggre3_lg.Plot(ppg_data_x, ppggre3_data);
});
}
});
}
public void PpgRedData_PlotInit()
{
for (int i = 0; i < ppg_data_len; i++)
{
ppg_data_x[i] = i - 299.0f;
}
PpgRedIrdAmbDataPlotAxisN.Children.Add(ppgred1_lg);
PpgRedIrdAmbDataPlotAxisN.Children.Add(ppgred2_lg);
PpgRedIrdAmbDataPlotAxisN.Children.Add(ppgired_lg);
PpgRedIrdAmbDataPlotAxisN.Children.Add(ppgambi_lg);
ppgred1_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
ppgred1_lg.Description = String.Format("Red1");
ppgred1_lg.StrokeThickness = 2;
ppgred1_lg.Plot(ppg_data_x, ppgred1_data);
ppgred2_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));
ppgred2_lg.Description = String.Format("Red2");
ppgred2_lg.StrokeThickness = 2;
ppgred2_lg.Plot(ppg_data_x, ppgred2_data);
ppgired_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
ppgired_lg.Description = String.Format("Ired");
ppgired_lg.StrokeThickness = 2;
ppgired_lg.Plot(ppg_data_x, ppgired_data);
ppgambi_lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 200, 200, 200));
ppgambi_lg.Description = String.Format("Ambi");
ppgambi_lg.StrokeThickness = 2;
ppgambi_lg.Plot(ppg_data_x, ppgambi_data);
}
public void PpgRedData_PlotLineStart()
{
Task.Run(() =>
{
while (ppgred_chart_need_refresh_flag == 1)
{
//Thread.Sleep(1000);
ppgred_chart_need_refresh_flag = 0;
Application.Current.Dispatcher.Invoke(() =>
{
//更新纵坐标数据
ppgred1_lg.Plot(ppg_data_x, ppgred1_data);
ppgred2_lg.Plot(ppg_data_x, ppgred2_data);
ppgired_lg.Plot(ppg_data_x, ppgired_data);
ppgambi_lg.Plot(ppg_data_x, ppgambi_data);
});
}
});
}
private void DeviceWatcher_Received(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher sender, Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementReceivedEventArgs args)
{
BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
if (asyncInfo.GetResults() != null)
{
BluetoothLEDevice currentDevice = asyncInfo.GetResults();
Boolean contain = false;
Dispatcher.Invoke(new Action(
delegate
{
foreach (BluetoothLEDevice device in DeviceList)
{
if (device.DeviceId == currentDevice.DeviceId)
{
contain = true;
}
}
if (!contain)
{
byte[] _Bytes1 = BitConverter.GetBytes(currentDevice.BluetoothAddress);
Array.Reverse(_Bytes1);
Growl.Info("发现设备并添加列表", "InfoMsg");
snap_save_all_devicesmac_s.DevicesMacToSave = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToUpper();
DevicesMacListSaveToCompare.Add(snap_save_all_devicesmac_s);
snap_save_all_devicesmac_s.ID = snap_save_all_devicesmac_s.ID + 1;
DeviceList.Add(currentDevice);
FirstTabShowBltDevicesListView.Items.Add(
new { DevicesName = currentDevice.Name, DevicesMac = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToUpper() });
}
}
));
}
}
};
}
public void StartBleDeviceWatcher()
{
deviceWatcher = new Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher();
deviceWatcher.ScanningMode = Windows.Devices.Bluetooth.Advertisement.BluetoothLEScanningMode.Active;
deviceWatcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;
deviceWatcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;
deviceWatcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
deviceWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);
deviceWatcher.Received += DeviceWatcher_Received;
deviceWatcher.Start();
Growl.Info(" 自动发现设备中..", "InfoMsg");
}
public async Task ShowDevicesAllServices()
{
CurrentDevice.GetGattServicesAsync().Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
var services = asyncInfo.GetResults().Services;
Dispatcher.Invoke(new Action(
delegate
{
AllDevicesServices snap_save_all_services_s = new AllDevicesServices();
snap_save_all_services_s.ID = 0;
foreach (GattDeviceService ser in services)
{
snap_save_all_services_s.ServicesToSave = ser;
ServicesListSaveToChoose.Add(snap_save_all_services_s);
snap_save_all_services_s.ID++;
SecTabShowBltDevicesServicesListView.Items.Add(new { ServicesName = ser.Uuid.ToString() });
}
}));
}
};
}
private void FirstTabFindBleDevicesButton_Click(object sender, RoutedEventArgs e)
{
FirstTabShowBltDevicesListView.Items.Clear();
SecTabShowBltDevicesServicesListView.Items.Clear();
DeviceList.Clear();
DevicesMacListSaveToCompare.Clear();
ServicesListSaveToChoose.Clear();
snap_save_all_devicesmac_s.ID = 0;
characteristics_current_select_index = 0;
StartBleDeviceWatcher();
}
private void SecTabSettingWriteChaButton_Click(object sender, RoutedEventArgs e)
{
if (characteristics_current_select_index == -1)
{
Growl.Info("未选中, 请双击选中", "ErrorMsg");
return;
}
SaveToWriteCharac = CharacteristicsListSaveToChoose[characteristics_current_select_index].CharacteristicsToSave;
Growl.Info("写入特征设置为:\n" + SaveToWriteCharac.Uuid.ToString(), "InfoMsg");
}
private void SecTabSettingReadChaButton_Click(object sender, RoutedEventArgs e)
{
if (characteristics_current_select_index == -1)
{
Growl.Info("未选中, 请双击选中", "ErrorMsg");
return;
}
SaveToReadCharac = CharacteristicsListSaveToChoose[characteristics_current_select_index].CharacteristicsToSave;
Growl.Info("读取特征设置为:\n" + SaveToReadCharac.Uuid.ToString(), "InfoMsg");
}
private async void SecTabSettingNotifiedChaButton_Click(object sender, RoutedEventArgs e)
{
if (characteristics_current_select_index == -1)
{
Growl.Info("未选中, 请双击选中", "ErrorMsg");
return;
}
SaveToNotifiedCharac = CharacteristicsListSaveToChoose[characteristics_current_select_index].CharacteristicsToSave;
Growl.Info("订阅特征设置为:\n" + SaveToNotifiedCharac.Uuid.ToString(), "InfoMsg");
SaveToNotifiedCharac.ValueChanged += Characteristic_ValueChanged;
}
private async void EnableBleNotifiedButton_Click(object sender, RoutedEventArgs e)
{
GattCommunicationStatus status = await SaveToNotifiedCharac.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
if (status == GattCommunicationStatus.Success)
{
// Server has been informed of clients interest.
}
}
private async void DisableBleNotifiedButton_Click(object sender, RoutedEventArgs e)
{
GattCommunicationStatus status = await SaveToNotifiedCharac.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.None);
if (status == GattCommunicationStatus.Success)
{
// Server has been informed of clients interest.
}
}
private async void AxisOpenGseDataShowModeButton_Click(object sender, RoutedEventArgs e)
{
GseDataPlotAxis.Visibility = Visibility.Visible;
PpgGreDataPlotAxis.Visibility = Visibility.Collapsed;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Collapsed;
EcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttEcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttPpgDataPlotAxis.Visibility = Visibility.Collapsed;
if(SaveToWriteCharac != null)
{
var writer = new DataWriter();
byte[] returnBytes = new byte[6];
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x70;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x10;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
}
}
private async void AxisOpenPpgGreDataShowModeButton_Click(object sender, RoutedEventArgs e)
{
GseDataPlotAxis.Visibility = Visibility.Collapsed;
PpgGreDataPlotAxis.Visibility = Visibility.Visible;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Collapsed;
EcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttEcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttPpgDataPlotAxis.Visibility = Visibility.Collapsed;
if (SaveToWriteCharac != null)
{
var writer = new DataWriter();
byte[] returnBytes = new byte[6];
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x70;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x20;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
}
}
private async void AxisOpenPpgRedDataShowModeButton_Click(object sender, RoutedEventArgs e)
{
GseDataPlotAxis.Visibility = Visibility.Collapsed;
PpgGreDataPlotAxis.Visibility = Visibility.Collapsed;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Visible;
EcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttEcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttPpgDataPlotAxis.Visibility = Visibility.Collapsed;
if (SaveToWriteCharac != null)
{
var writer = new DataWriter();
byte[] returnBytes = new byte[6];
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x70;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x20;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
}
}
private async void AxisOpenEcgDataShowModeButton_Click(object sender, RoutedEventArgs e)
{
GseDataPlotAxis.Visibility = Visibility.Collapsed;
PpgGreDataPlotAxis.Visibility = Visibility.Collapsed;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Collapsed;
EcgDataPlotAxis.Visibility = Visibility.Visible;
PwttEcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttPpgDataPlotAxis.Visibility = Visibility.Collapsed;
if (SaveToWriteCharac != null)
{
var writer = new DataWriter();
byte[] returnBytes = new byte[6];
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x70;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
returnBytes[0] = 0x47;
returnBytes[1] = 0x53;
returnBytes[2] = 0xFF;
returnBytes[3] = 0x20;
returnBytes[4] = 0x58;
returnBytes[5] = 0x54;
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
}
}
private async void AxisOpenPwttDataShowModeButton_Click(object sender, RoutedEventArgs e)
{
GseDataPlotAxis.Visibility = Visibility.Collapsed;
PpgGreDataPlotAxis.Visibility = Visibility.Collapsed;
PpgRedIrdAmbDataPlotAxis.Visibility = Visibility.Collapsed;
EcgDataPlotAxis.Visibility = Visibility.Collapsed;
PwttEcgDataPlotAxis.Visibility = Visibility.Visible;
PwttPpgDataPlotAxis.Visibility = Visibility.Visible;
}
private void ServicesListViewItem_PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
}
//
private void CharacteristicsListViewItem_PreviewMouseDoubleClick(object sender, RoutedEventArgs e)
{
characteristics_current_select_index = 0;
characteristics_current_select_index = (sender as ListView).SelectedIndex;
Growl.Info("双击选中行号:\n" + characteristics_current_select_index.ToString(), "InfoMsg");
}
private void CharacteristicsListViewItem_PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
characteristics_current_select_index = 0;
characteristics_current_select_index = (sender as ListView).SelectedIndex;
Growl.Info("单击选中行号:\n" + characteristics_current_select_index.ToString(), "InfoMsg");
}
private void ServicesListViewItem_PreviewMouseDoubleClick(object sender, RoutedEventArgs e)
{
var item = (sender as ListView).SelectedItem;
var selectec_id = (sender as ListView).SelectedIndex;
if (item != null)
{
ServicesListSaveToChoose[selectec_id].ServicesToSave.GetCharacteristicsAsync().Completed = (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
var characteristics = asyncInfo.GetResults().Characteristics;
Dispatcher.Invoke(new Action(
delegate
{
characteristics_current_select_index = 0;
SecTabShowServicesCharacteristicsListView.Items.Clear();
CharacteristicsListSaveToChoose.Clear();
AllCharacteristics snap_save_all_charactertics_s = new AllCharacteristics();
snap_save_all_charactertics_s.ID = 0;
foreach (var charac in characteristics)
{
snap_save_all_charactertics_s.CharacteristicsToSave = charac;
CharacteristicsListSaveToChoose.Add(snap_save_all_charactertics_s);
snap_save_all_charactertics_s.ID++;
SecTabShowServicesCharacteristicsListView.Items.Add(new { CharacteristicsName = charac.Uuid.ToString(), PropertiesVal = charac.CharacteristicProperties.ToString() });
}
}));
}
};
}
}
private void ListViewItem_PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
}
private async Task ConnectDevice(DeviceInformation deviceInfo)
{
// Note: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent.
BluetoothLEDevice.FromIdAsync(deviceInfo.Id).Completed = async (asyncInfo, asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Completed)
{
BluetoothLEDevice bleDevice = asyncInfo.GetResults();
Growl.Info("Devices 连接成功", "InfoMsg");
deviceWatcher.Stop();
Dispatcher.Invoke(new Action(
delegate
{
MainWindowsTabControl_Handle.SelectedIndex = 1;
}));
await ShowDevicesAllServices();
}
};
}
[Obsolete]
private async void ListViewItem_PreviewMouseDoubleClick(object sender, RoutedEventArgs e)
{
var item = (sender as ListView).SelectedItem;
var selectec_id = (sender as ListView).SelectedIndex;
if (item != null)
{
var DevicesMac = DeviceList[selectec_id].DeviceId;
Windows.Devices.Bluetooth.BluetoothLEDevice bluetoothLEDevice = DeviceList.Where(u => u.DeviceId == DevicesMac).FirstOrDefault();
if (bluetoothLEDevice != null)
{
if (bluetoothLEDevice.ConnectionStatus == BluetoothConnectionStatus.Disconnected)
{
CurrentDevice = DeviceList[selectec_id];
await ConnectDevice(DeviceList[selectec_id].DeviceInformation);
}
}
else
{
}
}
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.OriginalSource != MainWindowsTabControl_Handle)
{
return;
}
}
private static byte[] strToToHexByte(string hexString, ref byte[] reres)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
{
hexString = hexString.Insert(hexString.Length - 1, 0.ToString());
}
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
{
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
for (int i = 0; i < hexString.Length / 2; i++)
{
reres[i] = returnBytes[i];
}
return returnBytes;
}
private async void SendMsgToDevicesButton1_Click(object sender, RoutedEventArgs e)
{
var writer = new DataWriter();
byte[] returnBytes = new byte[6];
strToToHexByte(SendMsgToDevices_TextBox.Text.ToString(), ref returnBytes);
// WriteByte used for simplicity. Other common functions - WriteInt16 and WriteSingle
writer.WriteBytes(returnBytes);
await SaveToWriteCharac.WriteValueAsync(writer.DetachBuffer());
}
private void DataReceivedProcess(byte[] bledata)
{
int real_data_len = 0;
switch (bledata[0])
{
case 0x80:
real_data_len = bledata[1];
for (int i = 2; i < real_data_len + 2; i += 21)
{
for (int si = 0; si < ppg_data_len - 1; si++)
{
ppggre1_data[si] = ppggre1_data[si + 1];
ppggre2_data[si] = ppggre2_data[si + 1];
ppggre3_data[si] = ppggre3_data[si + 1];
ppgred1_data[si] = ppgred1_data[si + 1];
ppgred2_data[si] = ppgred2_data[si + 1];
ppgired_data[si] = ppgired_data[si + 1];
ppgambi_data[si] = ppgambi_data[si + 1];
}
for (int si = 0; si < ppg_data_len; si++)
{
ppg_data_x[si] += 1.0f;
}
ppggre1_data[ppg_data_len - 1] = (bledata[i + 0] & 15) * 65536.0f + bledata[i + 1] * 256.0f + bledata[i + 2];
ppggre2_data[ppg_data_len - 1] = (bledata[i + 3] & 15) * 65536.0f + bledata[i + 4] * 256.0f + bledata[i + 5];
ppggre3_data[ppg_data_len - 1] = (bledata[i + 6] & 15) * 65536.0f + bledata[i + 7] * 256.0f + bledata[i + 8];
ppgred1_data[ppg_data_len - 1] = (bledata[i + 9] & 15) * 65536.0f + bledata[i + 10] * 256.0f + bledata[i + 11];
ppgred2_data[ppg_data_len - 1] = (bledata[i + 12] & 15) * 65536.0f + bledata[i + 13] * 256.0f + bledata[i + 14];
ppgired_data[ppg_data_len - 1] = (bledata[i + 15] & 15) * 65536.0f + bledata[i + 16] * 256.0f + bledata[i + 17];
ppgambi_data[ppg_data_len - 1] = (bledata[i + 18] & 15) * 65536.0f + bledata[i + 19] * 256.0f + bledata[i + 20];
if (ppggre1_data[ppg_data_len - 1] >= 524288.0f)
{
ppggre1_data[ppg_data_len - 1] = ppggre1_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppggre2_data[ppg_data_len - 1] >= 524288.0f)
{
ppggre2_data[ppg_data_len - 1] = ppggre2_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppggre3_data[ppg_data_len - 1] >= 524288.0f)
{
ppggre3_data[ppg_data_len - 1] = ppggre3_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppgred1_data[ppg_data_len - 1] >= 524288.0f)
{
ppgred1_data[ppg_data_len - 1] = ppgred1_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppgred2_data[ppg_data_len - 1] >= 524288.0f)
{
ppgred2_data[ppg_data_len - 1] = ppgred2_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppgired_data[ppg_data_len - 1] >= 524288.0f)
{
ppgired_data[ppg_data_len - 1] = ppgired_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
if (ppgambi_data[ppg_data_len - 1] >= 524288.0f)
{
ppgambi_data[ppg_data_len - 1] = ppgambi_data[ppg_data_len - 1] - 1048576.0f + 1.0f;
}
}
ppggre_chart_need_refresh_flag = 1;
ppgred_chart_need_refresh_flag = 1;
PpgGreData_PlotLineStart();
PpgRedData_PlotLineStart();
break;
case 0x81:
break;
case 0x82:
break;
case 0x83:
break;
case 0x84:
break;
case 0x85:
break;
case 0x86:
break;
case 0x87:
// 加速度
real_data_len = bledata[1];
for (int i = 2; i < real_data_len + 2; i += 6)
{
for (int si = 0; si < gse_data_len - 1; si++)
{
gsex_data[si] = gsex_data[si + 1];
gsey_data[si] = gsey_data[si + 1];
gsez_data[si] = gsez_data[si + 1];
}
for (int si = 0; si < gse_data_len; si++)
{
gse_data_x[si] += 1.0f;
}
gsex_data[gse_data_len - 1] = bledata[i + 1] + bledata[i + 0] * 256.0f;
gsey_data[gse_data_len - 1] = bledata[i + 3] + bledata[i + 2] * 256.0f;
gsez_data[gse_data_len - 1] = bledata[i + 5] + bledata[i + 4] * 256.0f;
if (gsex_data[gse_data_len - 1] > 32768.0)
{
gsex_data[gse_data_len - 1] = gsex_data[gse_data_len - 1] - 65536.0f + 1.0f;
}
gsex_data[gse_data_len - 1] = gsex_data[gse_data_len - 1] * 8000.0f / 32768.0f;
if (gsey_data[gse_data_len - 1] > 32768.0)
{
gsey_data[gse_data_len - 1] = gsey_data[gse_data_len - 1] - 65536.0f + 1.0f;
}
gsey_data[gse_data_len - 1] = gsey_data[gse_data_len - 1] * 8000.0f / 32768.0f;
if (gsez_data[gse_data_len - 1] > 32768.0)
{
gsez_data[gse_data_len - 1] = gsez_data[gse_data_len - 1] - 65536.0f + 1.0f;
}
gsez_data[gse_data_len - 1] = gsez_data[gse_data_len - 1] * 8000.0f / 32768.0f;
}
gse_chart_need_refresh_flag = 1;
GseData_PlotLineStart();
break;
case 0x88:
break;
case 0x89:
break;
case 0x8A:
break;
case 0x8B:
break;
default:
break;
}
}
private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
An Indicate or Notify reported that the value has changed.
//var reader = DataReader.FromBuffer(args.CharacteristicValue);
Parse the data however required.
byte[] data;
CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
string str = BitConverter.ToString(data);
Dispatcher.Invoke(new Action(
delegate
{
ShowBleReceivedDataTextBox.Text = (DateTime.Now.ToString("s") + " " + str);
}));
Dispatcher.Invoke(new Action(
delegate
{
DataReceivedProcess(data);
// 解析数据
}));
//Growl.Info("收到数据\n" + str, "InfoMsg");
}
}
}