Skip to content

Commit ec3084b

Browse files
committed
feat: added Power Source screen
1 parent f12fe78 commit ec3084b

13 files changed

+1075
-0
lines changed

lib/communication/commands_proto.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class CommandsProto {
7272
int dac = 6;
7373
int setDac = 1;
7474
int setCalibratedDac = 2;
75+
int setPower = 3;
7576

7677
int wavegen = 7;
7778
int setWg = 1;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:data/polynomial.dart';
2+
import 'package:data/type.dart';
3+
4+
class DACChannel {
5+
late String name;
6+
late int channum;
7+
late int offset;
8+
late List<double> range;
9+
late double slope;
10+
late double intercept;
11+
late Polynomial vToCode;
12+
late Polynomial codeToV;
13+
late int channelCode;
14+
late String calibrationEnabled;
15+
16+
DACChannel(this.name, List<double> span, this.channum, this.channelCode) {
17+
range = span;
18+
slope = span[1] - span[0];
19+
intercept = span[0];
20+
vToCode = Polynomial.fromCoefficients(
21+
DataType.float, [3300.0 / slope, -3300.0 * intercept / slope]);
22+
codeToV = Polynomial.fromCoefficients(
23+
DataType.float, [slope / 3300.0, intercept]);
24+
calibrationEnabled = "false";
25+
offset = 0;
26+
}
27+
}

lib/communication/science_lab.dart

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import 'package:flutter/foundation.dart';
55
import 'package:pslab/communication/commands_proto.dart';
66
import 'package:pslab/communication/handler/base.dart';
77
import 'package:pslab/communication/packet_handler.dart';
8+
import 'package:pslab/communication/peripherals/dac_channel.dart';
89
import 'package:pslab/communication/socket_client.dart';
910
import 'package:pslab/others/logger_service.dart';
11+
import 'package:pslab/providers/board_state_provider.dart';
1012
import 'package:pslab/providers/locator.dart';
1113

1214
import 'analogChannel/analog_acquisition_channel.dart';
@@ -35,6 +37,7 @@ class ScienceLab {
3537
Map<String, String> waveType = {};
3638
List<AnalogAcquisitionChannel> aChannels = [];
3739
List<DigitalChannel> dChannels = [];
40+
Map<String, DACChannel> dacChannels = {};
3841
static final double capacitorDischargeVoltage = 0.01 * 3.3;
3942

4043
late CommunicationHandler mCommunicationHandler;
@@ -115,6 +118,17 @@ class ScienceLab {
115118
squareWaveFrequency['SQR2'] = 0.0;
116119
squareWaveFrequency['SQR3'] = 0.0;
117120
squareWaveFrequency['SQR4'] = 0.0;
121+
if (getIt<BoardStateProvider>().pslabVersion == 6) {
122+
dacChannels['PCS'] = DACChannel('PCS', [0, 3.3], 0, 0);
123+
dacChannels['PV3'] = DACChannel('PV3', [0, 3.3], 1, 1);
124+
dacChannels['PC2'] = DACChannel('PC2', [-3.3, 3.3], 2, 0);
125+
dacChannels['PV1'] = DACChannel('PV1', [-5, 5], 3, 1);
126+
} else {
127+
dacChannels['PCS'] = DACChannel('PCS', [0, 3.3], 0, 0);
128+
dacChannels['PV3'] = DACChannel('PV3', [0, 3.3], 1, 1);
129+
dacChannels['PC2'] = DACChannel('PC2', [-3.3, 3.3], 2, 2);
130+
dacChannels['PV1'] = DACChannel('PV1', [-5, 5], 3, 3);
131+
}
118132

119133
if (isConnected()) {
120134
await runInitSequence(true);
@@ -1024,6 +1038,58 @@ class ScienceLab {
10241038
return null;
10251039
}
10261040

1041+
Future<void> setVoltage(String channel, double voltage) async {
1042+
DACChannel dacChannel = dacChannels[channel]!;
1043+
int v = dacChannel.vToCode(voltage).toInt();
1044+
try {
1045+
mPacketHandler.sendByte(mCommandsProto.dac);
1046+
mPacketHandler.sendByte(mCommandsProto.setPower);
1047+
mPacketHandler.sendByte(dacChannel.channelCode);
1048+
mPacketHandler.sendInt(v);
1049+
await mPacketHandler.getAcknowledgement();
1050+
} catch (e) {
1051+
logger.e("Error in setVoltage: $e");
1052+
}
1053+
}
1054+
1055+
Future<void> setCurrent(double current) async {
1056+
DACChannel dacChannel = dacChannels['PCS']!;
1057+
int v = (3300 - dacChannel.vToCode(current)).toInt();
1058+
try {
1059+
mPacketHandler.sendByte(mCommandsProto.dac);
1060+
mPacketHandler.sendByte(mCommandsProto.setPower);
1061+
mPacketHandler.sendByte(dacChannel.channelCode);
1062+
mPacketHandler.sendInt(v);
1063+
await mPacketHandler.getAcknowledgement();
1064+
} catch (e) {
1065+
logger.e("Error in setCurrent: $e");
1066+
}
1067+
}
1068+
1069+
Future<void> setPV1(double voltage) async {
1070+
if (isConnected()) {
1071+
await setVoltage('PV1', voltage);
1072+
}
1073+
}
1074+
1075+
Future<void> setPV2(double voltage) async {
1076+
if (isConnected()) {
1077+
await setVoltage('PV2', voltage);
1078+
}
1079+
}
1080+
1081+
Future<void> setPV3(double voltage) async {
1082+
if (isConnected()) {
1083+
await setVoltage('PV3', voltage);
1084+
}
1085+
}
1086+
1087+
Future<void> setPCS(double current) async {
1088+
if (isConnected()) {
1089+
await setCurrent(current);
1090+
}
1091+
}
1092+
10271093
Future<void> servo4(
10281094
double? angle1,
10291095
double? angle2,

lib/l10n/app_en.arb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@
9494
"analysisOptionEveryRisingEdge": "EVERY RISING EDGE",
9595
"analysisOptionEveryFourthRisingEdge": "EVERY FOURTH RISING EDGE",
9696
"analysisOptionDisabled": "DISABLED",
97+
"powerSourceTitle": "Power Source",
98+
"pinPV1": "PV1",
99+
"pinPV2": "PV2",
100+
"pinPV3": "PV3",
101+
"pinPCS": "PCS",
97102
"analyze": "ANALYZE",
98103
"settings": "Settings",
99104
"autoStart": "Auto Start",

lib/l10n/app_localizations.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,36 @@ abstract class AppLocalizations {
658658
/// **'DISABLED'**
659659
String get analysisOptionDisabled;
660660

661+
/// No description provided for @powerSourceTitle.
662+
///
663+
/// In en, this message translates to:
664+
/// **'Power Source'**
665+
String get powerSourceTitle;
666+
667+
/// No description provided for @pinPV1.
668+
///
669+
/// In en, this message translates to:
670+
/// **'PV1'**
671+
String get pinPV1;
672+
673+
/// No description provided for @pinPV2.
674+
///
675+
/// In en, this message translates to:
676+
/// **'PV2'**
677+
String get pinPV2;
678+
679+
/// No description provided for @pinPV3.
680+
///
681+
/// In en, this message translates to:
682+
/// **'PV3'**
683+
String get pinPV3;
684+
685+
/// No description provided for @pinPCS.
686+
///
687+
/// In en, this message translates to:
688+
/// **'PCS'**
689+
String get pinPCS;
690+
661691
/// No description provided for @analyze.
662692
///
663693
/// In en, this message translates to:

lib/l10n/app_localizations_en.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,21 @@ class AppLocalizationsEn extends AppLocalizations {
301301
@override
302302
String get analysisOptionDisabled => 'DISABLED';
303303

304+
@override
305+
String get powerSourceTitle => 'Power Source';
306+
307+
@override
308+
String get pinPV1 => 'PV1';
309+
310+
@override
311+
String get pinPV2 => 'PV2';
312+
313+
@override
314+
String get pinPV3 => 'PV3';
315+
316+
@override
317+
String get pinPCS => 'PCS';
318+
304319
@override
305320
String get analyze => 'ANALYZE';
306321

lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:pslab/view/logic_analyzer_screen.dart';
1313
import 'package:pslab/view/luxmeter_screen.dart';
1414
import 'package:pslab/view/multimeter_screen.dart';
1515
import 'package:pslab/view/oscilloscope_screen.dart';
16+
import 'package:pslab/view/power_source_screen.dart';
1617
import 'package:pslab/view/robotic_arm_screen.dart';
1718
import 'package:pslab/view/settings_screen.dart';
1819
import 'package:pslab/view/about_us_screen.dart';
@@ -60,6 +61,7 @@ class MyApp extends StatelessWidget {
6061
'/oscilloscope': (context) => const OscilloscopeScreen(),
6162
'/multimeter': (context) => const MultimeterScreen(),
6263
'/logicAnalyzer': (context) => const LogicAnalyzerScreen(),
64+
'/powerSource': (context) => const PowerSourceScreen(),
6365
'/connectDevice': (context) => const ConnectDeviceScreen(),
6466
'/faq': (context) => FAQScreen(),
6567
'/settings': (context) => const SettingsScreen(),

lib/providers/board_state_provider.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ class BoardStateProvider extends ChangeNotifier {
1515
bool hasPermission = false;
1616
late ScienceLabCommon scienceLabCommon;
1717
String pslabVersionID = 'Not Connected';
18+
String pslabVersionIDV6 = 'PSLab V6';
19+
String pslabVersionIDV5 = 'PSLab V5';
20+
int pslabVersion = 0;
1821
late String exportFormat;
1922
bool autoStart = true;
2023

@@ -67,6 +70,11 @@ class BoardStateProvider extends ChangeNotifier {
6770

6871
Future<void> setPSLabVersionIDs() async {
6972
pslabVersionID = await getIt.get<ScienceLab>().getVersion();
73+
if (pslabVersionID == pslabVersionIDV6) {
74+
pslabVersion = 6;
75+
} else if (pslabVersionID == pslabVersionIDV5) {
76+
pslabVersion = 5;
77+
}
7078
notifyListeners();
7179
}
7280

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:pslab/communication/science_lab.dart';
3+
import 'package:pslab/providers/locator.dart';
4+
5+
enum Pin {
6+
pv1,
7+
pv2,
8+
pv3,
9+
pcs,
10+
}
11+
12+
class PowerSourceStateProvider extends ChangeNotifier {
13+
late double voltagePV1;
14+
late double voltagePV2;
15+
late double voltagePV3;
16+
late double currentPCS;
17+
18+
late List<double> rangePV1;
19+
late List<double> rangePV2;
20+
late List<double> rangePV3;
21+
late List<double> rangePCS;
22+
23+
late double step;
24+
25+
late ScienceLab _scienceLab;
26+
27+
PowerSourceStateProvider() {
28+
voltagePV1 = -5.00;
29+
voltagePV2 = -3.30;
30+
voltagePV3 = 0.00;
31+
currentPCS = 0.00;
32+
33+
rangePV1 = [-5.00, 5.00];
34+
rangePV2 = [-3.30, 3.30];
35+
rangePV3 = [0.00, 3.30];
36+
rangePCS = [0.00, 3.30];
37+
38+
step = 0.01;
39+
40+
_scienceLab = getIt.get<ScienceLab>();
41+
}
42+
43+
double valueToIndex(double value, Pin pin) {
44+
List<double> range;
45+
int sections;
46+
switch (pin) {
47+
case Pin.pv1:
48+
range = rangePV1;
49+
sections = 1000;
50+
break;
51+
case Pin.pv2:
52+
range = rangePV2;
53+
sections = 660;
54+
break;
55+
case Pin.pv3:
56+
range = rangePV3;
57+
sections = 330;
58+
break;
59+
case Pin.pcs:
60+
range = rangePCS;
61+
sections = 330;
62+
break;
63+
}
64+
final clampedValue = value.clamp(range[0], range[1]);
65+
return ((clampedValue - range[0]) / (range[1] - range[0])) * sections;
66+
}
67+
68+
double indexToValue(double index, Pin pin) {
69+
List<double> range;
70+
int sections;
71+
switch (pin) {
72+
case Pin.pv1:
73+
range = rangePV1;
74+
sections = 1000;
75+
break;
76+
case Pin.pv2:
77+
range = rangePV2;
78+
sections = 660;
79+
break;
80+
case Pin.pv3:
81+
range = rangePV3;
82+
sections = 330;
83+
break;
84+
case Pin.pcs:
85+
range = rangePCS;
86+
sections = 330;
87+
break;
88+
}
89+
final clampedIndex = index.clamp(0, sections);
90+
return (clampedIndex / sections) * (range[1] - range[0]) + range[0];
91+
}
92+
93+
Future<void> setPV1(double value) async {
94+
final clampedValue = value.clamp(rangePV1[0], rangePV1[1]);
95+
voltagePV1 = clampedValue;
96+
voltagePV3 = (3.3 / 2) * (1 + (voltagePV1 / 5.0));
97+
await _scienceLab.setPV1(voltagePV1);
98+
notifyListeners();
99+
}
100+
101+
Future<void> setPV2(double value) async {
102+
final clampedValue = value.clamp(rangePV2[0], rangePV2[1]);
103+
voltagePV2 = clampedValue;
104+
currentPCS = (3.3 - voltagePV2) / 2;
105+
await _scienceLab.setPV2(voltagePV2);
106+
notifyListeners();
107+
}
108+
109+
Future<void> setPV3(double value) async {
110+
final clampedValue = value.clamp(rangePV3[0], rangePV3[1]);
111+
voltagePV3 = clampedValue;
112+
voltagePV1 = 5 * (2 * voltagePV3 / 3.3 - 1);
113+
await _scienceLab.setPV3(voltagePV3);
114+
notifyListeners();
115+
}
116+
117+
Future<void> setPCS(double value) async {
118+
final clampedValue = value.clamp(rangePCS[0], rangePCS[1]);
119+
currentPCS = clampedValue;
120+
voltagePV2 = 3.3 - 2 * currentPCS;
121+
await _scienceLab.setPCS(currentPCS);
122+
notifyListeners();
123+
}
124+
125+
Future<void> setValue(double value, Pin pin) async {
126+
switch (pin) {
127+
case Pin.pv1:
128+
await setPV1(value);
129+
break;
130+
case Pin.pv2:
131+
await setPV2(value);
132+
break;
133+
case Pin.pv3:
134+
await setPV3(value);
135+
break;
136+
case Pin.pcs:
137+
await setPCS(value);
138+
break;
139+
}
140+
}
141+
142+
double getValue(Pin pin) {
143+
switch (pin) {
144+
case Pin.pv1:
145+
return voltagePV1;
146+
case Pin.pv2:
147+
return voltagePV2;
148+
case Pin.pv3:
149+
return voltagePV3;
150+
case Pin.pcs:
151+
return currentPCS;
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)