Bleno/Flutter - BLE communication - data transmission

518 Views Asked by At

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()
          );
  }
}
0

There are 0 best solutions below