Bluetooth Low Energy Development with Flutter and CircuitPython

Eric Pietrowicz
3 min readNov 5, 2019

Follow along with my latest posts here.

Flutter is a relatively new framework that is intended to be completely cross platform. Ideally, the same code base (written in Dart) will persist across the Android, iOS, and the web. One of Flutter’s main advantages is its already quite mature package ecosystem. Here we’re going to focus on Flutter Blue, the package used for Bluetooth Low Energy communication.

Let’s start by setting up a BLE CircuitPython device as our peripheral to keep things simple. Setup a Bluetooth Enabled CircuitPython board by following one of many guides (like here: https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpython) and upload the following code to it:

I’m using the nrf52840 USB Dongle (https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) flashed with CircuitPython.

The setup procedure for this particular device is described here: https://medium.com/@pietrowicz.eric/circuit-python-on-nrf52840-usb-dongle-with-jlink-80a7d3a88954

The USB dongle has an on-board RGB LED (this RGB module is low-side driven) which I’m controlling based on the received utf-8bit encoded commands from the Flutter app. The peripheral is broadcasting a UART service developed by Nordic acting as a UART serial port. This will matter more when we move into Dart.

While the example program in the Flutter Blue repository is useful, it’s needlessly complex when we’re trying to interact with our own Bluetooth peripheral design. Instead, we’ll start by using the application developed by 0015 (https://github.com/0015) called Flutter_JoyPad.

In the following section we’ll break down this code and modify it to connect with our peripheral USB dongle we deployed above. First, let’s grab some information about the CircuitPython device. Start by downloading nRFConnect on your phone. When its scan has completed, scroll through the available devices until you find something resembling “CIRCUITPY”. It might be truncated as shown below:

The device to look for on the Connect app

Connect to the device and swipe left to reveal the “Services” screen.

The services screen shows the details of the advertising packet from the CircuitPython device

Take note of the:

  • Nordic UART Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
  • Nordic UART Rx Characteristic UUID: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
  • Device Name: CIRCU

We now need to modify the flutter_app_joypad_ble code to scan for the BLE peripheral we set up. Clone the repository from the link above. The following lines of code are found in the flutter_app_joypad_ble/lib/main.dart file.

Notice that lines 36–38 take in the details that we discovered in the nRFConnect app. Change those to match what the nRFConnect app displayed. Make sure that the UUIDs are all lower case. The Flutter plugin will not recognize uppercase UUIDs.

We also need to change the PadButtonPressedCallback function around line 140 (reflected above) to correspond to the commands we hard coded into the CircuitPython device. I replaced the PadButtonPressedCallback function with the code that follows:

When running the Flutter app on an external device, we are now able to send data to a peripheral device via BLE to control an RGB LED. This is a great starting point for customization.

Check out the repository I created to control a servo motor with a similar setup.

--

--