Photo by Victor Aznabaev on Unsplash

The late night tinkering projects # 11: Arduino + Flutter = 💙

Juna Salviati
2 min readAug 30, 2020


Arduino Nano 33 Sense BLE comes with a lot of nice onboard sensors you can use to experiment and have fun.

This time, just to experiment with an onboard temperature sensor, you will try to publish a simple service to read temperature and to develop a very basic Flutter app to display the value on screen.

BLE for dummies

Without going into too much details, Bluetooth communication is similar to client/server communication.

The server (the BLE peripheral, Arduino in this case) makes data available to the client (the central device, the mobile phone in this case) in an exclusive way (i.e. the server can connect only to one device at time; the devices can be connected to multiple peripherals.

A characteristic is an attribute containing only a value ( it describes some kind of value that can be received from the device (i.e: the apparent wind speed, the heart rate lower limit…). Characteristics are stored in a lookup data table and are identified with a UUID.

A service is just a logical collection of characteristics (, for example “Alert notification service” or “Battery service”,“Environmental service” and so on…

The BLE peripheral advertises itself and when a central connects, the connection is established. From that moment, the communication can be bidirectional.

The Arduino code

Comments in code should be enough to understand its behaviour. There is something that it can be useful to note: you are going to publish a standard “temperature” characteristic (0x2A6E) in a standard “Environmental sensing” service (0x181A).

Now on with the Flutter code.

The Flutter code

The following is a very basic Flutter code to connect to 0x181A service to read read 0x2A6E (temperature) characteristic.

It makes use of FlutterReactiveBle package to use mobile device BLE.

What is worth to comment here is the ability to scan for specific advertising peripherals with specific scan modes:

withServices: [],
scanMode: ScanMode.lowLatency,
_requireLocationServicesEnabled: true)

and the connection to a specific characteristic in a specific service:

final characteristic = QualifiedCharacteristic(
serviceId: Uuid.parse("181A"),
characteristicId: Uuid.parse("2A6E"),
final response = await _ble.readCharacteristic(characteristic);

This is in fact a one-time read application because the code connects to the peripheral and then disconnects.

If the user wants to read the sensor value again, another scan is required (ameliorable!).

And here’s the result!

You can find the code at:



Juna Salviati

Full-time Human-computer interpreter. Opinions are my own.