Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="https://raw.githubusercontent.com/X2Cscope/pyx2cscope/develop/pyx2cscope/gui/img/pyx2cscope.jpg?token=GHSAT0AAAAAACGXT7TPLZREQNFPHPTGHAVEZHIPUNQ" alt="pyX2Cscope Logo" width="250">
<img src="https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/doc/images/pyx2cscope_logo.png" alt="pyX2Cscope Logo" width="250">
</p>

# pyX2Cscope
Expand Down Expand Up @@ -55,7 +55,7 @@ print(speed_measured.get_value())
speed_reference.set_value(1000)
```

Further [Examples](https://github.com/X2Cscope/pyx2cscope/tree/main/pyx2cscope/examples) directory in the pyX2Cscope project to check out the available examples or create a new .py file according to your requirements.
Check [Examples](https://github.com/X2Cscope/pyx2cscope/tree/main/pyx2cscope/examples) directory in the pyX2Cscope project to see common uses of this library.

## Development

Expand Down
34 changes: 13 additions & 21 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,41 +34,33 @@
"sphinx.ext.viewcode",
"sphinx.ext.graphviz",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"autoapi.extension",
]

autoapi_dirs = ["../pyx2cscope"]
autoapi_ignore = [
"*/examples/*",
"*/gui/*", # For now, we ignore this, TODO: fix this
"*/gui/*", # For now, we ignore this
]

suppress_warnings = [
"autoapi.python_import_resolution"
] # Suppress warnings about unresolved imports TODO: fix this
"autoapi.python_import_resolution"
] # Suppress warnings about unresolved imports

nitpick_ignore = [
("py:class", "numbers.Number"),
("py:class", "pyx2cscope.gui"),
("py:class", "mchplnet.lnet"),
("py:class", "mchplnet.lnet.LNet"),
("py:class", "mchplnet.lnet"), # For now, we ignore this, TODO: fix this
(
"py:class",
"pyx2cscope.variable.variable.LNet",
), # For now, we ignore this, TODO: fix this
("py:obj", "abc.ABC"), # For now, we ignore this, TODO: fix this
("py:class", "enum.Enum"), # For now, we ignore this, TODO: fix this
("py:class", "abc.ABC"), # For now, we ignore this, TODO: fix this
("py:class", "PyQt5.QtWidgets.QMainWindow"),
(
"py:class",
"mchplnet.services.scope.ScopeChannel",
), # For now, we ignore this, TODO: fix this
(
"py:class",
"mchplnet.interfaces.abstract_interface.InterfaceABC",
), # For now, we ignore this, TODO: fix this
("py:class", "mchplnet.services.scope.ScopeChannel"),
("py:class", "mchplnet.interfaces.factory.InterfaceType"),
("py:class", "mchplnet.interfaces.abstract_interface.InterfaceABC"),
]

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
}

graphviz_output_format = "png" # 'svg' is also possible

templates_path = ["_templates"]
Expand Down
6 changes: 5 additions & 1 deletion doc/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ There is a mailing group to receive your inputs and questions: MotorControl@micr
## Contribution
Contribute to source code, documentation, examples and report issues: https://github.com/X2Cscope/pyx2cscope

If you want to contribute to the project, please follow these steps:

1. Fork the pyX2Cscope repository.
2. Create a new branch for your changes.
3. Make the necessary changes and commit them.
Expand All @@ -22,8 +24,10 @@ Create virtual envrionment with make venv
git clone https://github.com/X2Cscope/pyx2cscope.git
cd pyx2cscope
python -m venv .venv

#Windows
.venv\Scripts\activate

#linux
source .venv\bin\activate
```
Expand Down Expand Up @@ -55,4 +59,4 @@ sphinx-build -M html doc build --keep-going
## Creating executables
```bash
pyinstaller --noconfirm .\pyx2cscope_win.spec
```
```
8 changes: 4 additions & 4 deletions doc/gui_qt.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ python -m pyx2cscope -q

## Getting Started with pyX2Cscope reference GUI
## Tab: WatchPlot
![WatchPlot](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/pyx2cscope/gui/img/NewGui.jpg)
![WatchPlot](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/doc/images/gui_watch_plot.jpg)
1. pyX2Cscope-GUI is based on Serial interface.
2. The Firmware of the microcontroller should have the X2Cscope library/Peripheral enabled.
3. in Tab WatchPlot, five channels values can be viewed, modified and can be plotted in the plot window.
3. In Tab WatchPlot, five channels values can be viewed, modified and can be plotted in the plot window.
4. In COM Port, either select **Auto Connect** or select the appropriate COM Port, Baud Rate from the drop-down menus and the ELF file of the project, the microcontroller programmed with. <br>
5. Sample time can be changed during run time as well, by default its set to 500 ms.
6. Press on **Connect**
7. Once the connection between pyX2Cscope and Microcontroller takes place, the buttons will be enabled.
8. Information related to the microcontroller will be displayed in the top-left corner.

## Tab: ScopeView
![ScopeView](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/pyx2cscope/gui/img/NewGui2.jpg)
![ScopeView](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/doc/images/gui_scope_view.jpg)

1. ScopeView supports up to 8 PWM resolution channels for precise signal control.
2. You can configure all trigger settings directly within the window. To enable the trigger for a variable, check the corresponding trigger checkbox.
Expand All @@ -40,7 +40,7 @@ python -m pyx2cscope -q
5. To zoom in on the plot, left-click and drag on the desired area. To return to the original view, right-click and select View All.

## Tab: WatchView
![WatchView](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/pyx2cscope/gui/img/NewGui3.jpg)
![WatchView](https://raw.githubusercontent.com/X2Cscope/pyx2cscope/refs/heads/main/doc/images/gui_watch_view.jpg)

1. WatchView lets users add or remove variables as needed. To remove a variable, click the Remove button next to it.
2. Users can visualize variables in live mode with an update rate of 500 milliseconds. This rate is the default setting and cannot be changed.
Expand Down
6 changes: 2 additions & 4 deletions doc/gui_web.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

The Web Graphic User Interface is implemented using Flask, bootstrap 4, jquery and chart.js
It is also an example of how to build a custom GUI using pyX2Cscope.
This interface allows
you to use multiple windows or even access functions from smart devices.
The server runs
by default on your local machine and does not allow external access.
This interface allows you to use multiple windows or even access functions from smart devices.
The server runs by default on your local machine and does not allow external access.
The server has default port 5000 and will be accessible on http://localhost:5000

## Starting the Web GUI
Expand Down
Binary file removed doc/images/NewGui4.jpg
Binary file not shown.
Binary file removed doc/images/Setting.jpg
Binary file not shown.
File renamed without changes
File renamed without changes
File renamed without changes
128 changes: 78 additions & 50 deletions doc/scripting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ X2CScope class

1. Import the X2Cscope class:

.. code-block:: python
.. code-block:: python

from pyx2scope import X2CScope
from pyx2scope import X2CScope

X2CScope class needs one parameter to be instantiated:

Expand All @@ -32,22 +32,29 @@ and TCP/IP are coming in near future. For serial, the only parameter needed is t
default baud rate is set to **115200**. If there's a need to change the baud rate, include the baud_rate
parameter with your preferred baud rate.

2. Instantiate X2CScope with the port:
2. Instantiate X2CScope with the serial port number:

.. code-block:: python
.. code-block:: python

x2c_scope = X2CScope(port="COM16")
x2c_scope = X2CScope(port="COM16")

Import variables
Load variables
----------------

X2Cscope needs the location of the variables inside the controller firmware. The list of variables can be loaded from multiple sources: .elf file, pickle binary and YML text file.
X2Cscope needs to know which variables are currently available on the firmware.
The list of variables can be loaded from multiple file formats:

- Executable and Linkable Format (ELF, .elf, binary)
- Pickle (PKL, .pkl, binary)
- Yaml (YML, .yml, text)

See more details at :ref:`Import and Export variables <import-and-export-variables>` section.
The ELF file is one artifact generated during code compilation. To load the variables, Execute
the code below:

.. code-block:: python
.. code-block:: python

x2c_scope.import_variables(r"..\..\tests\data\qspin_foc_same54.elf")
x2c_scope.import_variables(r"..\..\tests\data\qspin_foc_same54.elf")

Variable class
--------------
Expand All @@ -59,9 +66,9 @@ is a string containing the variable name.

3. Create a Variable object for the variable you want to monitor:

.. code-block:: python
.. code-block:: python

variable = x2c_scope.get_variable('variable_name')
variable = x2c_scope.get_variable('variable_name')

Replace 'variable_name' with the name of the variable you want to monitor. You can create multiple variable
objects as required. To get variables that are underneath a struct, use the "dot" convention:
Expand All @@ -74,18 +81,18 @@ Reading values
4. Once you have gone through these steps, you can use the method **get_value()** to retrieve the actual
value of the variable:

.. code-block:: python
.. code-block:: python

variable.get_value()
variable.get_value()

Writing values
^^^^^^^^^^^^^^

5. To set the value for the respective variable use the method **set_value()**:

.. code-block:: python
.. code-block:: python

variable.set_value(value)
variable.set_value(value)

.. _import-and-export-variables:

Expand Down Expand Up @@ -116,26 +123,26 @@ seaborn, etc.
1. To use the scope functionality, first you need to link a variable as previously explained, and
add this variable to the scope by means of the method: **add_scope_channel(variable: Variable)** :

.. code-block:: python
.. code-block:: python

variable1 = x2c_scope.get_variable("variable1")
variable2 = x2c_scope.get_variable("variable2")
variable1 = x2c_scope.get_variable("variable1")
variable2 = x2c_scope.get_variable("variable2")

x2c_scope.add_scope_channel(variable1)
x2c_scope.add_scope_channel(variable2)
x2c_scope.add_scope_channel(variable1)
x2c_scope.add_scope_channel(variable2)

2. To remove a variable from the scope: **remove_scope_channel(variable: Variable)**, to clear all
variables and reset the scope use instead: **clear_all_scope_channel()**

.. code-block:: python
.. code-block:: python

x2c_scope.remove_scope_channel(variable2)
x2c_scope.remove_scope_channel(variable2)

or

.. code-block:: python
.. code-block:: python

x2c_scope.clear_all_scope_channel()
x2c_scope.clear_all_scope_channel()

Up to 8 channels can be added. Each time you add or remove a variable, the number of channels present
on the channel are returned.
Expand All @@ -145,57 +152,78 @@ Getting Data from Scope

To get data from scope channel you need to follow this sequence:

* Request data
* Check if data is ready (sampling is done)
* Data is ready? Yes, get the data and handle it.
* Data is not ready? Execute some delay and check again.
* After handling the data, start from the beginning requesting new data.
::

+------------------------------------+
| Add variables to the scope channel |
+------------------------------------+
|
v
+--------------------------+
| Request scope data | <---------------+
+--------------------------+ |
| |
v |
+--------------------------+ |
| Is scope data ready? | |
+--------------------------+ |
/ Yes \ No |
v v |
+-----------------+ +--------------------+ |
| Handle the data | | Execute some delay | |
+-----------------+ +--------------------+ |
| | |
+-----------------+------------------+


Step-by-step you need:

1. Request to X2CScope to collect data for the variables registered on the scope channels.

.. code-block:: python
.. code-block:: python

x2c_scope.request_scope_data()
x2c_scope.request_scope_data()

2. Check if the data is ready:
Returns Scope sampling state. Returns: true if sampling has completed, false if it’s yet in progress.

.. code-block:: python
.. code-block:: python

while not x2c_scope.is_scope_data_ready():
time.sleep(0.1)
while not x2c_scope.is_scope_data_ready():
time.sleep(0.1)

3. Get the scope data once sampling is completed

.. code-block:: python
.. code-block:: python

data = x2c_scope.get_scope_channel_data()
data = x2c_scope.get_scope_channel_data()

A simple loop request example to get only 1 frame of scope data is depicted below:

.. code-block:: python
.. code-block:: python

# request scope to start sampling data
x2c_scope.request_scope_data()

# wait while the data is not yet ready for reading
while not x2c_scope.is_scope_data_ready():
time.sleep(0.1)

# request scope to start sampling data
x2c_scope.request_scope_data()
# wait while the data is not yet ready for reading
while not x2c_scope.is_scope_data_ready():
time.sleep(0.1)
for channel, data in x2c_scope.get_scope_channel_data().items():
# Do something with the data.
# channel contains the variable name, data is an array of values
for channel, data in x2c_scope.get_scope_channel_data().items():
# Do something with the data.
# channel contains the variable name, data is an array of values

Triggering
^^^^^^^^^^

To Set up Trigger, any available variable can be selected, by default works on no trigger configuration.
To set any trigger configuration, you need to pass a TriggerConfig imported from from pyx2cscope.x2cscope
To set up a Trigger, any variable added to the scope channel can be selected.
By default, there is no trigger selected.
To set any trigger configuration, you need to pass a TriggerConfig imported from pyx2cscope.x2cscope

.. code-block:: python
.. code-block:: python

trigger_config = TriggerConfig(Variable, trigger_level: int, trigger_mode: int, trigger_delay: int, trigger_edge: int)
x2cscope.set_scope_trigger(trigger_config)
trigger_config = TriggerConfig(Variable, trigger_level: int, trigger_mode: int, trigger_delay: int, trigger_edge: int)
x2cscope.set_scope_trigger(trigger_config)

TriggerConfig needs some parameters like the variable and some trigger values like:

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "pyx2cscope"
version = "0.4.3"
version = "0.4.4"
description = "python implementation of X2Cscope"
authors = [
"Yash Agarwal",
Expand Down
4 changes: 2 additions & 2 deletions pyx2cscope/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""This module contains the pyx2cscope package.

Version: 0.4.3
Version: 0.4.4
"""

import logging

__version__ = "0.4.3"
__version__ = "0.4.4"


def set_logger(
Expand Down
3 changes: 2 additions & 1 deletion pyx2cscope/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
import argparse

import pyx2cscope
from pyx2cscope import gui, utils
from pyx2cscope import utils
from pyx2cscope import gui


def parse_arguments():
Expand Down
Loading