Capture gpi0 gpi1 with jls2 on JS110

I tried to capture gpi0 and gpi1 data with jls2 format from python script, but I don’t see any data on UI when opening captured jls file.
But it works with jls1 format (I see both gpi0 and gpi1 signal on UI).

Do I miss anything for jls2?

environment:

  • python joulescope 1.1.2
  • joulescope JS110
  • joulescope UI 0.10.13
  • python script (capture_gpio.py): add 3 lines in capture.py in examples
  • command: python .\capture_gpio.py --duration 5.0 --frequency 1000000 --jls 2 --signals ‘current,voltage,power’ test_jls2.jls

I added 3 lines (device.parameter_set()) in capture.py as bellow.

...
    with device:
        device.parameter_set('io_voltage', '1.8V')
        device.parameter_set('voltage_lsb','gpi1')
        device.parameter_set('current_lsb','gpi0')
        if args.jls == 1:
            recorder = DataRecorder(args.filename, calibration=device.calibration)
        else:
            recorder = JlsWriter(device, args.filename, signals=args.signals)
            recorder.open()
...

Hi @kenta and welcome to the Joulescope forum!

Unfortunately, the joulescope.jls_v2_writer.JlsWriter class only supports the floating point signals current, voltage, and power. This was due to historical reasons when we first implemented the JLS v2 file format. I definitely need to take a look and improve this.

You will likely find it much easier to use the new pyjoulescope_driver.record.Record class using the record entry point.

Note that the pyjoulescope_driver package uses different parameters than the joulescope package. However, it is really easy to list them. With your Joulescope connected, type:

python -m pyjoulescope_driver info --verbose

I just pushed 825cc91 which improves the record entry point of joulescope_driver to accept set parameters. Starting with version 1.3.2 (hopefully available later today), you will be able to do this:

python -m pyjoulescope_driver record --set "s/i/lsb_src=gpi0" --set "s/v/lsb_src=gpi1" --set "s/extio/voltage=1.8V" --duration 5 --frequency 1000000 --signals i,v,p,0,1 test_jls2.jls

While the Joulescope UI 0.10.x will display the current, voltage, and power fields in a JLS v2 file, it will not display the additional GPI signals. You will need to use Joulescope UI 1.x to display these additional fields. You can find more info on Joulescope UI 1.x here.

To install the new pyjoulescope_driver when it is available (hopefully later today):

pip3 install -U pyjoulescope_driver

Please post and let me know if this works for you!

Hi @mliberty, thank you for support.
I’m glad to know the JlsWriter doesn’t support GPI signals so that I don’t need to spend time on it.

I may choose JLS v1 for now, since UI 0.10.x doesn’t display GPI signal in JSL v2 which is not convenient for check.

But I’ll try pyjoulescope_driver 1.3.2. It looks easy to use.
I assume it outputs only JLS v2 (no JLS v1).

Yes, you can certainly stay with JLS v1 for today. However, I do recommend that you consider updating when you move to Joulescope UI 1.x. JLS v2 is MUCH faster and more flexible to support the new JS220 signals. You can find more JLS v2 details over on GitHub.

Correct. All new Joulescope software will only write JLS v2. However, the Joulescope UI will retain support for displaying JLS v1 for quite some time.

We released pyjoulescope_driver 1.3.2, which you can install using:

pip3 install -U pyjoulescope_driver

Please post and let me know if this works for you!

1 Like

I got lots of error with pyjoulescope_driver 1.3.2.

Command:

python -m pyjoulescope_driver record --set "s/i/lsb_src=gpi0" --set "s/v/lsb_src=gpi1" --set "s/extio/voltage=1.8V" --duration 5 --frequency 1000000 --signals i,v,p,0,1 test_drv_jsl2.jls 2>&1> log.txt

I cannot upload log file, here is part of log (total 15778 lines).

python : INFO:2023-04-14 08:54:53,876:wr_fsr.c:233:pyjls.c:sample_decimate_factor adjusted from 10 to 16
At line:1 char:1
+ python -m pyjoulescope_driver record --set "s/i/lsb_src=gpi0" --set " ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (INFO:2023-04-14...d from 10 to 16:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
INFO:2023-04-14 08:54:53,876:wr_fsr.c:237:pyjls.c:samples_per_data adjusted from 10 to 16
INFO:2023-04-14 08:54:53,938:wr_fsr.c:233:pyjls.c:sample_decimate_factor adjusted from 100 to 104
INFO:2023-04-14 08:54:53,938:wr_fsr.c:237:pyjls.c:samples_per_data adjusted from 100000 to 83200
Traceback (most recent call last):
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\pyjoulescope_driver\record.py", 
line 233, in _on_data
    self._wr.utc(signal_id, 0, value['utc'])
  File "pyjls\binding.pyx", line 341, in pyjls.binding.Writer.utc
OverflowError: int too big to convert
Exception ignored in: 'pyjoulescope_driver.binding._on_cmd_publish2_cbk'
Traceback (most recent call last):
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\pyjoulescope_driver\record.py", 
line 233, in _on_data
    self._wr.utc(signal_id, 0, value['utc'])
  File "pyjls\binding.pyx", line 341, in pyjls.binding.Writer.utc
OverflowError: int too big to convert
ERROR:2023-04-14 08:54:53,938:writer.c:416:pyjls.c:Duplicate signal: 1
Traceback (most recent call last):
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\pyjoulescope_driver\record.py", 
line 224, in _on_data
    self._wr.signal_def(
  File "pyjls\binding.pyx", line 274, in pyjls.binding.Writer.signal_def
RuntimeError: signal_def failed 17
Exception ignored in: 'pyjoulescope_driver.binding._on_cmd_publish2_cbk'

...

Traceback (most recent call last):
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\pyjoulescope_driver\record.py", 
line 224, in _on_data
    self._wr.signal_def(
  File "pyjls\binding.pyx", line 274, in pyjls.binding.Writer.signal_def
RuntimeError: signal_def failed 17
Start recording.  Press CTRL-C to stop.

Installed module.

python -m pip show pyjoulescope_driver
Name: pyjoulescope-driver
Version: 1.3.2
Summary: Joulescope™ driver
Home-page: https://joulescope.readthedocs.io
Author: Jetperch LLC
Author-email: joulescope-dev@jetperch.com
License: Apache 2.0
Location: c:\users\test\appdata\local\programs\python\python310\lib\site-packages
Requires: numpy, pywin32, requests
Required-by: joulescope

seems I can upload file now.
log.txt (1.6 MB)

Hi @kenta - So, something is not right with your setup. Can you update pyjls?

python -m pip install -U pyjls

If you still see the errors, can you post the output of:

python -VV

That’s two “V”'s, not a W. You need a 64-bit version of python. I am running plain vanilla python 3.11.2 on Windows 11 x64:

Python 3.11.2 (tags/v3.11.2:878ead1, Feb  7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]

But, it looks like python 3.11.3 is out. Time to upgrade!

Hi @mliberty, it gets to work without error after updating pyjls from 0.4.3 to 0.5.2.
The captured data on UI looks expected.
I could see gpi0/1 data as well with UI 1.0.8 (alpha).

I think I should use JLS2 because I observed other problem with JLS1, which gave an exception error when performing capture twice in a script, while it works fine with JLS2.
I guess it’s better to move to JLS2.

I’ll use pyjoulescope-driver to capture JLS2 data and examine the captured jls file for i,v,p,0,1 data.

The exception when capture twice with JLS1:

<joulescope.data_recorder.DataRecorder object at 0x000001FC7502BF10> stream_notify() exception
Traceback (most recent call last):
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\joulescope\v1\device.py", line 424, in _stream_process_call
    rv |= bool(fn(*args, **kwargs))
  File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\joulescope\data_recorder.py", line 208, in stream_notify
    raise ValueError('Supports only a single stream_buffer instance')
ValueError: Supports only a single stream_buffer instance

Yes, you definitely need pyjls 0.5.0 or newer. We have not made pyjls an official dependency of pyjoulescope_driver, but perhaps we should to help keep versions matching. If we decide not to make it a dependency, pyjoulescope_driver should at least do a version check.

The JLS v1 error indicates that your code provides two different stream_buffer instances to the DataRecorder. As the error states, you must only provide the same stream_buffer instance to all stream_notify callbacks. This command using pyjoulescope_examples/bin/capture.py still works for me with a JS110:

python capture.py --duration 5.0 --frequency 1000000 --jls 1 test_jls1.jls

While I think JLS v2 is a good choice, you should also be able to use JLS v1 with the correct code. Some things to check:

  1. Close the DataRecorder and do not reuse the same instance between captures.
  2. Do not start/stop streaming while still recording.

Regarding the JLS v1 error, does it still work if you call run() twice in the sample?

if __name__ == '__main__':
    run()
    print("2nd run")
    run()

And does pyjoulescope-driver reset power (diconnect & connect current?) at the beginning?
If so, can I stop it?
I’d like to capture data while target is running. But when starting pyjoulescope-driver, target stops working because current looks dropped.
It also happens when lauching UI (0.10.2/0.10.13/1.0.8). But it doesn’t happen with UI 0.9.11.

In order to run it twice, you have to add device.stream_process_unregister(recorder) after line 111. I just fixed this in 0c90a6c.

With the new pyjoulescope_driver record entry point, I think that you have control over this. Pass “–open restore” on the command line for subsequent recordings to not change settings. For a few more details, check out the docs for open. Does this work for you?

The fix works.

“-open restore” doesn’t. It looks worse. I need to dig in what happens in signal.
Our expectation is joulescope does monitor signal, but not change any.
And it did with UI 0.9.11 and old python module (joulescope 0.9.11).

I noticed that you updated both joulescope_driver (0.5.3) and UI (1.0.9).

Current doesn’t drop when lauching the new UI 1.0.9, so that the target keeps running as expected.
I assume you changed something related to the current drop from UI 1.0.8.

I expected joulescope_driver 0.5.3 also worked, but I got error instead.
I used pyjls 0.5.3 (this is also newer).

The error looks a bug. I think you need to convert pyjls_version from list to tuple.
With fixing the bug, it works as expected (current doesn’t drop).

File "C:\Users\test\AppData\Local\Programs\Python\Python310\lib\site-packages\pyjoulescope_driver\record.py", line 139, in __init__
    if pyjls_version < _PYJLS_VERSION_MIN or pyjls_version >= _PYJLS_VERSION_MAX:
TypeError: '<' not supported between instances of 'list' and 'tuple'

Yes, we addressed pyjoulescope issue #33, which fixed the JS110 behavior at open.

Sorry about the incorrect JLS version check code. I thought I tested this. It would not be the first time I accidentally had the release pyjoulescope_driver installed while making changes in the source tree…

The fix is in bcf2fb6, and it will be available in the next official release.

Great to hear the issue #33 and the fix.
Now I can handle expected capture with JLS2 without any problem.

I look forward to having pyjoulescope_driver 1.3.4.
Thank you for your prompt support!

1 Like

I tried pyjoulescope_driver 1.3.4 (and 1.3.5). But it gives many warnings.
Any thoughts?

Environment:
module: pyjoulescope_driver 1.3.4 (or 1.3.5), pyjls 0.6.0
command:

python -m pyjoulescope_driver record --set "s/i/lsb_src=gpi0" --set "s/v/lsb_src=gpi1" --set "s/extio/voltage=1.8V" --duration 3 --frequency 100000 --signals power,gpi[0],gpi[1] test.jls

Output:

Start recording.  Press CTRL-C to stop.
WARNING:2023-04-27 16:24:20,726:threaded_writer.c:155:pyjls.c:thread msg 3 returned 5
WARNING:2023-04-27 16:24:20,726:threaded_writer.c:155:pyjls.c:thread msg 3 returned 5
...
WARNING:2023-04-27 16:24:20,726:threaded_writer.c:155:pyjls.c:thread msg 3 returned 5
WARNING:2023-04-27 16:24:20,726:threaded_writer.c:155:pyjls.c:thread msg 3 returned 5

Hi @kenta - The JS110 code had an error in determining the sample_id for downsampled data. With the existing 1.3.4, it usually indicates (incorrectly) a one-sample skip on the second data packet for the GPI signals. I already have a fix for this.

However, the observed errors were due to the JLS v2 writer not handling unaligned 1-bit and 4-bit data. It needs to handle this case. It also does not handle sample skips gracefully. There is a nice todo in the JLS code for both these issues that I am working on.

I’ll post again when the fix is ready.

I released pyjls 0.6.1 and pyjoulescope_driver 1.3.6 to address this issue. Here is how to update:

python -m pip install -U pyjls pyjoulescope_driver

I have tested your command for JS110 capture at 100 kHz, and it works for me. Please let me know if you run into issues!

It works fine with combination of pyjls 0.6.1 and pyjoulescope_driver 1.3.6.

Thank you for quick support!

1 Like