Timestamp along with measurements using JS Python driver

Hi, we’ve recently acquired one JS220 at work for test development purposes and therefore new to using it.

I’ve taken a look into the Joulescope Python driver to find ways of integrating measurements into our test and I’m wondering if there is a simple way of including timestamps to measurements acquired from the device.read(…) function?

I currently see that it is possible to retrieve a dictionary containing “time” and “signals” data, but the “time” does not contain timestamps (does not need to be absolute, relative works fine) for each individual datapoint.

Hi @crezle !

Both the JS110 and JS220 operate at their configured sample rate. You can therefore compute these relative times easily. Here is a script to demonstrate:

import joulescope
import matplotlib.pyplot as plt
import numpy as np

# open device and read duration samples
duration = 1
device = joulescope.scan_require_one()
with device:
    data = device.read(duration=duration, out_format='samples_get', fields=['current', 'voltage'])

# compute time for each sample (x-axis)
x = np.arange(data['time']['samples']['value'], dtype=float)
x *= 1.0 / data['time']['output_sampling_frequency']['value']

# display a plot
f = plt.figure()
for idx, signal_name in enumerate(data['signals'].keys()):
    d = data['signals'][signal_name]
    ax = f.add_subplot(len(data['signals']), 1, idx + 1)
    ax.grid(True)
    ax.plot(x, d['value'])
    ax.set_ylabel(f"{signal_name} ({d['units']})")
ax.set_xlabel('Time (seconds)')
plt.show()
plt.close(f)

Does this answer your question?

Not exactly, but that is because of vague description on my end.

I meant absolute as in not needing one relative to the time of day and relative as exact time of measurement relative to start, where start is equal to 0.

We believe that the time between each measurement is not necessarily perfectly equal (like 0.1s to 0.2, 0.3 etc.), but rather sometimes could be delays (like 0.1s to 0.21 then 0.31) and thought maybe the Joulescope possesses this exact timestamp data somewhere which we would like to be able to retrieve. Just requesting this since the data we intend to measure could be very time critical.

Either way, thank you very much for response! :slight_smile:

Ah, I think I understand. With the read method, the exact start time is subject to the host computer. Getting Windows, macOS, and Linux to do anything with better than 100 milliseconds of accuracy is a losing battle. So, if your code does read, sleep, read, then the interval between the reads will not be exactly the value you provide to sleep.

You can use data['time']['sample_id_range']['value'] to get the exact sample_id range.

However, if you need more control over intervals, you can use an external signal connected to one of the JS220’s general purpose inputs. You can then just record all the data, and use the GPI signal to indicate the areas of interest.

We do have plans to have a general-purpose output output a programmable PWM waveform, which would allow you to generate exact timing without an external input. Unfortunately, this feature does not exist quite yet.

Does this make sense? Do either of these recommendations work for you? If not, let me know, and I am happy to find an approach that does!

1 Like

(1) We suspected that the time given for samples was subject to the host computer, is there any way outside the device.read(…) function that captures the exact time for samples other than using the GPI signals (as we plan to experiment around this later).

(2) I also have another little unrelated question,
when performing a read(…) over a certain duration (not on main thread) I attempted to stop the reading prematurely by performing stop(…) (on main thread), but this did not work and still read for the entire duration. I might be using the functions wrong in attempting to stop, either way, do you know a good solution for this?

For context: I’m using the Joulescope to monitor our company devices for testing power consumption patterns of our device.

Thank you for the extremely quick response, much appreciated!

Hi @crezle - Are you sure you don’t want to simply record all the data to a JLS file for later analysis? If you install pyjoulescope_driver, you can do this:

python -m pyjoulescope_driver record --signal current,voltage,power out.jls

This will definitely preserve the timing, allow you to open the file in the Joulescope UI for manual inspection, and also allow you to open it in python using the pyjls package. For an example of how to read a JLS file, check out the plot entry point.

Yes, read always reads for the entire duration. You need to use start. See the capture_jls_v2 example. Also check out the read_by_callback example.

1 Like

EDIT: The method mentioned at the very start seems to work now (recording for the correct duration at least). The offset is still there, so the recording never starts at zero. The only actual issue now is that the process is inconsistent, meaning that in rare cases the output file is just corrupted and can’t open it. I don’t know the consistent reproduction steps yet for this, but I’ll let you know if I find out. Again, thanks so much for the support!

I attempted to modify your code from capture_jls_v2_example where instead of using user input to stop recording, I would just stop at a line in the code. This code assumes that “device” has already been connected with “scan_require_one” and that start() and stop() has a time.sleep(5) between them.

I see the image below uses read() instead of start(), but I did test this for start() also.

This does print out messages in terminal in addition to being unable to open the .jls file:

image

I also noticed that this worked perfectly fine, other than the large offset of start of measurement


I suspect the behavior of start and stop is not as I expect it to be (which is to be called whenever)?

Hi @crezle - The issue is that large fsr skip:, When it’s too big, the JLS file is filled with so much empty data that it causes problems keeping up with the incoming data. This skip should not exist. It is somehow caused by the joulescope package wrapper around pyjoulescope_driver. I’ll take a look…

1 Like

I’ve noticed that the “fsr skip” you mentioned keeps growing over time, like time elapsed since I turned on the joulescope. At a certain value, this causes the joulescope to be unable to operate until I unplug and replug power (usb)

1 Like

Hi @crezle - The issues should now be resolved with pyjoulescope_driver 1.3.17 and joulescope 1.1.8.

With these new versions, the fsr skip at the start, which was the duration since the JS220 was first used, is fixed. We also fixed the fsr skip warning message at the end, which was caused by the code not cleanly stopping the JS220 streaming.

You can upgrade both pyjoulescope_driver and joulescope using:

python -m pip install -U --upgrade-strategy eager joulescope

Does this fix the issues for you?

1 Like

It seems so! The first couple runs I had this morning went perfect, no skips and no nan.
I’ll let you know if I run into some anomalies during testing. :+1:

1 Like