-
Notifications
You must be signed in to change notification settings - Fork 848
Add PSLab Mini Support to the App #3543
Description
Adding PSLab Mini Support to the App
Description
Add support for the PSLab Mini to the app while maintaining backward compatibility with existing PSLab hardware.
The PSLab Mini uses a new SCPI-based text protocol, whereas the existing PSLab devices communicate using the legacy binary byte-stream protocol. The app therefore needs a clean branching strategy that can detect the connected hardware and route communication through the appropriate protocol.
This work will introduce PSLab Mini detection, SCPI command management, SCPI communication, handshake support, and protocol-specific instrument logic, without modifying the existing legacy communication methods.
Goals
Detect and recognize the PSLab Mini over USB.
Add the PSLab Mini to the list of supported boards.
Introduce a centralized SCPI command dictionary.
Add SCPI-specific communication methods while keeping the existing binary protocol unchanged.
Identify the PSLab Mini during the handshake.
Use a global version identifier to distinguish between legacy PSLab hardware and the Mini.
Route instrument operations to either the SCPI or legacy protocol based on the detected board.
Preserve existing functionality for V5/V6 and other supported PSLab hardware.
Implementation Roadmap
Step 1: Update USB Device Detection
Files
rust/api/simple.rsPSLabCommunicationHandler.dart
Changes
Update the Rust USB port scanning logic in:
check_desktop_device_presentinit_desktop
to accept the Raspberry Pi USB Vendor ID:
VID: 0x2E8A
In PSLabCommunicationHandler.dart, add the PSLab Mini to the supportedBoards list:
PSLabBoard(
version: 'Mini',
vid: 0x2E8A,
pid: 0x0003,
)
Why?
The PSLab Mini is based on Raspberry Pi Pico hardware and currently gets filtered out because its USB identifiers are not recognized by the application.
Adding the Mini's VID/PID allows the app to recognize the device and proceed with the connection instead of treating it as an unsupported USB device.
Step 2: Create the SCPI Command Dictionary
File
Create:
lib/communication/scpi_commands.dart
Changes
Create a centralized class containing static string constants for all SCPI commands supported by the PSLab Mini firmware.
For example:
class ScpiCommands { static const String identify = '*IDN?'; static const String i2cOpen = 'BUS:I2C:OPEN';
// Add remaining SCPI commands here.
}
The complete list of commands should be based on the commands implemented by the PSLab Mini firmware.
Why?
SCPI commands should not be hardcoded throughout the instrument implementation.
A centralized command dictionary:
Reduces the possibility of typos.
Makes commands easier to discover and maintain.
Keeps protocol definitions separate from instrument logic.
Provides a structure similar to the existing
CommandsProtoclass used by the legacy protocol.Makes future changes to the Mini firmware easier to propagate through the app.
Step 3: Extend the Packet Handler
File
lib/communication/packet_handler.dart
Changes
Keep the existing binary communication methods unchanged.
In particular, do not modify:
sendByte()
getInt()
Add two new methods for SCPI communication:
sendScpiCommand(String command)
and:
queryScpi(String command)
sendScpiCommand
This method should:
Accept a SCPI command as a
String.Encode the command using UTF-8.
Append a newline terminator.
Send the resulting bytes to the device.
Conceptually:
SCPI command
↓
UTF-8 encoding
↓
Append '\n'
↓
Send to PSLab Mini
queryScpi
This method should:
Send the SCPI command using the SCPI communication path.
Wait for the device response.
Decode the response as UTF-8.
Return the resulting string.
Why?
The existing PSLab devices expect binary data such as raw integers, while the PSLab Mini communicates using text-based SCPI commands.
The packet handler should therefore support both protocols independently:
Legacy PSLab
↓
sendByte() / getInt()
↓
Binary protocol
PSLab Mini
↓
sendScpiCommand() / queryScpi()
↓
SCPI text protocol
Keeping the existing methods unchanged minimizes the risk of breaking legacy hardware support.
Step 4: Update the Handshake and Global Board State
File
lib/providers/board_state_provider.dart
Changes
Update setPSLabVersionIDs() to recognize the PSLab Mini during the device identification/handshake process.
Add a condition similar to:
if (rawVersion.contains('PSLab Mini')) {
pslabVersionID = 'PSLab Mini';
pslabVersion = 7;
}
The exact placement should ensure that the Mini is recognized before the application falls through to the existing unsupported-version handling.
Why?
The current handshake logic identifies supported legacy versions such as V5 and V6. Since the PSLab Mini reports a different identification string, it may currently be treated as an unknown device and disconnected.
Assigning:
pslabVersion = 7
provides a simple global protocol/board identifier that can be used throughout the application.
This allows instrument implementations to determine which communication protocol should be used:
pslabVersion == 7
↓
PSLab Mini
↓
SCPI protocol
while all other supported versions continue using the existing binary protocol.
Step 5: Branch the Instrument Logic
Files
ScienceLab.dartI2C.dart
Changes
Update the relevant initialization, configuration, and capture methods to support both communication protocols.
The general structure should be:
if (pslabVersion == 7) {
// PSLab Mini / SCPI implementation
// Use queryScpi() / sendScpiCommand()
} else {
// Existing legacy implementation
// Use sendByte() / getInt()
}
ScienceLab.dart
Review the initialization and capture-related methods and identify all communication that currently assumes the legacy binary protocol.
For PSLab Mini:
Replace the relevant binary commands with their corresponding SCPI commands.
Use
queryScpi()when a response is required.Use
sendScpiCommand()for commands that do not require a response.
For existing PSLab versions, preserve the current sendByte()/getInt() implementation.
I2C.dart
Apply the same branching strategy to I2C initialization and communication.
For example:
if (pslabVersion == 7) {
// SCPI I2C commands
} else {
// Existing binary I2C commands
}
The SCPI branch should use the commands defined in scpi_commands.dart rather than hardcoded strings.
Why?
This keeps the protocol-specific logic isolated while allowing the same instrument APIs to work with both generations of hardware.
The desired architecture is:
┌─────────────────────┐
│ Instrument Logic │
│ ScienceLab / I2C │
└──────────┬──────────┘
│
Check pslabVersion
│
┌──────────────┴──────────────┐
│ │
pslabVersion == 7 Legacy versions
│ │
▼ ▼
SCPI communication Binary communication
│ │
▼ ▼
queryScpi / sendScpiCommand sendByte / getInt
│ │
▼ ▼
PSLab Mini Existing PSLab hardware
Expected Result
After these changes, the app should be able to:
Detect a PSLab Mini over USB.
Establish a connection with the Mini.
Identify the Mini during the handshake.
Set
pslabVersion = 7.Automatically route Mini-specific operations through the SCPI protocol.
Continue routing existing PSLab V5/V6 operations through the legacy binary protocol.
Use a centralized SCPI command dictionary for Mini commands.
Preserve the existing binary packet-handling implementation.
The final behavior should be transparent to higher-level application code: the connected board determines which communication protocol is used.
Files to be Modified
| File | Purpose |
|---|---|
| rust/api/simple.rs | Recognize the PSLab Mini USB Vendor ID |
| PSLabCommunicationHandler.dart | Add the PSLab Mini USB VID/PID |
| lib/communication/scpi_commands.dart | New centralized SCPI command dictionary |
| lib/communication/packet_handler.dart | Add SCPI send/query methods |
| lib/providers/board_state_provider.dart | Identify PSLab Mini and assign version 7 |
| ScienceLab.dart | Add SCPI/legacy protocol branching |
| I2C.dart | Add SCPI/legacy protocol branching |
Testing Checklist
USB Detection
PSLab Mini with VID
0x2E8Aand PID0x0003is detected.Existing supported PSLab boards are still detected.
Unsupported USB devices continue to be ignored.
Handshake
PSLab Mini responds to the identification query.
rawVersioncorrectly containsPSLab Mini.pslabVersionIDis set toPSLab Mini.pslabVersionis set to7.Existing V5/V6 identification behavior remains unchanged.
SCPI Communication
SCPI commands are encoded using UTF-8.
Commands are terminated with a newline.
sendScpiCommand()works for commands without responses.queryScpi()correctly decodes UTF-8 responses.Existing
sendByte()andgetInt()behavior is unchanged.
Instrument Support
ScienceLab.dartuses SCPI for PSLab Mini.ScienceLab.dartcontinues using the legacy protocol for existing boards.I2C.dartuses SCPI for PSLab Mini.I2C.dartcontinues using the legacy protocol for existing boards.No SCPI command strings are unnecessarily hardcoded in instrument logic.
Definition of Done
PSLab Mini is recognized by the app.
PSLab Mini can successfully complete the connection handshake.
SCPI commands are centralized in
scpi_commands.dart.SCPI communication is supported by
PacketHandler.Existing binary communication remains untouched.
pslabVersion == 7reliably identifies the PSLab Mini.ScienceLabsupports both SCPI and legacy communication.I2Csupports both SCPI and legacy communication.Existing PSLab hardware functionality is not regressed.
Relevant tests pass for both the PSLab Mini and legacy boards.