import 'dart:async'; import 'dart:convert' show utf8; import 'package:control_pad/control_pad.dart'; import 'package:control_pad/models/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_blue/flutter_blue.dart'; Future main() async { await SystemChrome.setPreferredOrientations( [DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft]); runApp(MainScreen()); } class MainScreen extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Joypad with BLE', debugShowCheckedModeBanner: false, home: JoyPad(), theme: ThemeData.dark(), ); } } class JoyPad extends StatefulWidget { @override _JoyPadState createState() => _JoyPadState(); } class _JoyPadState extends State { final String SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b"; final String CHARACTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"; final String TARGET_DEVICE_NAME = "ESP32 GET NOTI FROM DEVICE"; FlutterBlue flutterBlue = FlutterBlue.instance; StreamSubscription scanSubScription; BluetoothDevice targetDevice; BluetoothCharacteristic targetCharacteristic; String connectionText = ""; @override void initState() { super.initState(); startScan(); } startScan() { setState(() { connectionText = "Start Scanning"; }); scanSubScription = flutterBlue.scan().listen((scanResult) { if (scanResult.device.name == TARGET_DEVICE_NAME) { print('DEVICE found'); stopScan(); setState(() { connectionText = "Found Target Device"; }); targetDevice = scanResult.device; connectToDevice(); } }, onDone: () => stopScan()); } stopScan() { scanSubScription?.cancel(); scanSubScription = null; } connectToDevice() async { if (targetDevice == null) return; setState(() { connectionText = "Device Connecting"; }); await targetDevice.connect(); print('DEVICE CONNECTED'); setState(() { connectionText = "Device Connected"; }); discoverServices(); } disconnectFromDevice() { if (targetDevice == null) return; targetDevice.disconnect(); setState(() { connectionText = "Device Disconnected"; }); } discoverServices() async { if (targetDevice == null) return; List services = await targetDevice.discoverServices(); services.forEach((service) { // do something with service if (service.uuid.toString() == SERVICE_UUID) { service.characteristics.forEach((characteristic) { if (characteristic.uuid.toString() == CHARACTERISTIC_UUID) { targetCharacteristic = characteristic; writeData("Hi there, ESP32!!"); setState(() { connectionText = "All Ready with ${targetDevice.name}"; }); } }); } }); } writeData(String data) { if (targetCharacteristic == null) return; List bytes = utf8.encode(data); targetCharacteristic.write(bytes); } @override Widget build(BuildContext context) { JoystickDirectionCallback onDirectionChanged( double degrees, double distance) { String data = "Degree : ${degrees.toStringAsFixed(2)}, distance : ${distance.toStringAsFixed(2)}"; print(data); writeData(data); } PadButtonPressedCallback padBUttonPressedCallback( int buttonIndex, Gestures gesture) { String data = "buttonIndex : ${buttonIndex}"; print(data); writeData(data); } return Scaffold( appBar: AppBar( title: Text(connectionText), ), body: Container( child: targetCharacteristic == null ? Center( child: Text( "Waiting...", style: TextStyle(fontSize: 24, color: Colors.red), ), ) : Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ JoystickView( onDirectionChanged: onDirectionChanged, ), PadButtonsView( padButtonPressedCallback: padBUttonPressedCallback, ), ], ), ), ); } }