BLE API¶
New in version 1.2.0: BLE API added
BLE Limitations¶
This module uses the RF24
class to make the nRF24L01 imitate a
Bluetooth-Low-Emissions (BLE) beacon. A BLE beacon can send data (referred to as
advertisements) to any BLE compatible device (ie smart devices with Bluetooth
4.0 or later) that is listening.
Original research was done by Dmitry Grinberg and his write-up (including C source code) can be found here As this technique can prove invaluable in certain project designs, the code here has been adapted to work with CircuitPython.
Important
Because the nRF24L01 wasn’t designed for BLE advertising, it has some limitations that helps to be aware of.
The maximum payload length is shortened to 18 bytes (when not broadcasting a device
name
nor the nRF24L01show_pa_level
). This is calculated as:32 (nRF24L01 maximum) - 6 (MAC address) - 5 (required flags) - 3 (CRC checksum) = 18
Use the helper function
available()
to detirmine if your payload can be transmit.the channels that BLE use are limited to the following three: 2.402 GHz, 2.426 GHz, and 2.480 GHz. We have provided a tuple of these specific channels for convenience (See
BLE_FREQ
andhop_channel()
).crc
is disabled in the nRF24L01 firmware because BLE specifications require 3 bytes (crc24_ble()
), and the nRF24L01 firmware can only handle a maximum of 2. Thus, we have appended the required 3 bytes of CRC24 into the payload.address_length
of BLE packet only uses 4 bytes, so we have set that accordingly.The
auto_ack
(automatic acknowledgment) feature of the nRF24L01 is useless when tranmitting to BLE devices, thus it is disabled as well as automatic re-transmit (arc
) and custom ACK payloads (ack
) features which both depend on the automatic acknowledgments feature.The
dynamic_payloads
feature of the nRF24L01 isn’t compatible with BLE specifications. Thus, we have disabled it.BLE specifications only allow using 1 Mbps RF
data_rate
, so that too has been hard coded.Only the “on data sent” (
irq_ds
) & “on data ready” (irq_dr
) events will have an effect on the interrupt (IRQ) pin. The “on data fail” (irq_df
) is never triggered becausearc
attribute is disabled.
helpers¶
swap_bits()¶
-
circuitpython_nrf24l01.fake_ble.
swap_bits
(original)[source]¶ This function reverses the bit order for a single byte.
reverse_bits()¶
-
circuitpython_nrf24l01.fake_ble.
reverse_bits
(original)[source]¶ This function reverses the bit order for an entire buffer protocol object.
chunk()¶
-
circuitpython_nrf24l01.fake_ble.
chunk
(buf, data_type=22)[source]¶ This function is used to pack data values into a block of data that make up part of the BLE payload per Bluetooth Core Specifications.
- Parameters
buf (bytearray,bytes) – The actual data contained in the block.
data_type (int) – The type of data contained in the chunk. This is a predefined number according to BLE specifications. The default value
0x16
describes all service data.0xFF
describes manufacturer information. Any other values are not applicable to BLE advertisements.
Important
This function is called internally by
advertise()
. To pack multiple data values into a single payload, use this function for each data value and pass alist
ortuple
of the returned results toadvertise()
(see example code in documentation aboutadvertise()
for more detail). Remember that broadcasting multiple data values may require thename
be set toNone
and/or theshow_pa_level
be set toFalse
for reasons about the payload size with BLE Limitations.
crc24_ble()¶
-
circuitpython_nrf24l01.fake_ble.
crc24_ble
(data, deg_poly=1627, init_val=5592405)[source]¶ This function calculates a checksum of various sized buffers.
This is exposed for convenience but should not be used for other buffer protocols that require big endian CRC24 format.
- Parameters
data (bytearray,bytes) – The buffer of data to be uncorrupted.
deg_poly (int) – A preset “degree polynomial” in which each bit represents a degree who’s coefficient is 1. BLE specfications require
0x00065b
(default value).init_val (int) – This will be the initial value that the checksum will use while shifting in the buffer data. BLE specfications require
0x555555
(default value).
- Returns
A 24-bit
bytearray
representing the checksum of the data (in proper little endian).
BLE_FREQ¶
-
circuitpython_nrf24l01.fake_ble.
BLE_FREQ
= (2, 26, 80)¶ The BLE channel number is different from the nRF channel number.
This tuple contains the relative predefined channels used:
nRF24L01 channel
BLE channel
2
37
26
38
80
39
FakeBLE class¶
-
class
circuitpython_nrf24l01.fake_ble.
FakeBLE
(spi, csn, ce_pin, spi_frequency=10000000)[source]¶ A class to implement BLE advertisements using the nRF24L01.
Per the limitations of this technique, only some of underlying
RF24
functionality is available for configuration when implementing BLE transmissions. See the Unavailable RF24 functionality for more details.- Parameters
spi (SPI) –
The object for the SPI bus that the nRF24L01 is connected to.
Tip
This object is meant to be shared amongst other driver classes (like adafruit_mcp3xxx.mcp3008 for example) that use the same SPI bus. Otherwise, multiple devices on the same SPI bus with different spi objects may produce errors or undesirable behavior.
csn (DigitalInOut) – The digital output pin that is connected to the nRF24L01’s CSN (Chip Select Not) pin. This is required.
ce_pin (DigitalInOut) – The digital output pin that is connected to the nRF24L01’s CE (Chip Enable) pin. This is required.
spi_frequency (int) – Specify which SPI frequency (in Hz) to use on the SPI bus. This parameter only applies to the instantiated object and is made persistent via
SPIDevice
.
mac¶
-
FakeBLE.
mac
¶ This attribute returns a 6-byte buffer that is used as the arbitrary mac address of the BLE device being emulated.
You can set this attribute using a 6-byte
int
orbytearray
. If this is set toNone
, then a random 6-byte address is generated.
name¶
-
FakeBLE.
name
¶ The broadcasted BLE name of the nRF24L01.
This is not required. In fact setting this attribute will subtract from the available payload length (in bytes). Set this attribute to
None
to disable advertising the device name.Note
This information occupies (in the TX FIFO) an extra 2 bytes plus the length of the name set by this attribute.
show_pa_level¶
-
FakeBLE.
show_pa_level
¶ If this attribute is
True
, the payload will automatically include the nRF24L01’s pa_level in the advertisement.The default value of
False
will exclude this optional information.Note
This information occupies (in the TX FIFO) an extra 3 bytes, and is really only useful for some applications to calculate proximity to the nRF24L01 transceiver.
hop_channel()¶
whiten()¶
-
FakeBLE.
whiten
(data)[source]¶ Whitening the BLE packet data ensures there’s no long repeatition of bits.
This is done according to BLE specifications.
- Parameters
- Returns
A
bytearray
of thedata
with the whitening algorythm applied.
Warning
This function uses the currently set BLE channel as a base case for the whitening coefficient. Do not call
hop_channel()
before using this function to de-whiten received payloads (which isn’t officially supported yet). Note thatadvertise()
uses this function internally to prevent such improper usage.
len_available()¶
-
FakeBLE.
len_available
(hypothetical=b'')[source]¶ This function will calculates how much length (in bytes) is available in the next payload.
This is detirmined from the current state of
name
andshow_pa_level
attributes.- Parameters
hypothetical (bytearray,bytes) – Pass a potential
chunk()
of data to this parameter to calculate the resulting left over length in bytes. This parameter is optional.- Returns
An
int
representing the length of available bytes for the a single payload.
Changed in version 2.0.0: name changed from “available” to “len_available” to avoid confusion with
circuitpython_nrf24l01.rf24.RF24.available()
. This change also allows providing the underlyingRF24
class’available()
method in theFakeBLE
API.
advertise()¶
-
FakeBLE.
advertise
(buf=b'', data_type=255)[source]¶ This blocking function is used to broadcast a payload.
- Returns
Nothing as every transmission will register as a success under the required settings for BLE beacons.
- Parameters
buf (bytearray) – The payload to transmit. This bytearray must have a length greater than 0 and less than 22 bytes Otherwise a
ValueError
exception is thrown whose prompt will tell you the maximum length allowed under the current configuration. This can also be a list or tuple of payloads (bytearray
); in which case, all items in the list/tuple are processed are packed into 1 payload for a single transmissions. See example code below about passing alist
ortuple
to this parameter.data_type (int) – This is used to describe the buffer data passed to the
buf
parameter.0x16
describes all service data. The default value0xFF
describes manufacturer information. This parameter is ignored when atuple
orlist
is passed to thebuf
parameter. Any other values are not applicable to BLE advertisements.
Important
If the name and/or TX power level of the emulated BLE device is also to be broadcast, then the
name
and/orshow_pa_level
attribute(s) should be set prior to callingadvertise()
.To pass multiple data values to the
buf
parameter see the following code as an example:# let UUIDs be the 16-bit identifier that corresponds to the # BLE service type. The following values are not compatible with # BLE advertisements. UUID_1 = 0x1805 UUID_2 = 0x1806 service1 = ServiceData(UUID_1) service2 = ServiceData(UUID_2) service1.data = b"some value 1" service2.data = b"some value 2" # make a tuple of the buffers buffers = ( chunk(service1.buffer), chunk(service2.buffer) ) # let `ble` be the instantiated object of the FakeBLE class ble.advertise(buffers) ble.hop_channel()
channel¶
interrupt_config()¶
-
FakeBLE.
interrupt_config
(data_recv=True, data_sent=True, data_fail=True)¶ Sets the configuration of the nRF24L01’s IRQ pin. (write-only)
Warning
The
circuitpython_nrf24l01.rf24.RF24.irq_df
attribute is not implemented for BLE operations.See also
Unavailable RF24 functionality¶
The following RF24
functionality is not available in FakeBLE
objects:
Service related classes¶
abstract parent¶
-
class
circuitpython_nrf24l01.fake_ble.
ServiceData
(uuid)[source]¶ An abstract helper class to package specific service data using Bluetooth SIG defined 16-bit UUID flags to describe the data type.
- Parameters
uuid (int) – The 16-bit UUID “GATT Service assigned number” defined by the Bluetooth SIG to describe the service data. This parameter is required.
-
property
data
¶ The service’s data. This is a
bytearray
, and its format is defined by relative Bluetooth Service Specifications (and GATT supplemental specifications).
derivitive children¶
-
class
circuitpython_nrf24l01.fake_ble.
TemperatureServiceData
[source]¶ Bases:
circuitpython_nrf24l01.fake_ble.ServiceData
This derivitive of the
ServiceData
class can be used to represent temperature data values as afloat
value.This class’s
data
attribute accepts afloat
value as input and returns abytes
object that conforms to the Bluetooth Health Thermometer Measurement format as defined in the GATT Specifications Supplement.
-
class
circuitpython_nrf24l01.fake_ble.
BatteryServiceData
[source]¶ Bases:
circuitpython_nrf24l01.fake_ble.ServiceData
This derivitive of the
ServiceData
class can be used to represent battery charge percentage as a 1-byte value.The class’s
data
attribute accepts a 1-byte unsignedint
value as input and returns abytes
object that conforms to the Bluetooth Battery Level format as defined in the GATT Specifications Supplement.
-
class
circuitpython_nrf24l01.fake_ble.
UrlServiceData
[source]¶ Bases:
circuitpython_nrf24l01.fake_ble.ServiceData
This derivitive of the
ServiceData
class can be used to represent URL data as abytes
value.This class’s
data
attribute accepts astr
of URL data as input, and returns the URL as abytes
object where some of the URL parts are encoded using Eddystone byte codes as defined by the specifications.