Skip to content
Snippets Groups Projects
Commit 13184e44 authored by Sam Calisch's avatar Sam Calisch
Browse files

added ble uart example

parent 2433fab8
Branches
No related tags found
No related merge requests found
Pipeline #
rf/nrf52832_ble/ble_timing.png

43.9 KiB

#include <bluefruit.h>
BLEDis bledis;
BLEUart bleuart;
uint8_t ch;
void setup()
{
Serial.begin(115200);
Serial.println("Bluefruit52 BLEUART Example");
Bluefruit.begin();
Bluefruit.setName("Bluefruit52");
Bluefruit.setConnectCallback(connect_callback);
Bluefruit.setDisconnectCallback(disconnect_callback);
// Configure and Start Device Information Service
bledis.setManufacturer("Adafruit Industries");
bledis.setModel("Bluefruit Feather52");
bledis.begin();
bleuart.begin(); // Configure and Start BLE Uart Service
setupAdv(); // Set up Advertising Packet
Bluefruit.Advertising.start(); // Start Advertising
while(1){
// echo BLEUART
if ( bleuart.available() )
{
ch = (uint8_t) bleuart.read();
bleuart.write(&ch,1);
}
}
}
void setupAdv(void)
{
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
// Include bleuart 128-bit uuid
Bluefruit.Advertising.addService(bleuart);
// There is no room for Name in Advertising packet, so use Scan response for Name
Bluefruit.ScanResponse.addName();
}
void loop(){}
void connect_callback(void) {Serial.println("Connected");}
void disconnect_callback(uint8_t reason)
{
(void) reason;
Serial.println();
Serial.println("Disconnected");
Serial.println("Bluefruit will start advertising again");
}
# Round trip timing of BLE UART Service
# Sam Calisch, 2017
# Adapted from Tony DiCola's BLE UART example: https://github.com/adafruit/Adafruit_Python_BluefruitLE
import Adafruit_BluefruitLE
from Adafruit_BluefruitLE.services import UART
import time
ble = Adafruit_BluefruitLE.get_provider()
def main():
ble.clear_cached_data()
adapter = ble.get_default_adapter()
adapter.power_on()
print('Using adapter: {0}'.format(adapter.name))
UART.disconnect_devices()
print('Searching for UART device...')
try:
adapter.start_scan()
device = UART.find_device()
if device is None:
raise RuntimeError('Failed to find UART device!')
finally:
adapter.stop_scan()
print('Connecting to device...')
device.connect()
try:
print('Discovering services...')
UART.discover(device)
uart = UART(device)
print "Measuring"
i = 0
N = 100
t0 = time.time();
times = []
#we run 2N trials
#the first N trials wait for a response from the ble uart
#the second N trials don't wait for a response, in order to time the host side of the loop
while(i<2*N):
uart.write('\n') #write newline to the TX characteristic.
received = uart.read(timeout_sec=10) if i<N else 10
if received is not None:
times.append( time.time()-t0 )
t0 = time.time()
i = i+1
finally:
device.disconnect() #disconnect on exit.
print "Disconnected"
print times
ble.initialize()
ble.run_mainloop_with(main)
<html>
<head>
<style>
pre code {
background-color: #eee;
border: 1px solid #999;
display: block;
padding: 20px;
}
figure{
text-align: center
}
</style>
</head>
<body>
<h1>NRF52832 BLE</h1>
<figure>
<img src='ble_timing.png' width=50%>
<figcaption>Timing 100 packets sent from a host and echoed by an nrf52 using the BLEUart Service.</figcaption>
</figure>
<p>This RF ring oscillator runs on the NRF52 BLE SOC using the Adafruit feather development board. The NRF52 has an ARM Cortex M4F running at 64 MHz with built in BLE radio. This example uses a BLE stack provided by Adafruit. In particular, it makes use of the BLEUART service, a wrapper for the Nordic UART Service. On a host PC, we run a python script using the Adafruit BluefruitLE library.</p>
<p>To estimate round trip timing between two nodes with time loops of the host program where a byte is sent to the slave, and the slave sends the byte back. We also time the loop (including the sending) without waiting for the response. In this way, we can subtract the time taken by the host and estimate the time for a single RX and TX by the slave. The round trip packet time (as is consistent with other examples on this site) is then twice this estimate.</p>
<p>An arduino sketch for the oscillator is available <a href='ble_uart_ring.ino'>here</a>, or visible below.</p>
<pre>
<code>
#include &ltbluefruit.h&gt
BLEDis bledis;
BLEUart bleuart;
uint8_t ch;
void setup()
{
Serial.begin(115200);
Serial.println("Bluefruit52 BLEUART Example");
Bluefruit.begin();
Bluefruit.setName("Bluefruit52");
Bluefruit.setConnectCallback(connect_callback);
Bluefruit.setDisconnectCallback(disconnect_callback);
// Configure and Start Device Information Service
bledis.setManufacturer("Adafruit Industries");
bledis.setModel("Bluefruit Feather52");
bledis.begin();
bleuart.begin(); // Configure and Start BLE Uart Service
setupAdv(); // Set up Advertising Packet
Bluefruit.Advertising.start(); // Start Advertising
while(1){
// echo BLEUART
if ( bleuart.available() )
{
ch = (uint8_t) bleuart.read();
bleuart.write(&ch,1);
}
}
}
void setupAdv(void)
{
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
// Include bleuart 128-bit uuid
Bluefruit.Advertising.addService(bleuart);
// There is no room for Name in Advertising packet, so use Scan response for Name
Bluefruit.ScanResponse.addName();
}
void loop(){}
void connect_callback(void) {Serial.println("Connected");}
void disconnect_callback(uint8_t reason)
{
(void) reason;
Serial.println();
Serial.println("Disconnected");
Serial.println("Bluefruit will start advertising again");
}
</code>
</pre>
<p>The python host script is available <a href='ble_uart_ring.py'>here</a>, or visible below.</p>
<pre>
<code>
# Round trip timing of BLE UART Service
# Sam Calisch, 2017
# Adapted from Tony DiCola's BLE UART example: https://github.com/adafruit/Adafruit_Python_BluefruitLE
import Adafruit_BluefruitLE
from Adafruit_BluefruitLE.services import UART
import time
ble = Adafruit_BluefruitLE.get_provider()
def main():
ble.clear_cached_data()
adapter = ble.get_default_adapter()
adapter.power_on()
print('Using adapter: {0}'.format(adapter.name))
UART.disconnect_devices()
print('Searching for UART device...')
try:
adapter.start_scan()
device = UART.find_device()
if device is None:
raise RuntimeError('Failed to find UART device!')
finally:
adapter.stop_scan()
print('Connecting to device...')
device.connect()
try:
print('Discovering services...')
UART.discover(device)
uart = UART(device)
print "Measuring"
i = 0
N = 100
t0 = time.time();
times = []
#we run 2N trials
#the first N trials wait for a response from the ble uart
#the second N trials don't wait for a response, in order to time the host side of the loop
while(i<2*N):
uart.write("\n") #write newline to the TX characteristic.
received = uart.read(timeout_sec=10) if i&ltN else 10
if received is not None:
times.append( time.time()-t0 )
t0 = time.time()
i = i+1
finally:
device.disconnect() #disconnect on exit.
print "Disconnected"
print times
ble.initialize()
ble.run_mainloop_with(main)
</code>
</pre>
<p>Note: This test was run on a the Adafruit Feather Dev board, which uses the Raytac MDBT42Q module, incorporating the NRF52. The module retails for $7, the development board retails $24. Other modules are available for $5 from Fanstel.</p>
<p><a href='../../index.html'>Back</a></p>
</body>
</html>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment