Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,10 @@ String lx = 'Lx';
String maxScaleError = 'Max Scale';
String lightSensorError = 'Light sensor error:';
String lightSensorInitialError = 'Failed to initialize light sensor:';
String barometerTitle = 'Barometer';
String atm = 'atm';
String barometerSensorInitialError = 'Failed to initialize barometer sensor:';
String barometerSensorError = 'Barometer sensor error occurred';
String barometerNotAvailable = 'Barometer sensor not available on this device';
String meterUnit = 'm';
String altitudeLabel = 'Altitude';
2 changes: 2 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
import 'package:pslab/providers/board_state_provider.dart';
import 'package:pslab/providers/locator.dart';
import 'package:pslab/view/accelerometer_screen.dart';
import 'package:pslab/view/barometer_screen.dart';
import 'package:pslab/view/connect_device_screen.dart';
import 'package:pslab/view/faq_screen.dart';
import 'package:pslab/view/gyroscope_screen.dart';
Expand Down Expand Up @@ -53,6 +54,7 @@ class MyApp extends StatelessWidget {
'/accelerometer': (context) => const AccelerometerScreen(),
'/gyroscope': (context) => const GyroscopeScreen(),
'/luxmeter': (context) => const LuxMeterScreen(),
'/barometer': (context) => const BarometerScreen(),
},
);
}
Expand Down
166 changes: 166 additions & 0 deletions lib/providers/barometer_state_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import 'dart:async';
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:pslab/others/logger_service.dart';
import 'package:sensors_plus/sensors_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:pslab/constants.dart';

class BarometerStateProvider extends ChangeNotifier {
double _currentPressure = 0.0;
StreamSubscription? _barometerSubscription;
Timer? _timeTimer;
final List<double> _pressureData = [];
final List<double> _timeData = [];
final List<FlSpot> pressureChartData = [];
double _startTime = 0;
double _currentTime = 0;
final int _maxLength = 50;
double _pressureMin = 0;
double _pressureMax = 0;
double _pressureSum = 0;
int _dataCount = 0;
bool _sensorAvailable = true;

Function(String)? onSensorError;

void initializeSensors({Function(String)? onError}) {
onSensorError = onError;

try {
_startTime = DateTime.now().millisecondsSinceEpoch / 1000.0;
_timeTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
_currentTime =
(DateTime.now().millisecondsSinceEpoch / 1000.0) - _startTime;
if (_sensorAvailable) {
_updateData();
}
notifyListeners();
});

_barometerSubscription = barometerEventStream().listen(
(BarometerEvent event) {
_currentPressure = event.pressure / 1013.25;
_sensorAvailable = true;
notifyListeners();
},
onError: (error) {
logger.e("$barometerSensorError $error");
_handleSensorError(error);
},
cancelOnError: false,
);
} catch (e) {
logger.e("$barometerSensorInitialError $e");
_handleSensorError(e);
}
}

void _handleSensorError(dynamic error) {
_sensorAvailable = false;
String errorString = error.toString().toLowerCase();
if (errorString.contains('not available') ||
errorString.contains('not supported') ||
errorString.contains('sensor not found') ||
errorString.contains('no sensor')) {
_handleSensorNotAvailable();
} else {
onSensorError?.call(barometerSensorError);
}
}

void _handleSensorNotAvailable() {
_sensorAvailable = false;
onSensorError?.call(barometerNotAvailable);
}

void disposeSensors() {
_barometerSubscription?.cancel();
_timeTimer?.cancel();
}

@override
void dispose() {
disposeSensors();
super.dispose();
}

void _updateData() {
if (!_sensorAvailable) return;

final pressure = _currentPressure;
final time = _currentTime;
_pressureData.add(pressure);
_timeData.add(time);
_pressureSum += pressure;
_dataCount++;
if (_pressureData.length > _maxLength) {
final removedValue = _pressureData.removeAt(0);
_timeData.removeAt(0);
_pressureSum -= removedValue;
_dataCount--;
}
if (_pressureData.isNotEmpty) {
_pressureMin = _pressureData.reduce(min);
_pressureMax = _pressureData.reduce(max);
}
pressureChartData.clear();
for (int i = 0; i < _pressureData.length; i++) {
pressureChartData.add(FlSpot(_timeData[i], _pressureData[i]));
}
notifyListeners();
}

double _pressureToAltitude(double pressureAtm) {
const double seaLevelPressureAtm = 1.0;
const double temperatureK = 288.15;
const double lapseRate = 0.0065;
const double gasConstant = 287.05;
const double gravity = 9.80665;

if (pressureAtm <= 0) return 0.0;

double altitude = (temperatureK / lapseRate) *
(1 -
pow(pressureAtm / seaLevelPressureAtm,
(gasConstant * lapseRate) / gravity));

return altitude;
}

double getCurrentPressure() => _currentPressure;
double getMinPressure() => _pressureMin;
double getMaxPressure() => _pressureMax;
double getAveragePressure() =>
_dataCount > 0 ? _pressureSum / _dataCount : 0.0;

double getCurrentAltitude() => _pressureToAltitude(_currentPressure);
double getMinAltitude() =>
_pressureMin > 0 ? _pressureToAltitude(_pressureMax) : 0.0;
Comment thread
Yugesh-Kumar-S marked this conversation as resolved.
Outdated
double getMaxAltitude() =>
_pressureMax > 0 ? _pressureToAltitude(_pressureMin) : 0.0;
double getAverageAltitude() => _pressureToAltitude(getAveragePressure());

double getMaxAltitudeForChart() =>
_pressureMax > 0 ? _pressureToAltitude(0) : 10000.0;
double getMinAltitudeForChart() =>
_pressureMin > 0 ? _pressureToAltitude(_pressureMax * 1.1) : 0.0;
double getAltitudeInterval() {
double maxAlt = getMaxAltitudeForChart();
return maxAlt > 0 ? (maxAlt / 5) : 2000;
}

List<FlSpot> getPressureChartData() => pressureChartData;
int getDataLength() => pressureChartData.length;
double getCurrentTime() => _currentTime;
double getMaxTime() => _timeData.isNotEmpty ? _timeData.last : 0;
double getMinTime() => _timeData.isNotEmpty ? _timeData.first : 0;
double getTimeInterval() {
if (_currentTime <= 10) return 2;
if (_currentTime <= 30) return 5;
return 10;
}

bool get sensorAvailable => _sensorAvailable;
}
Loading