Hi everyone and thank you for reading this.
So I have a Bleno file that configure the bluetooth for my raspberry pi 4 and wait for connections. I also have a flutter app using the flutter_blue library for bluetooth communication. The app search for available devices and connect to the selected one. After that I have a button to send data and disconnect to the device selected.
ISSUE: When I send data, I go trough the Characteristics and for each Characteristics the write properties is set to false. But in the Bleno file I set the Characteristic properties to 'write' so it should be true
new bleno.PrimaryService({
uuid: '1801',
characteristics: [
new bleno.Characteristic({
value: null,
uuid: '1801',
properties: ['write', 'writeWithoutResponse', 'read'],
onWriteRequest: (_, callback) => {
console.log('Write request received !');
callback();
}
}),
]
}),
I guess I'm missing something - but after a lot of research I can't solve my issue. I watch a few videos on YouTube that explain BLE and try some solutions find on StackOverflow but any of those solutions fix my issues.
Please notify me if my issues isn't clear enough.
Bleno file code
var bleno = require('bleno');
_startAdvertising = () => {
bleno.startAdvertising(
'RaspberryPI',
'1801'
);
}
bleno.on('stateChange', (state) => {
console.log('Bleno state changed. New state: ' + state);
if (state === 'poweredOn') {
_startAdvertising();
} else {
bleno.stopAdvertising();
}
});
bleno.on('accept', (clientAddr) => {
console.log('Stop advertising...');
bleno.stopAdvertising();
console.log('You are connected to the device: ' + clientAddr);
});
bleno.on('disconnect', (clientAddr) => {
console.log('You are disconnected from the device: ' + clientAddr);
_startAdvertising();
});
bleno.on('advertisingStop', (err) => {
console.log('Advertising stopped...');
});
bleno.on('advertisingStart', (err) => {
if (err) {
console.log('An error occured when advertising started ! ' + err);
return;
}
console.log('Configuring advertising...');
bleno.setServices([
new bleno.PrimaryService({
uuid: '1801',
characteristics: [
new bleno.Characteristic({
value: null,
uuid: '1801',
properties: ['write', 'writeWithoutResponse', 'read'],
onWriteRequest: (_, callback) => {
console.log('Write request received !');
callback();
}
}),
]
}),
]);
console.log('Advertising started...');
});
Flutter app code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SafeArea(child: BluetoothApp()),
);
}
}
class BluetoothApp extends StatefulWidget {
BluetoothApp() : super();
_BluetoothAppState createState() => _BluetoothAppState();
}
class _BluetoothAppState extends State<BluetoothApp> {
bool isBluetoothOn = false;
bool isPairing = false;
bool isPaired = false;
bool isScanning = false;
FlutterBlue _blue = FlutterBlue.instance;
List<BluetoothDevice> _devicesFounded = List<BluetoothDevice>();
BluetoothDevice _device;
@override
void initState() {
super.initState();
_blue.isOn.then((state) {
setState(() {
isBluetoothOn = state;
});
});
_blue.isScanning.listen((event) {
setState(() {
isScanning = event;
});
});
_blue.state.listen((state) {
setState(() {
if (state == BluetoothState.off) {
isBluetoothOn = false;
} else {
isBluetoothOn = true;
}
});
});
}
void _scan() {
print('Scanning...');
_devicesFounded.clear();
_blue.startScan();
_blue.scanResults.listen((scan) {
scan.forEach((element) {
if (!_devicesFounded.contains(element.device)) {
setState(() {
_devicesFounded.add(element.device);
});
}
});
});
}
Widget _displayDevices() {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _devicesFounded.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
child: Card(
elevation: 4,
child: ListTile(
leading: Icon(Icons.devices),
title: Text(_devicesFounded[index].name.isEmpty
? "Unknow device"
: _devicesFounded[index].name),
subtitle: Text(_devicesFounded[index].id.toString()),
onTap: () async {
setState(() {
_device = _devicesFounded[index];
isPairing = true;
});
await _device.connect();
setState(() {
isPairing = false;
isPaired = true;
});
},
),
),
);
},
);
}
void _discoverServices(BluetoothDevice device) async {
BluetoothCharacteristic bluetoothCharacteristic;
List<BluetoothService> services = await device.discoverServices();
services.forEach((service) {
service.characteristics.forEach((servChar) async {
print(servChar.properties.toString());
print('Properties WRITE = ' + servChar.properties.write.toString());
if (servChar.properties.write) {
try {
await servChar.write(utf8.encode("Hello World"));
} catch (err) {
print('\n\nAn error occured: ' + err.toString() + '\n\n');
}
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isScanning) {
_scan();
setState(() {
isScanning = true;
});
} else {
_blue.stopScan();
setState(() {
isScanning = false;
});
}
},
child: isScanning ? Icon(Icons.pause) : Icon(Icons.play_arrow)),
body: !isBluetoothOn
? Center(child: Text('Please turn on the bluetooth !'))
: isPairing
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
Text('Connecting to the device...')
]),
)
: isPaired
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('You are connected to the device: ' +
_device.name),
FlatButton(
child: Text('Send data'),
onPressed: () async {
await _discoverServices(_device);
},
),
FlatButton(
child: Text('Disconnect'),
onPressed: () async {
setState(() {
isPaired = false;
});
await _device.disconnect();
},
)
]),
)
: _displayDevices()
);
}
}