nanoFramework.Device.Bluetooth
1.0.0-preview.21
Prefix Reserved
See the version list below for details.
dotnet add package nanoFramework.Device.Bluetooth --version 1.0.0-preview.21
NuGet\Install-Package nanoFramework.Device.Bluetooth -Version 1.0.0-preview.21
<PackageReference Include="nanoFramework.Device.Bluetooth" Version="1.0.0-preview.21" />
paket add nanoFramework.Device.Bluetooth --version 1.0.0-preview.21
#r "nuget: nanoFramework.Device.Bluetooth, 1.0.0-preview.21"
// Install nanoFramework.Device.Bluetooth as a Cake Addin #addin nuget:?package=nanoFramework.Device.Bluetooth&version=1.0.0-preview.21&prerelease // Install nanoFramework.Device.Bluetooth as a Cake Tool #tool nuget:?package=nanoFramework.Device.Bluetooth&version=1.0.0-preview.21&prerelease
Welcome to the .NET nanoFramework nanoFramework.Device.Bluetooth Library repository
Build status
Component | Build Status | NuGet Package |
---|---|---|
nanoFramework.Device.Bluetooth | ||
nanoFramework.Device.Bluetooth (preview) |
nanoFramework.Device.Bluetooth class Library
Bluetooth Low Energy library.
This library is based on the Windows.Devices.Bluetooth UWP class library but simplified and with all the async related calls removed. The original .Net assembly depended on Windows.Storage.Streams for DataReader & DataWriter; this library has simplified inbuilt versions. References to IBuffer in .Net UWP examples should now use Buffer instead.
Currently only supported on ESP32 devices with following firmware.
- ESP32_BLE_REV0
- ESP32_BLE_REV3
This restriction is due to IRAM memory space in the firmware image. With revision 1 ESP32 devices the PSRAM implementation requires PSRAM fixes which takes space in IRAM so PSRAM is currently disabled for ESP32_BLE_REV0. With the revision 3 devices the Bluetooth and PSRAM and are both available.
Samples
A number of Bluetooth LE samples are available in the nanoFramework samples repo
- Nordic Spp Sample. (coming soon)
- Environmental sensor sample. (coming soon)
Usage
Overview
The current implementation only supports the Gatt Server calls.
Also as part of this assembly is the NordicSPP class which implements a Serial Protocol Profile based on the Nordic specification. This allows clients to easily connect via Bluetooth LE to send and receive messages via a Bluetooth Serial Terminal application. A common use case for provisioning devices. See SPP section later for usage.
Attributes and UUIDs
Each service, characteristic and descriptor is defined by it's own unique 128-bit UUID. These are called GUID in this assembly. These are called UUID in the Bluetooth specifications.
If the attribute is standard UUID defined by the Bluetooth SIG, it will also have a corresponding 16-bit short ID (for example, the characteristic Battery Level has a UUID of 00002A19-0000-1000-8000-00805F9B34FB and the short ID is 0x2A19). The common standard UUIDs can be seen in GattServiceUuids and GattCharacteristicUuids.
If the short ID is not present in GattServiceUuids or GattCharacteristicUuids then create your own short GUID by calling the utility function CreateUuidFromShortCode.
Guid uuid1 = Utility.CreateUuidFromShortCode(0x2A19);
Defining the service and associated Characteristics
The GattServiceProvider is used to create and advertise the primary service definition. An extra device information service will be automatically created.
GattServiceProviderResult result = GattServiceProvider.Create(uuid);
if (result.Error != BluetoothError.Success)
{
return result.Error;
}
serviceProvider = result.ServiceProvider;
Now add to the service all the required characteristics and descriptors. Currently only Read, Write, WriteWithoutResponse, Notify and Indicate characteristics are supported.
Adding a Read Characteristic
If a userDescription is added to the GattLocalCharacteristicParameters then a user description descriptor will be automatically added to the Characteristic. For a read Characteristic you will need an associated event handler to provide the data for the read.
GattLocalCharacteristicParameters ReadParameters = new GattLocalCharacteristicParameters
{
CharacteristicProperties = (GattCharacteristicProperties.Read),
UserDescription = "My Read Characteristic"
};
GattLocalCharacteristicResult characteristicResult = serviceProvider.Service.CreateCharacteristic(uuid1, ReadParameters);
if (characteristicResult.Error != BluetoothError.Success)
{
// An error occurred.
return characteristicResult.Error;
}
_readCharacteristic = characteristicResult.Characteristic;
_readCharacteristic.ReadRequested += _readCharacteristic_ReadRequested;
You can have a read Characteristics with a constant value by setting the StaticValue property.
// Setting a Int 16 constant value to the characteristic.
DataWriter dr = new DataWriter();
dr.WriteInt16(123);
GattLocalCharacteristicParameters ReadParameters = new GattLocalCharacteristicParameters
{
CharacteristicProperties = (GattCharacteristicProperties.Read),
UserDescription = "My Read Characteristic",
StaticValue = dr.DetachBuffer()
};
If the StaticValue is set the the read event will not be called and doesn't need to be defined.
Adding a Write or WriteWithoutResponse Characteristic
The Write Characteristic is used for receiving data from the client.
GattLocalCharacteristicParameters WriteParameters = new GattLocalCharacteristicParameters
{
CharacteristicProperties = GattCharacteristicProperties.Write,
UserDescription = "My Write Characteristic"
};
characteristicResult = serviceProvider.Service.CreateCharacteristic(uuid2, WriteParameters);
if (characteristicResult.Error != BluetoothError.Success)
{
// An error occurred.
return characteristicResult.Error;
}
_writeCharacteristic = characteristicResult.Characteristic;
_writeCharacteristic.WriteRequested += _writeCharacteristic_WriteRequested;
Adding a Notify Characteristic
A notify Characteristic is used to automatically notify subscribed clients when a value has changed.
GattLocalCharacteristicParameters NotifyParameters = new GattLocalCharacteristicParameters
{
CharacteristicProperties = GattCharacteristicProperties.Notify,
UserDescription = "My Notify Characteristic"
};
characteristicResult = serviceProvider.Service.CreateCharacteristic(uuid3, NotifyParameters);
if (characteristicResult.Error != BluetoothError.Success)
{
// An error occurred.
return characteristicResult.Error;
}
_notifyCharacteristic = characteristicResult.Characteristic;
_notifyCharacteristic.SubscribedClientsChanged += _notifyCharacteristic_SubscribedClientsChanged;
Sending data to a Notify Characteristic
Data can be sent to subscribed clients by calling the NotifyValue method on the notify characteristic. Extra checks can be added to only send values if there are subscribed clients or if the values has changed since last notified.
private static void UpdateNotifyValue(double newValue)
{
DataWriter dw = new DataWriter();
dw.WriteDouble(newValue);
_notifyCharacteristic.NotifyValue(dw.DetachBuffer());
}
Events
Read requested event
When a client requests to read a characteristic, the managed event will be called assuming a static value hasn't been set.
If no event handler is set or you don't respond in a timely manner an Unlikely bluetooth error will be returned to client.
If reading the value from a peripheral device takes time then best to put this outside the event handler.
This show the returning of 2 values to client request.
private static void _readCharacteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs ReadRequestEventArgs)
{
GattReadRequest request = ReadRequestEventArgs.GetRequest();
// Create DataWriter and write the data into buffer
DataWriter dw = new DataWriter();
dw.WriteInt16(1);
dw.WriteInt32(2);
request.RespondWithValue(dw.DetachBuffer());
// If there is some sort of error then response with an error
//request.RespondWithProtocolError((byte)BluetoothError.DeviceNotConnected);
}
Write requested event
When data is sent to a write characteristic the managed event is called. If no event handler is set or you don't respond in a timely manner an Unlikely bluetooth error will be returned to client.
The data received is a array of bytes and this is formatted as required by characteristic. This could be a single value of Int16, Int32, string etc. or it could be a number of different values.
This shows the reading of a single Int32 value from buffer and returns an error if the wrong number of bytes has been supplied.
private static void _writeCharacteristic_WriteRequested(GattLocalCharacteristic sender, GattWriteRequestedEventArgs WriteRequestEventArgs)
{
GattWriteRequest request = WriteRequestEventArgs.GetRequest();
// Check expected data length
if (request.Value.Length != 4)
{
request.RespondWithProtocolError((byte)BluetoothError.NotSupported);
return;
}
// Read data from buffer of required format
DataReader rdr = DataReader.FromBuffer(request.Value);
Int32 data = rdr.ReadInt32();
// Do something with received data
Debug.WriteLine($"Rx data::{data}");
// Respond if Write requires response
if (request.Option == GattWriteOption.WriteWithResponse)
{
request.Respond();
}
}
Subscribed Clients changed event
For notify characteristics a client can subscribe to receive the notification values. When a client subscribes the managed event will be called. The SubscribedClients array of the characteristics contains the connected clients.
private static void _notifyCharacteristic_SubscribedClientsChanged(GattLocalCharacteristic sender, object args)
{
if ( sender.SubscribedClients.Length > 0)
{
Debug.WriteLine($"Client connected ");
}
}
Bluetooth Serial Port Profile(SPP)
This assembly has an implementation of the Nordic SPP which can easily be used to send messages between a Bluetooth client and the device running the SPP. This is a simple way of provisioning a device with any extra information like WiFi details.
There are a number of Android and IOS app that support Nordic SPP that can be used to send/receive messages.
Create instance of the SPP
Create an instance of the SPP and provide event handlers for reading messages and client connection activity. Start advertising with a device name.
Uses namespace nanoFramework.Device.Bluetooth.Spp
NordicSpp spp = new NordicSpp();
spp.ReceivedData += Spp_ReceivedData;
spp.ConnectedEvent += Spp_ConnectedEvent;
spp.Start("MySpp");
When complete, call the Stop method to stop the SPP.
Handling Read Data events
Data can be read as either a array of bytes or as a string.
private void Spp_ReceivedData(IBluetoothSpp sender, SppReceivedDataEventArgs ReadDataEventArgs)
{
string message = ReadDataEventArgs.DataString;
// Do something with incoming message
Debug.WriteLine($"Message:{message}");
// For this example lets respond with "OK"
NordicSpp spp = sender as NordicSpp;
spp.SendString("OK");
}
Handling connection events
A connection event is thrown when a client connects or disconnects from SPP server. Here we send a message when a client connects.
private void Spp_ConnectedEvent(IBluetoothSpp sender, EventArgs e)
{
NordicSpp spp = sender as NordicSpp;
if (spp.IsConnected)
{
spp.SendString("Welcome to nanoFramework");
}
}
Feedback and documentation
For documentation, providing feedback, issues and finding out how to contribute please refer to the Home repo.
Join our Discord community here.
Credits
The list of contributors to this project can be found at CONTRIBUTORS.
License
The nanoFramework Class Libraries are licensed under the MIT license.
Code of Conduct
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behaviour in our community. For more information see the .NET Foundation Code of Conduct.
.NET Foundation
This project is supported by the .NET Foundation.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET Framework | net is compatible. |
-
- nanoFramework.CoreLibrary (>= 1.12.0-preview.18)
- nanoFramework.Runtime.Events (>= 1.10.0-preview.11)
- nanoFramework.System.Text (>= 1.1.3-preview.19)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on nanoFramework.Device.Bluetooth:
Package | Downloads |
---|---|
nanoFramework.Bluetooth.Hid
This package includes the .NET nanoFramework.Bluetooth.Hid assembly for .NET nanoFramework C# projects. This allows to have a device seen as an HID device over Bluetooth. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on nanoFramework.Device.Bluetooth:
Repository | Stars |
---|---|
nanoframework/Samples
🍬 Code samples from the nanoFramework team used in testing, proof of concepts and other explorational endeavours
|
Version | Downloads | Last updated |
---|---|---|
1.1.84 | 235 | 10/11/2024 |
1.1.83 | 223 | 9/26/2024 |
1.1.75 | 644 | 6/16/2024 |
1.1.73 | 111 | 6/15/2024 |
1.1.65 | 344 | 5/9/2024 |
1.1.60 | 999 | 11/9/2023 |
1.1.58 | 111 | 11/9/2023 |
1.1.56 | 426 | 8/9/2023 |
1.1.54 | 249 | 8/2/2023 |
1.1.47 | 397 | 4/25/2023 |
1.1.45 | 231 | 4/16/2023 |
1.1.43 | 192 | 4/13/2023 |
1.1.40 | 294 | 3/16/2023 |
1.1.37 | 286 | 3/10/2023 |
1.1.35 | 220 | 3/9/2023 |
1.1.32 | 443 | 12/28/2022 |
1.1.30 | 301 | 12/27/2022 |
1.1.21 | 629 | 10/26/2022 |
1.1.16 | 466 | 9/27/2022 |
1.1.13 | 505 | 9/16/2022 |
1.1.10 | 421 | 9/6/2022 |
1.1.8 | 394 | 9/6/2022 |
1.1.4 | 472 | 8/20/2022 |
1.1.2 | 450 | 8/4/2022 |
1.0.2.6 | 558 | 6/9/2022 |
1.0.2.4 | 429 | 6/8/2022 |
1.0.2.1 | 405 | 6/6/2022 |
1.0.1 | 318 | 3/30/2022 |
1.0.0-preview.31 | 127 | 3/28/2022 |
1.0.0-preview.29 | 124 | 3/28/2022 |
1.0.0-preview.26 | 134 | 3/17/2022 |
1.0.0-preview.24 | 150 | 3/17/2022 |
1.0.0-preview.23 | 127 | 3/14/2022 |
1.0.0-preview.21 | 124 | 3/14/2022 |
1.0.0-preview.18 | 173 | 2/17/2022 |
1.0.0-preview.17 | 138 | 2/8/2022 |
1.0.0-preview.16 | 133 | 2/4/2022 |
1.0.0-preview.15 | 140 | 1/28/2022 |
1.0.0-preview.14 | 135 | 1/28/2022 |
1.0.0-preview.13 | 134 | 1/21/2022 |
1.0.0-preview.12 | 132 | 1/21/2022 |
1.0.0-preview.11 | 131 | 1/20/2022 |
1.0.0-preview.9 | 157 | 1/4/2022 |
1.0.0-preview.8 | 145 | 12/28/2021 |
1.0.0-preview.6 | 281 | 12/3/2021 |
1.0.0-preview.4 | 156 | 12/3/2021 |