Skip to content

Commit

Permalink
feat: added basic communication and initialization logic
Browse files Browse the repository at this point in the history
  • Loading branch information
AsCress committed Jan 24, 2025
1 parent aba81ed commit 9033728
Show file tree
Hide file tree
Showing 23 changed files with 1,399 additions and 74 deletions.
10 changes: 8 additions & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ linter:
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
avoid_print: false
constant_identifier_names: false
non_constant_identifier_names: false
prefer_final_fields: false
unnecessary_nullable_for_final_variable_declarations: false

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
errors:
unused_element: ignore
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.usb.host" />
<application
android:label="PSLab"
android:name="${applicationName}"
Expand All @@ -23,7 +24,10 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
Expand Down
39 changes: 39 additions & 0 deletions android/app/src/main/res/xml/device_filter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 0x0403 / 0x60??: FTDI -->
<usb-device vendor-id="1027" product-id="24577" /> <!-- 0x6001: FT232R -->
<usb-device vendor-id="1027" product-id="24592" /> <!-- 0x6010: FT2232H -->
<usb-device vendor-id="1027" product-id="24593" /> <!-- 0x6011: FT4232H -->
<usb-device vendor-id="1027" product-id="24596" /> <!-- 0x6014: FT232H -->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->

<!-- 0x10C4 / 0xEA??: Silabs CP210x -->
<usb-device vendor-id="4292" product-id="60000" /> <!-- 0xea60: CP2102 and other CP210x single port devices -->
<usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
<usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->

<!-- 0x067B / 0x23?3: Prolific PL2303x -->
<usb-device vendor-id="1659" product-id="8963" /> <!-- 0x2303: PL2303HX, HXD, TA, ... -->
<usb-device vendor-id="1659" product-id="9123" /> <!-- 0x23a3: PL2303GC -->
<usb-device vendor-id="1659" product-id="9139" /> <!-- 0x23b3: PL2303GB -->
<usb-device vendor-id="1659" product-id="9155" /> <!-- 0x23c3: PL2303GT -->
<usb-device vendor-id="1659" product-id="9171" /> <!-- 0x23d3: PL2303GL -->
<usb-device vendor-id="1659" product-id="9187" /> <!-- 0x23e3: PL2303GE -->
<usb-device vendor-id="1659" product-id="9203" /> <!-- 0x23f3: PL2303GS -->

<!-- 0x1a86 / 0x?523: Qinheng CH34x -->
<usb-device vendor-id="6790" product-id="21795" /> <!-- 0x5523: CH341A -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x7523: CH340 -->

<!-- CDC driver -->
<usb-device vendor-id="1240" product-id="223"/> <!-- 1240 / 223: MCP2200(For PSLab V5) -->
<usb-device vendor-id="9025" /> <!-- 0x2341 / ......: Arduino -->
<usb-device vendor-id="5824" product-id="1155" /> <!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="1003" product-id="8260" /> <!-- 0x03EB / 0x2044: Atmel Lufa -->
<usb-device vendor-id="7855" product-id="4" /> <!-- 0x1eaf / 0x0004: Leaflabs Maple -->
<usb-device vendor-id="3368" product-id="516" /> <!-- 0x0d28 / 0x0204: ARM mbed -->
<usb-device vendor-id="1155" product-id="22336" /><!-- 0x0483 / 0x5740: ST CDC -->
<usb-device vendor-id="11914" product-id="5" /> <!-- 0x2E8A / 0x0005: Raspberry Pi Pico Micropython -->
<usb-device vendor-id="11914" product-id="10" /> <!-- 0x2E8A / 0x000A: Raspberry Pi Pico SDK -->
<usb-device vendor-id="6790" product-id="21972" /><!-- 0x1A86 / 0x55D4: Qinheng CH9102F -->
</resources>
Binary file added assets/icons/ic_usb_connected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions lib/communication/analogChannel/analog_acquisition_channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:pslab/communication/analogChannel/analog_input_source.dart';

class AnalogAcquisitionChannel {
late int _resolution;
late AnalogInputSource _analogInputSource;
late double _calibration_ref196;
late int length;
late double _timebase;
final List<double> _xAxis = List.filled(10000, 0.0);
List<double> yAxis = List.filled(10000, 0.0);

AnalogAcquisitionChannel(String channel) {
_calibration_ref196 = 1;
_resolution = 10;
length = 100;
_timebase = 1;
_analogInputSource = AnalogInputSource('CH1');
}

List<double> fixValue(List<double> val) {
List<double> calcData = List.filled(val.length, 0.0);
if (_resolution == 12) {
for (int i = 0; i < val.length; i++) {
calcData[i] = _calibration_ref196 *
(_analogInputSource.calPoly12.evaluate(val[i]));
}
} else {
for (int i = 0; i < val.length; i++) {
calcData[i] = _calibration_ref196 *
(_analogInputSource.calPoly10.evaluate(val[i]));
}
}
return calcData;
}

void setParams(String? channel, int length, double timebase, int resolution,
AnalogInputSource? source, double? gain) {
_analogInputSource = source!;
if (resolution != -1) _resolution = resolution;
if (length != -1) this.length = length;
if (timebase != -1) _timebase = timebase;
regenerateXAxis();
}

void regenerateXAxis() {
for (int i = 0; i < length; i++) {
_xAxis[i] = _timebase * i;
}
}

List<double> getXAxis() {
return List.from(_xAxis.getRange(0, length));
}

List<double> getYAxis() {
return List.from(yAxis.getRange(0, length));
}
}
43 changes: 43 additions & 0 deletions lib/communication/analogChannel/analog_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class AnalogConstants {
List<double> gains = [1, 2, 4, 5, 8, 10, 16, 32, 1 / 11];
List<String> allAnalogChannels = [
'CH1',
'CH2',
'CH3',
'MIC',
'CAP',
'RES',
'VOL',
];
List<String> biPolars = [
'CH1',
'CH2',
'CH3',
'MIC',
];
Map<String, List<double>> inputRanges = {};
Map<String, int> picADCMultiplex = {};

AnalogConstants() {
inputRanges = {
"CH1": [16.5, -16.5],
"CH2": [16.5, -16.5],
"CH3": [-3.3, 3.3],
"MIC": [-3.3, 3.3],
"CAP": [0, 3.3],
"RES": [0, 3.3],
"VOL": [0, 3.3],
};

picADCMultiplex = {
"CH1": 3,
"CH2": 0,
"CH3": 1,
"MIC": 2,
"AN4": 4,
"RES": 7,
"CAP": 5,
"VOL": 8,
};
}
}
86 changes: 86 additions & 0 deletions lib/communication/analogChannel/analog_input_source.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:polynomial/polynomial.dart';
import 'package:pslab/communication/analogChannel/analog_constants.dart';

class AnalogInputSource {
late List<double> _gainValues, _range;
bool gainEnabled = false, inverted = false, calibrationReady = false;
double _gain = 0;
late int gainPGA, CHOSA;
final String _channelName;
late Polynomial calPoly10;
late Polynomial calPoly12;
late Polynomial voltToCode10;
late Polynomial voltToCode12;
List<double> _adc_shifts = [];
List<Polynomial> _polynomials = [];

AnalogInputSource(this._channelName) {
AnalogConstants analogConstants = AnalogConstants();
_range = analogConstants.inputRanges[_channelName]!;
_gainValues = analogConstants.gains;
CHOSA = analogConstants.picADCMultiplex[_channelName]!;

calPoly10 = Polynomial([0, 3.3 / 1023, 0]);
calPoly12 = Polynomial([0, 3.3 / 4095, 0]);

if (_range[1] - _range[0] < 0) {
inverted = true;
}
if (_channelName == "CH1") {
gainEnabled = true;
gainPGA = 1;
_gain = 0;
} else if (_channelName == "CH2") {
gainEnabled = true;
gainPGA = 2;
_gain = 0;
}
_gain = 0;
regenerateCalibration();
}

bool setGain(int index) {
if (!gainEnabled) {
print("$_channelName: Analog gain is not available");
return false;
}
_gain = _gainValues[index];
regenerateCalibration();
return true;
}

void ignoreCalibration() {
calibrationReady = false;
}

void regenerateCalibration() {
double A, B, intercept, slope;
B = _range[1];
A = _range[0];
if (_gain >= 0 && _gain <= 8) {
_gain = _gainValues[_gain.round()];
B /= _gain;
A /= _gain;
}
slope = 2 * (B - A);
intercept = 2 * A;
if (!calibrationReady || _gain == 8) {
calPoly10 = Polynomial([intercept, slope / 1023, 0]);
calPoly12 = Polynomial([intercept, slope / 4095, 0]);
}

voltToCode10 = Polynomial([-1023 * intercept / slope, 1023 / slope, 0]);
voltToCode12 = Polynomial([-4095 * intercept / slope, 4095, 0]);
}

List<double> cal12(List<double> raw) {
List<double> calcData = List.filled(raw.length, 0.0);
for (int i = 0; i < raw.length; i++) {
double avgShifts =
(_adc_shifts[raw[i].floor()] + _adc_shifts[raw[i].ceil()]) / 2;
raw[i] -= 4095 * avgShifts / 3.3;
calcData[i] = _polynomials[_gain as int].evaluate(raw[i]);
}
return calcData;
}
}
Loading

0 comments on commit 9033728

Please sign in to comment.