{"id":369,"date":"2015-08-05T20:09:23","date_gmt":"2015-08-06T03:09:23","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=369"},"modified":"2015-08-05T20:09:23","modified_gmt":"2015-08-06T03:09:23","slug":"developing-a-uart-over-bluetooth-le-adapter-using-nordic-nrf51","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/uart-bluetooth\/","title":{"rendered":"Developing a UART-over-Bluetooth LE adapter using Nordic nRF51"},"content":{"rendered":"<p>This tutorial shows how to create a UART-over-Bluetooth LE adapter using the nRF51-DK evaluation board from Nordic and VisualGDB. We will show how to use the Nordic Android app to send and receive data to the UART port on the board.<\/p>\n<p>Before you begin, install VisualGDB 5.0, get a Bluetooth LE-enabled Android phone and follow our <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/nrf51\">Basic nRF51 tutorial<\/a> to get started with nRF51 devices.<\/p>\n<ol>\n<li>\u00a0Start creating a new Visual Studio project using the VisualGDB Embedded Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-uartprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-371\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-uartprj.png\" alt=\"01-uartprj\" width=\"800\" height=\"450\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-uartprj.png 800w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/01-uartprj-300x169.png 300w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/a><\/li>\n<li>Proceed with the default settings on the first page of the wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-binary2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-372\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-binary2.png\" alt=\"02-binary\" width=\"702\" height=\"571\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-binary2.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/02-binary2-300x244.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>Specify your Nordic device. Set the softdevice to S110 that supports Bluetooth LE Peripheral mode:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-373\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device3.png\" alt=\"03-device\" width=\"702\" height=\"597\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device3.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/03-device3-300x255.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>On the next page select the Bluetooth LE UART sample and specify your board type that is printed on a sticker on the board below:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-uartsample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-374\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-uartsample.png\" alt=\"04-uartsample\" width=\"702\" height=\"597\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-uartsample.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/04-uartsample-300x255.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>On the Debug Settings page specify a debug method that works with your board. In this example we will use the on-board Segger J-Link that works with the Segger software. Check the &#8220;Reset device after programming&#8221; checkbox as otherwise GDB will try to run your program entry point bypassing the softdevice entry point:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-reset.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-375\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-reset.png\" alt=\"05-reset\" width=\"702\" height=\"597\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-reset.png 702w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/05-reset-300x255.png 300w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/li>\n<li>Press Finish to create your project. Build it via Build-&gt;Build Solution. Ensure that the build succeeds:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-376\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build1.png\" alt=\"06-build\" width=\"695\" height=\"650\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build1.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/06-build1-300x281.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Open VisualGDB Project Properties and go to the Raw Terminal page. Specify the COM port number of the on-board J-Link (see <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/uart\/\">this tutorial<\/a> for details) and the advanced connection settings by clicking &#8220;advanced settings&#8221;. By default, the Bluetooth LE UART sample uses 38400 bits per second and hardware flow control: <a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-hwuart.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-377\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-hwuart.png\" alt=\"07-hwuart\" width=\"843\" height=\"743\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-hwuart.png 843w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/07-hwuart-300x264.png 300w\" sizes=\"(max-width: 843px) 100vw, 843px\" \/><\/a><\/li>\n<li>\u00a0 Start debugging your program and ensure that the COMx window displays the &#8220;Start&#8230;&#8221; message. Note that if you have not overridden the <strong>_isatty()<\/strong> function as described in the <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/uart\/\">UART tutorial<\/a>, VisualGDB will also show the ARM Semihosting console that will be empty:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-started.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-378\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-started.png\" alt=\"08-started\" width=\"695\" height=\"650\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-started.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/08-started-300x281.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Install the nRF UART App on your Android device. Launch it and click &#8220;Connect&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-uart2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-387\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-uart2.png\" alt=\"09-uart\" width=\"700\" height=\"394\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-uart2.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/09-uart2-300x169.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Ensure you see the Nordic_UART device in the list. Note that the Nordic UART service does not require bonding, so you do not need to pair with the device using the Android Bluetooth manager (in fact, it will not work as the UART sample does not handle bonding requests):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-device1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-388\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-device1.png\" alt=\"10-device\" width=\"700\" height=\"394\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-device1.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/10-device1-300x169.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Click on the device name to connect to it. Once the connection is established, type some text in the app and press the &#8220;Send&#8221; button:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-hello-vs1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-385\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-hello-vs1.png\" alt=\"11-hello-vs\" width=\"700\" height=\"394\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-hello-vs1.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/11-hello-vs1-300x169.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>See how the text appears in the Visual Studio COMx window:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-hello-in.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-382\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-hello-in.png\" alt=\"12-hello-in\" width=\"695\" height=\"648\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-hello-in.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/12-hello-in-300x280.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Type some text back in Visual Studio and press &#8220;Enter&#8221; (you can turn on character echoing via the &#8220;settings&#8221; button in the COMx window):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hello-v2a.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-383\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hello-v2a.png\" alt=\"13-hello-v2a\" width=\"695\" height=\"648\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hello-v2a.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/13-hello-v2a-300x280.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Check that the reply is shown in the nRF UART app:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-hello-android1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-386\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-hello-android1.png\" alt=\"14-hello-android\" width=\"700\" height=\"394\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-hello-android1.png 700w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/14-hello-android1-300x169.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/li>\n<li>Now we will see how the communication is performed. Set a breakpoint in the <strong>ble_nus_string_send()<\/strong> function and send a line of text from the COMx window:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-send.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-390\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-send.png\" alt=\"15-send\" width=\"695\" height=\"870\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-send.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/15-send-240x300.png 240w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a>Note that once you have stopped at a breakpoint in a Bluetooth-enabled application, resuming will most likely result in a reset, as the softdevice will detect inconsistencies due to missed interrupts. This is a known limitation of the Nordic nRF51 devices and can be partially worked around by setting PRIMASK register to 1 using the Watch window as described in the <a href=\"http:\/\/visualgdb.com\/tutorials\/arm\/nrf51\/mouse\/\">nRF51 Bluetooth LE Mouse tutorial<\/a>.<\/li>\n<li>Right-click at the rx_handles field and select &#8220;Show on Code Map&#8221;. Then display the functions using the field and the functions calling them:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-codemap.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-391\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-codemap.png\" alt=\"16-codemap\" width=\"695\" height=\"726\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-codemap.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/16-codemap-287x300.png 287w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>This reveals the <strong>rx_char_add()<\/strong> function that adds a proprietary characteristic (BLE_UUID_NUS_RX_CHARACTERISTIC) used by the Nordic UART App. When the firmware wants to send a string to the UART, it generates an update event for this characteristic and the App receives it and displays the text:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-charadd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-392\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-charadd.png\" alt=\"17-charadd\" width=\"695\" height=\"835\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-charadd.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/17-charadd-250x300.png 250w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>The Code Map has also revealed the <strong>on_write()<\/strong> function that is called when the UART App sets the BLE_UUID_NUS_TX_CHARACTERISTIC characteristic:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-write.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-393\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-write.png\" alt=\"18-write\" width=\"695\" height=\"833\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-write.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/18-write-250x300.png 250w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>Using the Code Map you can see that the <strong>data_handler<\/strong> field\u00a0 of <strong>ble_nus_s<\/strong> used by on_write() is initialized from the <strong>ble_nus_init_t::data_handler<\/strong> field that is in turn set in <strong>services_init()<\/strong> in the main.c file.<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-handler.png\"> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-394\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-handler.png\" alt=\"19-handler\" width=\"695\" height=\"804\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-handler.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/19-handler-259x300.png 259w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<li>The handler in the UART example simply prints the received string using the <strong>app_uart_put()<\/strong> function:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-handler-src.png\"> <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-395\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-handler-src.png\" alt=\"20-handler-src\" width=\"695\" height=\"607\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-handler-src.png 695w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2015\/08\/20-handler-src-300x262.png 300w\" sizes=\"(max-width: 695px) 100vw, 695px\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a UART-over-Bluetooth LE adapter using the nRF51-DK evaluation board from Nordic and VisualGDB. We<\/p>\n","protected":false},"author":1,"featured_media":397,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[53,96,56,95],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/369"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=369"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/369\/revisions"}],"predecessor-version":[{"id":396,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/369\/revisions\/396"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/397"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}