Skip to content
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0aa77ec
First commit
ctrlVnt May 19, 2026
f0c2494
Dust implementation without logic
ctrlVnt May 20, 2026
f14245c
Added psLab ch1 listen
ctrlVnt May 20, 2026
d1edc47
Solved workflow issues
ctrlVnt May 20, 2026
fbf5683
First commit
ctrlVnt May 19, 2026
4a72ace
Dust implementation without logic
ctrlVnt May 20, 2026
7a32906
Added psLab ch1 listen
ctrlVnt May 20, 2026
b08d28f
Solved workflow issues
ctrlVnt May 20, 2026
e4c0193
Merge remote-tracking branch 'origin/dust-sensor' into dust-sensor
ctrlVnt May 21, 2026
c4bf5f7
Merge branch 'main' into dust-sensor
marcnause May 24, 2026
bcbd26b
Deleted built-in option
ctrlVnt May 27, 2026
eb78982
Merge branch 'main' into dust-sensor
marcnause May 30, 2026
e286bd6
Merge branch 'main' into dust-sensor
marcnause Jun 1, 2026
f48b63a
New implementation UART
ctrlVnt Jun 4, 2026
589921b
Merge branch 'main' into dust-sensor
ctrlVnt Jun 4, 2026
6bea87a
Merge branch 'main' into dust-sensor
ctrlVnt Jun 9, 2026
96fce79
dart format
ctrlVnt Jun 9, 2026
6b95572
dart format
ctrlVnt Jun 9, 2026
bbda066
Merge branch 'main' into dust-sensor
marcnause Jun 10, 2026
f01370d
Added getUART2BytesAvailable method
ctrlVnt Jun 11, 2026
8e22aba
Merge branch 'main' into dust-sensor
ctrlVnt Jun 11, 2026
888f997
Merge branch 'main' into dust-sensor
marcnause Jun 11, 2026
447338e
New getbyte return
ctrlVnt Jun 12, 2026
adf4055
Merge branch 'main' into dust-sensor
marcnause Jun 14, 2026
6011116
fix log message
marcnause Jun 14, 2026
0f74cc7
Merge branch 'main' into dust-sensor
marcnause Jun 18, 2026
290d4f0
Merge branch 'main' into dust-sensor
ctrlVnt Jun 19, 2026
5046655
Merge branch 'main' into dust-sensor
mariobehling Jun 23, 2026
669015d
Merge branch 'main' into dust-sensor
ctrlVnt Jun 27, 2026
abfc280
Merge branch 'main' into dust-sensor
ctrlVnt Jun 29, 2026
15c1680
workflow errors
ctrlVnt Jun 29, 2026
06ce577
yaml function for MacOS
ctrlVnt Jul 1, 2026
012d5e1
Added some tests
ctrlVnt Jul 2, 2026
8a12768
experimental setup
ctrlVnt Jul 4, 2026
3db7b1b
Merge remote-tracking branch 'origin/dust-sensor' into dust-sensor
ctrlVnt Jul 4, 2026
a7857b7
Merge branch 'main' into dust-sensor
ctrlVnt Jul 6, 2026
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
44 changes: 44 additions & 0 deletions lib/communication/science_lab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1392,4 +1392,48 @@ class ScienceLab {
logger.e("Error in servo4(): $e");
}
}

Future<void> configureUART({required int baudRate}) async {
if (!isConnected()) return;

try {
mPacketHandler.sendByte(mCommandsProto.uart2);
mPacketHandler.sendByte(mCommandsProto.setBaud);
mPacketHandler.sendInt(baudRate);
Comment on lines +1396 to +1402

await mPacketHandler.getAcknowledgement();
logger.i("UART2 peripheral successfully configured at $baudRate baud.");
} catch (e) {
logger.e("Error configuring UART2: $e");
rethrow;
}
}

Future<int> getUART2BytesAvailable() async {
if (!isConnected()) return 0;
try {
mPacketHandler.sendByte(mCommandsProto.uart2);
mPacketHandler.sendByte(mCommandsProto.readUart2Status);
return await mPacketHandler.getByte();
} catch (e) {
logger.e("Error reading UART2 status: $e");
return 0;
}
}

Future<List<int>> readUARTBytes(int bytesToRead) async {
if (!isConnected()) return [];

try {
mPacketHandler.sendByte(mCommandsProto.uart2);
mPacketHandler.sendByte(mCommandsProto.readByte);
mPacketHandler.sendByte(bytesToRead);
Uint8List rawBuffer = Uint8List(bytesToRead + 1); // +1 for ACK
await mPacketHandler.read(rawBuffer, bytesToRead + 1);
return rawBuffer.sublist(0, bytesToRead).map((b) => b & 0xFF).toList();
} catch (e) {
logger.e("Error reading bytes from UART2: $e");
return [];
}
}
}
10 changes: 10 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
"manualMode": "Manual Mode",
"frequencyChange": "Stop playback to change frequency.",
"playBackStop": "Playback stopped",
"dustSensorIntro": "Connect pins according to pin diagram and start measuring. Power up the sensor using VCC pin in PSLab and connect data pin to CH1. Make sure the ground wire is connected to one of the GND pins in PSLab.",
"soundMeterIntro": "Sound meter Introduction",
"soundMeterDescFull": "To measure the loudness in the environment in decibel(dB)",
"luxMeterDescFull": "The Lux meter can be used to measure the ambient light intensity. This instruments is compatible with either the built-in light sensor on any Android device or the BH-1750 light sensor.",
Expand Down Expand Up @@ -695,6 +696,15 @@
"comingSoon": "Coming Soon",
"startRecording": "Start Recording",
"stopRecording": "Stop Recording",
"ppm": "PPM",
"airQuality": "Air Quality",
"good": "Good",
"moderate": "Moderate",
"unhealthy": "Unhealthy",
"hazardous": "Hazardous",
"dustSensorConfig": "Dust Sensor Configurations",
"dustUpdatePeriodHint": "Please provide time interval at which data will be updated (100 ms to 1000 ms)",
"dustHighLimitHint": "Please provide the maximum limit of PPM value to be recorded (0.0 PPM to 5.0 PPM)",
"gasSensorGuideIntro": "To use this instrument, you need an MQ-135 semiconductor gas sensor.",
"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).",
"gasSensorGuideConnectLabel": "How to connect:",
Expand Down
3 changes: 3 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:pslab/providers/settings_config_provider.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/dust_sensor_screen.dart';
import 'package:pslab/view/faq_screen.dart';
import 'package:pslab/view/gas_sensor_screen.dart';
import 'package:pslab/view/gyroscope_screen.dart';
Expand Down Expand Up @@ -118,6 +119,8 @@ class MyApp extends StatelessWidget {
const _LocaleAware(child: LogicAnalyzerScreen()),
'/powerSource': (context) =>
const _LocaleAware(child: PowerSourceScreen()),
'/dustsensor': (context) =>
const _LocaleAware(child: DustSensorScreen()),
'/compass': (context) =>
const _LocaleAware(child: CompassScreen()),
'/connectDevice': (context) =>
Expand Down
45 changes: 45 additions & 0 deletions lib/models/dust_sensor_config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class DustSensorConfig {
final int updatePeriod;
final double highLimit;
final String activeSensor;
final bool includeLocationData;

const DustSensorConfig({
this.updatePeriod = 1000,
this.highLimit = 4.0,
this.activeSensor = 'In-built Sensor',
this.includeLocationData = true,
});

DustSensorConfig copyWith({
int? updatePeriod,
double? highLimit,
String? activeSensor,
bool? includeLocationData,
}) {
return DustSensorConfig(
updatePeriod: updatePeriod ?? this.updatePeriod,
highLimit: highLimit ?? this.highLimit,
activeSensor: activeSensor ?? this.activeSensor,
includeLocationData: includeLocationData ?? this.includeLocationData,
);
}

Map<String, dynamic> toJson() {
return {
'updatePeriod': updatePeriod,
'highLimit': highLimit,
'activeSensor': activeSensor,
'includeLocationData': includeLocationData,
};
}

factory DustSensorConfig.fromJson(Map<String, dynamic> json) {
return DustSensorConfig(
updatePeriod: json['updatePeriod'] ?? 1000,
highLimit: (json['highLimit'] ?? 4.0).toDouble(),
activeSensor: json['activeSensor'] ?? 'In-built Sensor',
includeLocationData: json['includeLocationData'] ?? true,
);
}
}
64 changes: 64 additions & 0 deletions lib/providers/dust_sensor_config_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'package:flutter/foundation.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:pslab/models/dust_sensor_config.dart';

class DustSensorConfigProvider extends ChangeNotifier {
DustSensorConfig _config = const DustSensorConfig();
DustSensorConfig get config => _config;

DustSensorConfigProvider() {
_loadConfigFromPrefs();
}

Future<void> _loadConfigFromPrefs() async {
final prefs = await SharedPreferences.getInstance();
final jsonString = prefs.getString('dust_config');
if (jsonString != null) {
final Map<String, dynamic> jsonMap = json.decode(jsonString);
_config = DustSensorConfig.fromJson(jsonMap);
notifyListeners();
}
}

Future<void> _saveConfigToPrefs() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('dust_config', json.encode(_config.toJson()));
}

void updateConfig(DustSensorConfig newConfig) {
_config = newConfig;
notifyListeners();
_saveConfigToPrefs();
}

void updateUpdatePeriod(int updatePeriod) {
_config = _config.copyWith(updatePeriod: updatePeriod);
notifyListeners();
_saveConfigToPrefs();
}

void updateHighLimit(double highLimit) {
_config = _config.copyWith(highLimit: highLimit);
notifyListeners();
_saveConfigToPrefs();
}

void updateActiveSensor(String activeSensor) {
_config = _config.copyWith(activeSensor: activeSensor);
notifyListeners();
_saveConfigToPrefs();
}

void updateIncludeLocationData(bool includeLocationData) {
_config = _config.copyWith(includeLocationData: includeLocationData);
notifyListeners();
_saveConfigToPrefs();
}

void resetToDefaults() {
_config = const DustSensorConfig();
notifyListeners();
_saveConfigToPrefs();
}
}
Loading
Loading