Skip to content

Commit 1ae0fd0

Browse files
committed
completed mq-135 sensor
1 parent 7d07ca4 commit 1ae0fd0

8 files changed

Lines changed: 916 additions & 226 deletions

lib/l10n/app_en.arb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,14 @@
696696
"comingSoon": "Coming Soon",
697697
"startRecording": "Start Recording",
698698
"stopRecording": "Stop Recording",
699-
"gasSensorGuideIntro": "To use this instrument, you need an MQ-135 semiconductor gas sensor.",
700-
"gasSensorGuideDetail": "The MQ-135 is primarily intended for detecting flammable gases and broad air quality, but its readings can be mathematically translated to estimate CO2 Parts Per Million (PPM).",
699+
"gasSensorGuideIntro": "The MQ-135 is a broad-spectrum semiconductor gas sensor. It utilizes a Tin Dioxide (SnO2) sensitive layer whose electrical conductivity changes when exposed to clean air versus air polluted with target gases.",
700+
"gasSensorGuideDetail": "The Mathematical Formula:\nThe sensor does not read gases individually. Instead, any detectable gas causes the sensor's internal resistance (Rs) to drop relative to its baseline resistance in fresh air (R0).\n\nppm = a * (Rs / R0)^b\n\nWhere 'a' represents the scaling multiplier and 'b' represents the curve slope. By altering these coefficients based on the manufacturer's datasheet curves, the app can calculate estimations for different gases:\n• Carbon Dioxide (CO2): a ≈ 110.5, b ≈ -2.86\n• Ammonia (NH3): a ≈ 102.2, b ≈ -2.47\n• Alcohol / Ethanol: a ≈ 75.4, b ≈ -3.12",
701701
"gasSensorGuideConnectLabel": "How to connect:",
702702
"gasSensorGuideConnectStep1": "1. Connect the PSLab +5V pin to the sensor's VCC pin.",
703703
"gasSensorGuideConnectStep2": "2. Connect the PSLab GND pin to the sensor's GND pin.",
704704
"gasSensorGuideConnectStep3": "3. Connect the PSLab CH1 pin to the sensor's Analog Out (A0) pin.",
705-
"gasSensorGuideWarning": "Note: Readings are estimated based on default load and baseline resistances and assume a fresh air environment during calibration.",
705+
"gasSensorGuideWarning": "Important Scientific Limitation:\nBecause the sensor reacts to all of these gases simultaneously on the same electrical line, it cannot differentiate between them. For example, if you configure to display Ammonia (NH3) from configuration menu, but alcohol fumes enter the room, the sensor will misinterpret the resistance drop and show a massive, false spike in Ammonia.\n\nTherefore, all target-specific outputs are mathematical approximations assuming a strictly controlled background environment."
706+
,
706707
"ppmCO2" : "PPM CO₂",
707708
"noGasSensor" : "Gas Sensor Unavailable Please connect Gas Sensor",
708709
"tsl2561" : "TSL2561",
@@ -772,5 +773,6 @@
772773
"eco2" : "eCO2",
773774
"tvoc" : "TVOC",
774775
"ppb" : "ppb",
775-
"concentrationPpm" : "Concentration (PPM)"
776+
"concentrationPpm" : "Concentration (PPM)",
777+
"airQuality" : "Air Quality"
776778
}

lib/models/gas_sensor_config.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class GasSensorConfig {
2+
final int updatePeriod;
3+
final String activeGas;
4+
final bool includeLocationData;
5+
6+
const GasSensorConfig({
7+
this.updatePeriod = 1000,
8+
this.activeGas = 'Raw',
9+
this.includeLocationData = true,
10+
});
11+
12+
GasSensorConfig copyWith({
13+
int? updatePeriod,
14+
String? activeGas,
15+
bool? includeLocationData,
16+
}) {
17+
return GasSensorConfig(
18+
updatePeriod: updatePeriod ?? this.updatePeriod,
19+
activeGas: activeGas ?? this.activeGas,
20+
includeLocationData: includeLocationData ?? this.includeLocationData,
21+
);
22+
}
23+
24+
Map<String, dynamic> toJson() {
25+
return {
26+
'updatePeriod': updatePeriod,
27+
'activeGas': activeGas,
28+
'includeLocationData': includeLocationData,
29+
};
30+
}
31+
32+
factory GasSensorConfig.fromJson(Map<String, dynamic> json) {
33+
return GasSensorConfig(
34+
updatePeriod: json['updatePeriod'] ?? 1000,
35+
activeGas: json['activeGas'] ?? 'Raw',
36+
includeLocationData: json['includeLocationData'] ?? true,
37+
);
38+
}
39+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'dart:convert';
3+
import 'package:shared_preferences/shared_preferences.dart';
4+
import 'package:pslab/others/logger_service.dart';
5+
import '../models/gas_sensor_config.dart';
6+
7+
class GasSensorConfigProvider extends ChangeNotifier {
8+
GasSensorConfig _config = const GasSensorConfig();
9+
10+
GasSensorConfig get config => _config;
11+
12+
GasSensorConfigProvider() {
13+
_loadConfigFromPrefs();
14+
}
15+
16+
Future<void> _loadConfigFromPrefs() async {
17+
try {
18+
final prefs = await SharedPreferences.getInstance();
19+
final jsonString = prefs.getString('gas_sensor_config');
20+
if (jsonString != null) {
21+
final Map<String, dynamic> jsonMap = json.decode(jsonString);
22+
_config = GasSensorConfig.fromJson(jsonMap);
23+
logger.d("Loaded GasSensorConfig: ${_config.toJson()}");
24+
notifyListeners();
25+
}
26+
} catch (e) {
27+
logger.e("Error loading GasSensorConfig from prefs: $e");
28+
_config = const GasSensorConfig();
29+
notifyListeners();
30+
}
31+
}
32+
33+
Future<void> _saveConfigToPrefs() async {
34+
try {
35+
final prefs = await SharedPreferences.getInstance();
36+
await prefs.setString('gas_sensor_config', json.encode(_config.toJson()));
37+
logger.d("Saved GasSensorConfig: ${_config.toJson()}");
38+
} catch (e) {
39+
logger.e("Error saving GasSensorConfig to prefs: $e");
40+
}
41+
}
42+
43+
void updateUpdatePeriod(int updatePeriod) {
44+
_config = _config.copyWith(updatePeriod: updatePeriod);
45+
notifyListeners();
46+
_saveConfigToPrefs();
47+
}
48+
49+
void updateActiveGas(String activeGas) {
50+
_config = _config.copyWith(activeGas: activeGas);
51+
notifyListeners();
52+
_saveConfigToPrefs();
53+
}
54+
55+
void updateIncludeLocationData(bool includeLocationData) {
56+
_config = _config.copyWith(includeLocationData: includeLocationData);
57+
notifyListeners();
58+
_saveConfigToPrefs();
59+
}
60+
61+
void resetToDefaults() {
62+
_config = const GasSensorConfig();
63+
notifyListeners();
64+
_saveConfigToPrefs();
65+
}
66+
}

0 commit comments

Comments
 (0)