Wpf + 低功耗蓝牙

  • 参考: 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");
        }


    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值