diff --git a/rf/nrf52832_ble/ble_timing.png b/rf/nrf52832_ble/ble_timing.png new file mode 100644 index 0000000000000000000000000000000000000000..82edd8847862aba9eb4380f821854fc59316dda2 Binary files /dev/null and b/rf/nrf52832_ble/ble_timing.png differ diff --git a/rf/nrf52832_ble/ble_uart_ring.ino b/rf/nrf52832_ble/ble_uart_ring.ino new file mode 100644 index 0000000000000000000000000000000000000000..04f6602801a9f9d6f0e38e8c6f0a0df0473d3f9c --- /dev/null +++ b/rf/nrf52832_ble/ble_uart_ring.ino @@ -0,0 +1,55 @@ +#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"); +} diff --git a/rf/nrf52832_ble/ble_uart_ring.py b/rf/nrf52832_ble/ble_uart_ring.py new file mode 100644 index 0000000000000000000000000000000000000000..1541c7dc837a3f5c76e8ee199115395faf8c3907 --- /dev/null +++ b/rf/nrf52832_ble/ble_uart_ring.py @@ -0,0 +1,52 @@ +# 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) diff --git a/rf/nrf52832_ble/index.html b/rf/nrf52832_ble/index.html new file mode 100644 index 0000000000000000000000000000000000000000..208fe51479aaf1d1c5f95ce467885a998a279f67 --- /dev/null +++ b/rf/nrf52832_ble/index.html @@ -0,0 +1,164 @@ +<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 <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"); +} + +</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<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) + +</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