import 'dart:async'; import 'dart:io'; import 'package:esense_flutter/esense.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:sense_the_rhythm/arrows.dart'; import 'package:sense_the_rhythm/level.dart'; class ESenseInput { static final instance = ESenseInput._(); ESenseManager eSenseManager = ESenseManager('unknown'); ValueNotifier deviceStatus = ValueNotifier(''); StreamSubscription? subscription; String eSenseDeviceName = ''; bool connected = false; bool sampling = false; int sampleRate = 20; InputDirection inputDirection = InputDirection(); int x = 0; int y = 0; int z = 0; ESenseInput._() { _listenToESense(); } Future _askForPermissions() async { if (!Platform.isAndroid && !Platform.isIOS) return; if (!(await Permission.bluetoothScan.request().isGranted && await Permission.bluetoothConnect.request().isGranted && await Permission.bluetooth.request().isGranted)) { print( 'WARNING - no permission to use Bluetooth granted. Cannot access eSense device.'); } // for some strange reason, Android requires permission to location for Bluetooth to work.....? if (Platform.isAndroid) { if (!(await Permission.locationWhenInUse.request().isGranted)) { print( 'WARNING - no permission to access location granted. Cannot access eSense device.'); } } } void _listenToESense() { // if you want to get the connection events when connecting, // set up the listener BEFORE connecting... eSenseManager.connectionEvents.listen((event) { print('CONNECTION event: $event'); // when we're connected to the eSense device, we can start listening to events from it // if (event.type == ConnectionType.connected) _listenToESenseEvents(); connected = false; switch (event.type) { case ConnectionType.connected: deviceStatus.value = 'connected'; connected = true; _startListenToSensorEvents(); break; case ConnectionType.unknown: deviceStatus.value = 'unknown'; break; case ConnectionType.disconnected: deviceStatus.value = 'disconnected'; sampling = false; _pauseListenToSensorEvents(); break; case ConnectionType.device_found: deviceStatus.value = 'device_found'; break; case ConnectionType.device_not_found: deviceStatus.value = 'device_not_found'; break; } }); } Stream buttonEvents() { return eSenseManager.eSenseEvents .where((event) => event.runtimeType == ButtonEventChanged) .cast(); } void _startListenToSensorEvents() async { // // any changes to the sampling frequency must be done BEFORE listening to sensor events print('setting sampling frequency...'); bool successs = await eSenseManager.setSamplingRate(sampleRate); if (successs) { print('setSamplingRate success'); } else { print('setSamplingRate fail'); } // subscribe to sensor event from the eSense device subscription = eSenseManager.sensorEvents.listen((event) { // print('SENSOR event: $event'); if (event.gyro != null) { _parseGyroData(event.gyro!); } }); sampling = true; } void _pauseListenToSensorEvents() async { subscription?.cancel(); sampling = false; } void _parseGyroData(List data) { // Float value in deg/s = Gyro value / Gyro scale factor // The default configuration is +- 500deg/s for the gyroscope. x = (x + (15 * data[0] ~/ (500 * sampleRate))) % 360; y = (y + (15 * data[1] ~/ (500 * sampleRate))) % 360; z = (z + (15 * data[2] ~/ (500 * sampleRate))) % 360; print('$x, $y, $z'); // print('${(z.toDouble() / 500.0 * (1.0 / sampleRate.toDouble())) * 7.5}'); // print('${z.toDouble() / 500.0 * (1.0 / 10.0)}'); } void resetAngles() { inputDirection.reset(); x = 0; y = 0; z = 0; } InputDirection getInputDirection(ArrowDirection expect) { inputDirection.up = z > 270 && z < 340; inputDirection.down = z > 40 && z < 180; inputDirection.left = y > 40 && y < 180; inputDirection.right = y > 270 && y < 340; if (expect == ArrowDirection.up && inputDirection.up || expect == ArrowDirection.down && inputDirection.down) { y = 0; print("ehit"); } if (expect == ArrowDirection.left && inputDirection.left || expect == ArrowDirection.right && inputDirection.right) { z = 0; print("ehit"); } return inputDirection; } Future connectToESense(String deviceName) async { if (!connected) { await _askForPermissions(); print('Trying to connect to eSense device namend \'$deviceName\''); eSenseDeviceName = deviceName; eSenseManager.deviceName = deviceName; connected = await eSenseManager.connect(); print( 'Trying to connect to eSense device namend \'${eSenseManager.deviceName}\''); deviceStatus.value = connected ? 'connecting...' : 'connection failed'; print(deviceStatus.value); } } }