From 04ad41224cd4124e9e4870bb494c854c159f9fc1 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 19:59:20 +0200 Subject: [PATCH 01/10] changes for usb connection --- .vscode/launch.json | 4 +- README.md | 13 +-- __main__.py | 21 ++++- src/science_mode_4/protocol/protocol.py | 1 - src/science_mode_4/utils/connection.py | 13 ++- .../utils/serial_port_connection.py | 13 +-- src/science_mode_4/utils/usb_connection.py | 93 ++++++++++--------- 7 files changed, 91 insertions(+), 67 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 266e7b4..545d635 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,8 +8,8 @@ "name": "Python Debugger: Current File", "type": "debugpy", "request": "launch", - // "program": "__main__.py", - "module": "examples.dyscom.example_dyscom_write_csv", + "program": "__main__.py", + // "module": "examples.dyscom.example_dyscom_get", "justMyCode": false, // "args": ["COM3"], "console": "integratedTerminal" diff --git a/README.md b/README.md index 1b5c4d1..995e640 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,15 @@ Python 3.11 or higher - PySerial - https://pypi.org/project/pyserial/ - `pip install pyserial` -- PyUSB - currently not used +- PyUSB - https://pypi.org/project/pyusb/ - - `pip install pyusb` + - `pip install pyusb` - On Windows - - Download libusb from https://libusb.info/ - - Copy libusb-XX.dll into environment root folder (besides python.exe) - - Under Windows there are driver issues - - Code is currently commented out and not usable + - Install libusb-package to get _libusb-XX.dll_ + - `pip install libusb-package` + - Under Windows there may be driver issues + - See https://github.com/libusb/libusb/wiki/Windows#How_to_use_libusb_on_Windows + - Use Zadig to change driver for _STM32 Virtual ComPort_ to _libusb-XX.dll_ and reinstall driver ## Build library - Only necessary, if you made changes to the library or install a version from a branch diff --git a/__main__.py b/__main__.py index e9d8441..caaf7f1 100644 --- a/__main__.py +++ b/__main__.py @@ -1,25 +1,36 @@ """Test program how to use library without installing the library, DO NOT USE THIS FILE, USE EXAMPLES INSTEAD""" +import logging import sys import asyncio +from science_mode_4.device_i24 import DeviceI24 from science_mode_4.device_p24 import DeviceP24 +from science_mode_4.utils import logger from science_mode_4.utils.serial_port_connection import SerialPortConnection +from science_mode_4.utils.usb_connection import UsbConnection async def main() -> int: """Main function""" - devices = SerialPortConnection.list_science_mode_device_ports() - connection = SerialPortConnection(devices[0].device) - # devices = UsbConnection.list_science_mode_devices() - # connection = UsbConnection(devices[0]) + # Serial + # 2025-04-22 15:38 - DEBUG - Outgoing data, length: 12, bytes: F0 81 55 81 59 81 4E 81 0C 04 3E 0F + # 2025-04-22 15:38 - DEBUG - Incoming data, length: 13, bytes: F0 81 55 81 58 81 D1 81 0A 04 43 00 0F + # USB + # 2025-04-22 15:45 - DEBUG - Outgoing data, length: 12, bytes: F0 81 55 81 59 81 4E 81 0C 04 3E 0F + # 2025-04-22 15:45 - DEBUG - Incoming data, length: 13, bytes: F0 81 55 81 58 81 D1 81 0A 04 43 00 0F + logger().setLevel(logging.DEBUG) + # devices = SerialPortConnection.list_science_mode_device_ports() + # connection = SerialPortConnection(devices[0].device) + devices = UsbConnection.list_science_mode_devices() + connection = UsbConnection(devices[0]) # connection = NullConnection() connection.open() - device = DeviceP24(connection) + device = DeviceI24(connection) await device.initialize() general = device.get_layer_general() print(f"Device id: {general.device_id}") diff --git a/src/science_mode_4/protocol/protocol.py b/src/science_mode_4/protocol/protocol.py index b60540d..b6cc72b 100644 --- a/src/science_mode_4/protocol/protocol.py +++ b/src/science_mode_4/protocol/protocol.py @@ -48,7 +48,6 @@ def packet_to_bytes(packet: Packet) -> bytes: bb.append_byte(Protocol.STOP_BYTE) logger().debug("Build package, %s", packet) - logger().debug("Outgoing data, %s", bb) result = bb.get_bytes() return bytes(result) diff --git a/src/science_mode_4/utils/connection.py b/src/science_mode_4/utils/connection.py index 958034b..2ff7dc9 100644 --- a/src/science_mode_4/utils/connection.py +++ b/src/science_mode_4/utils/connection.py @@ -2,6 +2,8 @@ from abc import ABC, abstractmethod +from .logger import logger + class Connection(ABC): """Abstract base class for connection""" @@ -22,16 +24,23 @@ def is_open(self) -> bool: """Checks if connection is open""" - @abstractmethod def write(self, data: bytes): """Write data to connection""" + logger().debug("Outgoing data, length: %d, bytes: %s", len(data), data.hex(" ").upper()) - @abstractmethod def read(self) -> bytes: """Read all data from connection""" + result = self._read_intern() + logger().debug("Incoming data, length: %d, bytes: %s", len(result), result.hex(" ").upper()) + return result @abstractmethod def clear_buffer(self): """Clear buffer from connection""" + + + @abstractmethod + def _read_intern(self): + """Read all data from connection""" diff --git a/src/science_mode_4/utils/serial_port_connection.py b/src/science_mode_4/utils/serial_port_connection.py index 3f75cc2..4076487 100644 --- a/src/science_mode_4/utils/serial_port_connection.py +++ b/src/science_mode_4/utils/serial_port_connection.py @@ -47,16 +47,17 @@ def is_open(self) -> bool: def write(self, data: bytes): + super().write(data) self._ser.write(data) - def read(self) -> bytes: + def clear_buffer(self): + self._ser.reset_input_buffer() + + + def _read_intern(self) -> bytes: result = [] if self._ser.in_waiting > 0: result = self._ser.read_all() - logger().debug("Incoming data, length: %d, bytes: %s", len(result), result.hex(" ").upper()) + return bytes(result) - - - def clear_buffer(self): - self._ser.reset_input_buffer() diff --git a/src/science_mode_4/utils/usb_connection.py b/src/science_mode_4/utils/usb_connection.py index 09b5c33..0cdfd4a 100644 --- a/src/science_mode_4/utils/usb_connection.py +++ b/src/science_mode_4/utils/usb_connection.py @@ -1,7 +1,8 @@ """Provides a class for a usb connection""" -# import usb.core -# import usb.util +import libusb_package +import usb.core +import usb.util from .connection import Connection class UsbConnection(Connection): @@ -9,64 +10,66 @@ class UsbConnection(Connection): IMPORTANT: work in progress (there are driver issues under windows)""" - # @staticmethod - # def list_devices() -> list[usb.core.Device]: - # """Returns all USB devices""" - # return list(usb.core.find(find_all=True)) + @staticmethod + def list_devices() -> list[usb.core.Device]: + """Returns all USB devices""" + # return list(usb.core.find(find_all=True)) + return libusb_package.find(find_all=True) - # @staticmethod - # def list_science_mode_devices() -> list[usb.core.Device]: - # """Returns all potential science mode USB devices""" - # devices = UsbConnection.list_devices() - # # science mode devices (P24/I24) have an STM32 mcu and these are - # # default values for USB CDC devices - # filtered_devices = list(filter(lambda x: x.idVendor == 0x0483 and x.idProduct == 0x5740 and - # x.bDeviceClass == 0x02, devices)) - # return filtered_devices + @staticmethod + def list_science_mode_devices() -> list[usb.core.Device]: + """Returns all potential science mode USB devices""" + devices = UsbConnection.list_devices() + # science mode devices (P24/I24) have an STM32 mcu and these are + # default values for USB CDC devices + filtered_devices = list(filter(lambda x: x.idVendor == 0x0483 and x.idProduct == 0x5740 and + x.bDeviceClass == 0x02, devices)) + return filtered_devices - # def __init__(self, device: usb.core.Device): - # self._device = device - # self._out_endpoint = None - # self._in_endpoint = None - # self._is_open = False + def __init__(self, device: usb.core.Device): + self._device = device + self._out_endpoint: usb.core.Endpoint = None + self._in_endpoint: usb.core.Endpoint = None + self._is_open = False - # def open(self): - # # P24/I24 have only one configuration - # self._device.set_configuration() - # # get an endpoint instance - # cfg = self._device.get_active_configuration() - # intf = cfg[(0,0)] + def open(self): + # P24/I24 have only one configuration + self._device.set_configuration() + # get an endpoint instance + cfg = self._device.get_active_configuration() + intf = cfg[(1,0)] - # # match the first OUT endpoint - # self._out_endpoint = usb.util.find_descriptor( - # intf, - # custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT) - # # match the first IN endpoint - # self._in_endpoint = usb.util.find_descriptor( - # intf, - # custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN) + # match the first OUT endpoint + self._out_endpoint = usb.util.find_descriptor( + intf, + custom_match = lambda e: (print(e) or usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT)) + # match the first IN endpoint + self._in_endpoint = usb.util.find_descriptor( + intf, + custom_match = lambda e: (print(e) or usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN)) - # self._is_open = True + self._is_open = True - # def close(self): - # self._is_open = False + def close(self): + self._is_open = False - # def is_open(self) -> bool: - # return self._is_open + def is_open(self) -> bool: + return self._is_open - # def write(self, data: bytes): - # self._out_endpoint.write(data) + def write(self, data: bytes): + super().write(data) + self._out_endpoint.write(data) - # def read(self) -> bytes: - # return self._in_endpoint.read() + def clear_buffer(self): + pass - # def clear_buffer(self): - # pass + def _read_intern(self) -> bytes: + return bytes(self._in_endpoint.read(self._in_endpoint.wMaxPacketSize)) From f1fc5e289c695e03657fe7c59a54e766b1747b51 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:39:04 +0200 Subject: [PATCH 02/10] wip --- .vscode/launch.json | 2 +- __main__.py | 83 +++++++++++++++++++--- pyproject.toml | 3 +- src/science_mode_4/utils/usb_connection.py | 34 +++++++-- 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 545d635..c269084 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "debugpy", "request": "launch", "program": "__main__.py", - // "module": "examples.dyscom.example_dyscom_get", + // "module": "examples.dyscom.example_dyscom_write_csv", "justMyCode": false, // "args": ["COM3"], "console": "integratedTerminal" diff --git a/__main__.py b/__main__.py index caaf7f1..6791a42 100644 --- a/__main__.py +++ b/__main__.py @@ -1,12 +1,20 @@ """Test program how to use library without installing the library, DO NOT USE THIS FILE, USE EXAMPLES INSTEAD""" +from timeit import default_timer as timer + import logging import sys import asyncio from science_mode_4.device_i24 import DeviceI24 from science_mode_4.device_p24 import DeviceP24 +from science_mode_4.dyscom.ads129x.ads129x_config_register_1 import Ads129xOutputDataRate, Ads129xPowerMode +from science_mode_4.dyscom.dyscom_get_operation_mode import PacketDyscomGetAckOperationMode +from science_mode_4.dyscom.dyscom_send_live_data import PacketDyscomSendLiveData +from science_mode_4.dyscom.dyscom_types import DyscomFilterType, DyscomGetType, DyscomInitParams, DyscomPowerModulePowerType, DyscomPowerModuleType, DyscomSignalType +from science_mode_4.protocol.commands import Commands +from science_mode_4.protocol.types import ResultAndError from science_mode_4.utils import logger from science_mode_4.utils.serial_port_connection import SerialPortConnection from science_mode_4.utils.usb_connection import UsbConnection @@ -16,12 +24,8 @@ async def main() -> int: """Main function""" - # Serial - # 2025-04-22 15:38 - DEBUG - Outgoing data, length: 12, bytes: F0 81 55 81 59 81 4E 81 0C 04 3E 0F - # 2025-04-22 15:38 - DEBUG - Incoming data, length: 13, bytes: F0 81 55 81 58 81 D1 81 0A 04 43 00 0F - # USB - # 2025-04-22 15:45 - DEBUG - Outgoing data, length: 12, bytes: F0 81 55 81 59 81 4E 81 0C 04 3E 0F - # 2025-04-22 15:45 - DEBUG - Incoming data, length: 13, bytes: F0 81 55 81 58 81 D1 81 0A 04 43 00 0F + logger().disabled = True + logger().setLevel(logging.DEBUG) # devices = SerialPortConnection.list_science_mode_device_ports() # connection = SerialPortConnection(devices[0].device) @@ -32,10 +36,69 @@ async def main() -> int: device = DeviceI24(connection) await device.initialize() - general = device.get_layer_general() - print(f"Device id: {general.device_id}") - print(f"Firmware version: {general.firmware_version}") - print(f"Science mode version: {general.science_mode_version}") + # get dyscom layer to call dyscom level commands + dyscom = device.get_layer_dyscom() + + # call enable measurement power module for measurement + await dyscom.power_module(DyscomPowerModuleType.MEASUREMENT, DyscomPowerModulePowerType.SWITCH_ON) + # call init with 4k sample rate and enable signal types + init_params = DyscomInitParams() + init_params.filter = DyscomFilterType.PREDEFINED_FILTER_2 + init_params.signal_type = [DyscomSignalType.BI, DyscomSignalType.EMG_1,\ + DyscomSignalType.EMG_2, DyscomSignalType.BREATHING, DyscomSignalType.TEMPERATURE] + init_params.register_map_ads129x.config_register_1.output_data_rate = Ads129xOutputDataRate.HR_MODE_4_KSPS__LP_MODE_2_KSPS + init_params.register_map_ads129x.config_register_1.power_mode = Ads129xPowerMode.HIGH_RESOLUTION + await dyscom.init(init_params) + + # start dyscom measurement + await dyscom.start() + + start_time = timer() + total_count = 0 + + # loop for some time + for x in range(1000): + # check operation mode from time to time, this function is not waiting for response + # so we have to handle it by ourself later + if x % 100 == 0: + dyscom.send_get_operation_mode() + + live_data_counter = 0 + while True: + # process all available packages + ack = dyscom.packet_buffer.get_packet_from_buffer(live_data_counter == 0) + if ack: + # because there are multiple get commands, we need to additionally check kind, + # which is always associated DyscomGetType + if ack.command == Commands.DL_GET_ACK and ack.kind == DyscomGetType.OPERATION_MODE: + om_ack: PacketDyscomGetAckOperationMode = ack + print(f"Operation mode {om_ack.operation_mode.name}") + # check if measurement is still active + if om_ack.result_error != ResultAndError.NO_ERROR: + break + elif ack.command == Commands.DL_SEND_LIVE_DATA: + live_data_counter += 1 + total_count += 1 + + sld: PacketDyscomSendLiveData = ack + if sld.status_error: + print(f"SendLiveData status error {sld.samples}") + break + + else: + # print(f"Live data acknowledges per iteration {live_data_counter}") + break + + # await asyncio.sleep(0.01) + + # print stats + end_time = timer() + print(f"Samples: {total_count}, duration: {end_time - start_time}, sample rate: {total_count / (end_time - start_time)}") + + # stop measurement + await dyscom.stop() + # turn power module off + await dyscom.power_module(DyscomPowerModuleType.MEASUREMENT, DyscomPowerModulePowerType.SWITCH_OFF) connection.close() diff --git a/pyproject.toml b/pyproject.toml index 0692517..2265968 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,8 @@ license-files = [ "LICENSE" ] dependencies = [ - "pyserial >= 3.5", + "pyserial", + "pyusb" ] [project.urls] diff --git a/src/science_mode_4/utils/usb_connection.py b/src/science_mode_4/utils/usb_connection.py index 0cdfd4a..3691904 100644 --- a/src/science_mode_4/utils/usb_connection.py +++ b/src/science_mode_4/utils/usb_connection.py @@ -32,6 +32,7 @@ def __init__(self, device: usb.core.Device): self._device = device self._out_endpoint: usb.core.Endpoint = None self._in_endpoint: usb.core.Endpoint = None + self._in_endpoint_buffer_size = 128 * 64 self._is_open = False @@ -40,16 +41,18 @@ def open(self): self._device.set_configuration() # get an endpoint instance cfg = self._device.get_active_configuration() - intf = cfg[(1,0)] + # Interface 0: CDC Communication + # Interface 1: CDC Data + interface: usb.core.Interface = cfg[(1,0)] # match the first OUT endpoint self._out_endpoint = usb.util.find_descriptor( - intf, - custom_match = lambda e: (print(e) or usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT)) + interface, + custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT) # match the first IN endpoint self._in_endpoint = usb.util.find_descriptor( - intf, - custom_match = lambda e: (print(e) or usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN)) + interface, + custom_match = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN) self._is_open = True @@ -68,8 +71,25 @@ def write(self, data: bytes): def clear_buffer(self): - pass + # there is no way to clear the buffer from in endpoint, so + # read all data and discard it + self._read_intern() def _read_intern(self) -> bytes: - return bytes(self._in_endpoint.read(self._in_endpoint.wMaxPacketSize)) + data = bytes() + try: + while True: + # Read up to endpoint's max packet size (64 bytes in this case) + tmp = self._in_endpoint.read(self._in_endpoint_buffer_size) + data += bytes(tmp) + if len(tmp) < self._in_endpoint_buffer_size: + break + except usb.core.USBError as e: + if e.errno == 10060: + # Timeout error (no data available) + pass + else: + raise + + return data From 481be7b8d951a7bddc0bebe0c7e7805253e310b7 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:47:03 +0200 Subject: [PATCH 03/10] wip --- .github/workflows/build-validation.yml | 3 +-- pyproject.toml | 3 ++- src/science_mode_4/requirements.txt | 3 +++ src/science_mode_4/utils/serial_port_connection.py | 3 +-- 4 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 src/science_mode_4/requirements.txt diff --git a/.github/workflows/build-validation.yml b/.github/workflows/build-validation.yml index 81c844a..98afe5e 100644 --- a/.github/workflows/build-validation.yml +++ b/.github/workflows/build-validation.yml @@ -20,8 +20,7 @@ jobs: python3 -m pip install build - pyserial - pylint + -r src/science_mode_4/requirements.txt --user - name: Build a binary wheel and a source tarball run: python3 -m build diff --git a/pyproject.toml b/pyproject.toml index 2265968..4a5d32d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,8 @@ license-files = [ ] dependencies = [ "pyserial", - "pyusb" + "pyusb", + "libusb-package" ] [project.urls] diff --git a/src/science_mode_4/requirements.txt b/src/science_mode_4/requirements.txt new file mode 100644 index 0000000..b4da6b7 --- /dev/null +++ b/src/science_mode_4/requirements.txt @@ -0,0 +1,3 @@ +pyserial +pyusb +libusb-package \ No newline at end of file diff --git a/src/science_mode_4/utils/serial_port_connection.py b/src/science_mode_4/utils/serial_port_connection.py index 4076487..f2f7129 100644 --- a/src/science_mode_4/utils/serial_port_connection.py +++ b/src/science_mode_4/utils/serial_port_connection.py @@ -5,7 +5,6 @@ import serial.tools.list_ports_common from .connection import Connection -from .logger import logger class SerialPortConnection(Connection): @@ -59,5 +58,5 @@ def _read_intern(self) -> bytes: result = [] if self._ser.in_waiting > 0: result = self._ser.read_all() - + return bytes(result) From 0290ab9fe38dd3a041b202523122a7a60d79981b Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:48:03 +0200 Subject: [PATCH 04/10] wip --- .github/workflows/build-validation.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-validation.yml b/.github/workflows/build-validation.yml index 98afe5e..6a1ba32 100644 --- a/.github/workflows/build-validation.yml +++ b/.github/workflows/build-validation.yml @@ -15,11 +15,12 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.x" - - name: Install pypa/build/pylint + - name: Install pypa/build/pylint/requirements.txt run: >- python3 -m pip install build + pylint -r src/science_mode_4/requirements.txt --user - name: Build a binary wheel and a source tarball From 00e3c11fa1dc9ae4d1d1b9bde27f877dcd105204 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:50:14 +0200 Subject: [PATCH 05/10] wip --- .github/workflows/publish-to-pypi.yml | 1 + .github/workflows/publish-to-test-pypi.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index f3d341c..b89260d 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -23,6 +23,7 @@ jobs: python3 -m pip install build + -r src/science_mode_4/requirements.txt --user - name: Build a binary wheel and a source tarball run: python3 -m build diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index bc89587..6dfa141 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -20,6 +20,7 @@ jobs: python3 -m pip install build + -r src/science_mode_4/requirements.txt --user - name: Build a binary wheel and a source tarball run: python3 -m build From 677b85453fa2f2834ba82b60c37b858de7d682db Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:50:52 +0200 Subject: [PATCH 06/10] wip --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4a5d32d..494fa83 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "science_mode_4" -version = "0.0.10" +version = "0.0.11" authors = [ { name="Marc Hofmann", email="marc-hofmann@gmx.de" }, ] From 5a00b7ac7c93a5a4865340862543c2eea4b01dc8 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Tue, 22 Apr 2025 22:55:04 +0200 Subject: [PATCH 07/10] wip --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 995e640..1912cb9 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,11 @@ Python 3.11 or higher # Library ## Installation - - Install science_mode_4 library inclusive dependencies via pip - `pip install science_mode_4` - https://pypi.org/project/science-mode-4/ ## Dependencies - - PySerial - https://pypi.org/project/pyserial/ - `pip install pyserial` @@ -33,8 +31,10 @@ Python 3.11 or higher ## Build library - Only necessary, if you made changes to the library or install a version from a branch -- Install dependencies +- Install build dependencies - `python -m pip install --upgrade build` +- Install other library dependencies + - `pip install -r src/science_mode_4/requirements.txt` - Optional run linter - `pip install pylint` - `pylint .\src\science_mode_4\` From 19d3dcccdc3ae72774122121dd0c55a0f51e4778 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Wed, 23 Apr 2025 21:06:11 +0200 Subject: [PATCH 08/10] fixed error under linux for serial connection --- src/science_mode_4/utils/serial_port_connection.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/science_mode_4/utils/serial_port_connection.py b/src/science_mode_4/utils/serial_port_connection.py index f2f7129..81643ea 100644 --- a/src/science_mode_4/utils/serial_port_connection.py +++ b/src/science_mode_4/utils/serial_port_connection.py @@ -1,5 +1,6 @@ """Provides a class for a serial connection""" +import os import serial import serial.tools.list_ports import serial.tools.list_ports_common @@ -34,7 +35,9 @@ def __init__(self, port: str): def open(self): self._ser.open() - self._ser.set_buffer_size(4096*128) + + if os.name == "nt": + self._ser.set_buffer_size(4096*128) def close(self): From 624e39db604382604568182b11dc37ee1925ccd7 Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Wed, 23 Apr 2025 21:08:06 +0200 Subject: [PATCH 09/10] wip --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1912cb9..e7eed2f 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Python 3.11 or higher - https://pypi.org/project/matplotlib/ - `pip install matplotlib` - Fastplotlib with glfw backend + - https://pypi.org/project/fastplotlib/ - `pip install -U fastplotlib` - `pip install -U glfw` From 654d7c2d09c8623b020535f85e0023fbe285484f Mon Sep 17 00:00:00 2001 From: Marc Hofmann Date: Wed, 23 Apr 2025 21:39:46 +0200 Subject: [PATCH 10/10] wip --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index e7eed2f..12f4f96 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Python 3.11 or higher - `pip install pyusb` - On Windows - Install libusb-package to get _libusb-XX.dll_ + - https://pypi.org/project/libusb-package/ - `pip install libusb-package` - Under Windows there may be driver issues - See https://github.com/libusb/libusb/wiki/Windows#How_to_use_libusb_on_Windows @@ -92,3 +93,9 @@ Python 3.11 or higher - `pip install -U fastplotlib` - `pip install -U glfw` +# Changes + +## 0.0.11 +- Implemented UsbConnection class + - Alternative for SerialPortConnection, both share the same base class Connection + - Added _PyUSB_ and _libusb-package_ as dependencies \ No newline at end of file