Skip to content

Commit 5c9f425

Browse files
authored
feat: added Accelerometer screen (fossasia#2709)
1 parent 8fbccb5 commit 5c9f425

File tree

10 files changed

+395
-0
lines changed

10 files changed

+395
-0
lines changed

assets/images/phone_x_axis.png

23.1 KB
Loading

assets/images/phone_y_axis.png

17.9 KB
Loading

assets/images/phone_z_axis.png

21.4 KB
Loading

lib/constants.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,11 @@ List<String> connectWithUs = [
133133
'Developers'
134134
];
135135
String softwareLicenses = 'Software Licenses';
136+
String accelerometer = 'Accelerometer';
137+
String xAxis = 'x';
138+
String yAxis = 'y';
139+
String zAxis = 'z';
140+
String timeAxisLabel = 'Time(s)';
141+
String accelerationAxisLabel = 'm/s²';
142+
String minValue = 'Min: ';
143+
String maxValue = 'Max: ';

lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:provider/provider.dart';
33
import 'package:pslab/providers/board_state_provider.dart';
44
import 'package:pslab/providers/locator.dart';
5+
import 'package:pslab/view/accelerometer_screen.dart';
56
import 'package:pslab/view/connect_device_screen.dart';
67
import 'package:pslab/view/faq_screen.dart';
78
import 'package:pslab/view/instruments_screen.dart';
@@ -49,6 +50,7 @@ class MyApp extends StatelessWidget {
4950
'/settings': (context) => const SettingsScreen(),
5051
'/aboutUs': (context) => const AboutUsScreen(),
5152
'/softwareLicenses': (context) => const SoftwareLicensesScreen(),
53+
'/accelerometer': (context) => const AccelerometerScreen(),
5254
},
5355
);
5456
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import 'dart:async';
2+
import 'dart:math';
3+
import 'package:fl_chart/fl_chart.dart';
4+
import 'package:flutter/material.dart';
5+
import 'package:pslab/others/logger_service.dart';
6+
import 'package:sensors_plus/sensors_plus.dart';
7+
import 'package:flutter/foundation.dart';
8+
9+
class AccelerometerStateProvider extends ChangeNotifier {
10+
AccelerometerEvent _accelerometerEvent =
11+
AccelerometerEvent(0, 0, 0, DateTime.now());
12+
StreamSubscription? _accelerometerSubscription;
13+
final List<double> _xData = [];
14+
final List<double> _yData = [];
15+
final List<double> _zData = [];
16+
17+
final List<FlSpot> xData = [];
18+
final List<FlSpot> yData = [];
19+
final List<FlSpot> zData = [];
20+
21+
final int _maxLength = 50;
22+
double _xMin = 0, _xMax = 0;
23+
double _yMin = 0, _yMax = 0;
24+
double _zMin = 0, _zMax = 0;
25+
26+
void initializeSensors() {
27+
_accelerometerSubscription = accelerometerEventStream().listen(
28+
(event) {
29+
_accelerometerEvent = event;
30+
_updateData();
31+
notifyListeners();
32+
},
33+
onError: (error) {
34+
logger.e(
35+
"Accelerometer error: $error",
36+
);
37+
},
38+
cancelOnError: true,
39+
);
40+
}
41+
42+
void disposeSensors() {
43+
_accelerometerSubscription?.cancel();
44+
}
45+
46+
@override
47+
void dispose() {
48+
disposeSensors();
49+
super.dispose();
50+
}
51+
52+
void _updateData() {
53+
final x = _accelerometerEvent.x;
54+
final y = _accelerometerEvent.y;
55+
final z = _accelerometerEvent.z;
56+
57+
_xData.add(x);
58+
_yData.add(y);
59+
_zData.add(z);
60+
61+
if (_xData.length > _maxLength) _xData.removeAt(0);
62+
if (_yData.length > _maxLength) _yData.removeAt(0);
63+
if (_zData.length > _maxLength) _zData.removeAt(0);
64+
65+
_xMin = _xData.reduce(min);
66+
_xMax = _xData.reduce(max);
67+
_yMin = _yData.reduce(min);
68+
_yMax = _yData.reduce(max);
69+
_zMin = _zData.reduce(min);
70+
_zMax = _zData.reduce(max);
71+
72+
xData.clear();
73+
yData.clear();
74+
zData.clear();
75+
76+
for (int i = 0; i < _xData.length; i++) {
77+
xData.add(FlSpot(i.toDouble(), _xData[i]));
78+
yData.add(FlSpot(i.toDouble(), _yData[i]));
79+
zData.add(FlSpot(i.toDouble(), _zData[i]));
80+
}
81+
82+
notifyListeners();
83+
}
84+
85+
List<FlSpot> getAxisData(String axis) {
86+
switch (axis) {
87+
case 'x':
88+
return xData;
89+
case 'y':
90+
return yData;
91+
case 'z':
92+
return zData;
93+
default:
94+
return [];
95+
}
96+
}
97+
98+
double getMin(String axis) {
99+
switch (axis) {
100+
case 'x':
101+
return _xMin;
102+
case 'y':
103+
return _yMin;
104+
case 'z':
105+
return _zMin;
106+
default:
107+
return 0.0;
108+
}
109+
}
110+
111+
double getMax(String axis) {
112+
switch (axis) {
113+
case 'x':
114+
return _xMax;
115+
case 'y':
116+
return _yMax;
117+
case 'z':
118+
return _zMax;
119+
default:
120+
return 0.0;
121+
}
122+
}
123+
124+
double getCurrent(String axis) {
125+
switch (axis) {
126+
case 'x':
127+
return _accelerometerEvent.x;
128+
case 'y':
129+
return _accelerometerEvent.y;
130+
case 'z':
131+
return _accelerometerEvent.z;
132+
default:
133+
return 0.0;
134+
}
135+
}
136+
137+
int getDataLength(String axis) {
138+
switch (axis) {
139+
case 'x':
140+
return xData.length;
141+
case 'y':
142+
return yData.length;
143+
case 'z':
144+
return zData.length;
145+
default:
146+
return 0;
147+
}
148+
}
149+
}

lib/view/accelerometer_screen.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:provider/provider.dart';
3+
import 'package:pslab/constants.dart';
4+
import 'package:pslab/providers/accelerometer_state_provider.dart';
5+
import 'package:pslab/view/widgets/common_scaffold_widget.dart';
6+
import 'package:pslab/view/widgets/accelerometer_card.dart';
7+
8+
class AccelerometerScreen extends StatefulWidget {
9+
const AccelerometerScreen({super.key});
10+
11+
@override
12+
State<StatefulWidget> createState() => _AccelerometerScreenState();
13+
}
14+
15+
class _AccelerometerScreenState extends State<AccelerometerScreen> {
16+
@override
17+
Widget build(BuildContext context) {
18+
return MultiProvider(
19+
providers: [
20+
ChangeNotifierProvider<AccelerometerStateProvider>(
21+
create: (_) => AccelerometerStateProvider()..initializeSensors(),
22+
),
23+
],
24+
child: CommonScaffold(
25+
title: accelerometer,
26+
body: SafeArea(
27+
child: Column(
28+
children: [
29+
Expanded(
30+
child: AccelerometerCard(color: Colors.yellow, axis: xAxis)),
31+
Expanded(
32+
child: AccelerometerCard(color: Colors.purple, axis: yAxis)),
33+
Expanded(
34+
child: AccelerometerCard(color: Colors.green, axis: zAxis)),
35+
],
36+
))),
37+
);
38+
}
39+
}

lib/view/instruments_screen.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ class _InstrumentsScreenState extends State<InstrumentsScreen> {
2626
(route) => route.isFirst,
2727
);
2828
}
29+
case 7:
30+
if (Navigator.canPop(context) &&
31+
ModalRoute.of(context)?.settings.name == '/accelerometer') {
32+
Navigator.popUntil(context, ModalRoute.withName('/accelerometer'));
33+
} else {
34+
Navigator.pushNamedAndRemoveUntil(
35+
context,
36+
'/accelerometer',
37+
(route) => route.isFirst,
38+
);
39+
}
2940
break;
3041
default:
3142
break;

0 commit comments

Comments
 (0)