从C#中的BLE设备读取数据

时间:2019-08-19 16:13:29

标签: c# wpf windows bluetooth-lowenergy

我必须编写Windows桌面应用程序才能从便携式医疗设备读取日志。该场景是设备进入维修站进行维护。该技术人员通过蓝牙将PC连接到设备并下载日志。进行一些维护后,该设备将运回给客户,并且可能几个月都不会再次出现。

我已经尝试使用串行端口配置文件,但是很快了解到BLE不支持它。另一家公司正在开发的设备仅限于BLE,因此我不能使用SPP。数据范围为10kb至100kb。

我已经研究过创建自定义服务,以获取可用的日志条目数量,以及可能设置的日期范围来获取日志。这部分看起来很合理。

我不确定的是,一旦我知道要检索多少日志,如何打开流来读取日志。每个日志条目将作为字符串发送,Windows代码将解析为单个值以显示给技术人员。

我对BLE还是有些陌生,所以我不确定该通过哪种方式获取实际的日志条目。预先感谢您的指导。

更新:

需要做更多的调查,看来对象传输协议可能是要走的路。快速计算可使每个日志记录的大小范围为64字节左右。

我的理解是,OTP允许我获取对象(在这种情况下为日志记录)的计数,并从设备中逐一请求它们。这种方法看起来合理吗?

1 个答案:

答案 0 :(得分:0)

这是几年前我写的一些代码,用于通过蓝牙与LG G3手机通话。我使用了InTheHand库。我不记得它是否支持BLE。...

using InTheHand.Net;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Bluetooth.AttributeIds;
using InTheHand.Net.Sockets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BluetoothPrototype1
{
    class Program
    {
        private const string DEVICE_NAME = "G3";

        private static BluetoothDeviceInfo _device = null;
        private static BluetoothWin32Events _bluetoothEvents = null;

        static void Main(string[] args)
        {
            try
            {
                displayBluetoothRadio();

                _bluetoothEvents = BluetoothWin32Events.GetInstance();
                _bluetoothEvents.InRange += onInRange;
                _bluetoothEvents.OutOfRange += onOutOfRange;

                using (BluetoothClient client = new BluetoothClient())
                {
                    BluetoothComponent component = new BluetoothComponent(client);
                    component.DiscoverDevicesProgress += onDiscoverDevicesProgress;
                    component.DiscoverDevicesComplete += onDiscoverDevicesComplete;
                    component.DiscoverDevicesAsync(255, true, false, false, false, null);

                    //BluetoothDeviceInfo[] peers = client.DiscoverDevices();

                    //device = peers.ToList().Where(p => p.DeviceName == DEVICE_NAME).FirstOrDefault();
                }                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.ReadKey();
            }
        }

        static void onOutOfRange(object sender, BluetoothWin32RadioOutOfRangeEventArgs e)
        {
            Console.WriteLine(string.Format("Device {0} out of range", e.Device.DeviceName));
        }

        static void onInRange(object sender, BluetoothWin32RadioInRangeEventArgs e)
        {
            Console.WriteLine(string.Format("Device {0} in range.  Connected:{1}", e.Device.DeviceName, e.Device.Connected));
        }

        static void onDiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
        {
            Console.WriteLine("Device discovery in progress");
            foreach (var device in e.Devices)
            {
                Console.WriteLine(device.DeviceName);
            }
            Console.WriteLine();
        }

        static void onDiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e)
        {
            Console.WriteLine("Device discovery complete");
            foreach (var device in e.Devices)
            {
                Console.WriteLine(device.DeviceName);
            }
            Console.WriteLine();

            _device = e.Devices.ToList().Where(p => p.DeviceName == DEVICE_NAME).FirstOrDefault();

            if (_device != null)
            {                
                Console.WriteLine("Selected {0} device with address {1}", _device.DeviceName, _device.DeviceAddress);               

                using (BluetoothClient client = new BluetoothClient())
                {
                    client.Connect(new BluetoothEndPoint(_device.DeviceAddress, BluetoothService.SerialPort));
                    Stream peerStream = client.GetStream();

                    for (int i = 0; i < 100; i++)
                    {
                        byte[] wb = Encoding.ASCII.GetBytes(string.Format("{0:X2} : This is a test : {1}{2}", i, DateTime.Now.ToString("o"), Environment.NewLine));
                        peerStream.Write(wb, 0, wb.Length);
                    }

                    byte [] buf = new byte[1024];
                    int readLength = peerStream.Read(buf, 0, buf.Length);
                    if (readLength > 0)
                    {
                        Console.WriteLine("Received {0} bytes", readLength);
                    }
                    else
                    {
                        Console.WriteLine("Connection is closed");
                    }
                }
            }
        }

        private static void displayBluetoothRadio()
        {
            BluetoothRadio myRadio = BluetoothRadio.PrimaryRadio;
            if (myRadio == null)
            {
                Console.WriteLine("No radio hardware or unsupported software stack");
                return;
            }
            RadioMode mode = myRadio.Mode;
            // Warning: LocalAddress is null if the radio is powered-off.
            Console.WriteLine("* Radio, address: {0:C}", myRadio.LocalAddress);
            Console.WriteLine("Mode: " + mode.ToString());
            Console.WriteLine("Name: " + myRadio.Name);
            Console.WriteLine("HCI Version: " + myRadio.HciVersion
                + ", Revision: " + myRadio.HciRevision);
            Console.WriteLine("LMP Version: " + myRadio.LmpVersion
                + ", Subversion: " + myRadio.LmpSubversion);
            Console.WriteLine("ClassOfDevice: " + myRadio.ClassOfDevice.ToString()
                + ", device: " + myRadio.ClassOfDevice.Device.ToString()
                + " / service: " + myRadio.ClassOfDevice.Service.ToString());
            //
            //
            // Enable discoverable mode
            Console.WriteLine();
            myRadio.Mode = RadioMode.Discoverable;
            Console.WriteLine("Radio Mode now: " + myRadio.Mode.ToString());
            Console.WriteLine();
        }
    }
}