Saleae automation test error

After testing automation all day, the system encounters an error and the automation stops.
The error had occurred after about 6 hours or more.

I used the Saleae logic pro 16.
below infomations are error code and my python code.

---------------------------------------- error code ----------------------------------------
loop:1004
INFO:saleae.automation.manager:sub ChannelConnectivity.IDLE
INFO:saleae.automation.manager:sub ChannelConnectivity.CONNECTING
INFO:saleae.automation.manager:sub ChannelConnectivity.READY
Traceback (most recent call last):
File “saleae_capture_10s_glitch_10ns.py”, line 120, in
I2c_JLR = Logic_capture()
File “saleae_capture_10s_glitch_10ns.py”, line 46, in init
with manager.start_capture(
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\saleae\automation\manager.py”, line 583, in start_capture
reply: saleae_pb2.StartCaptureReply = self.stub.StartCapture(
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\grpc_channel.py”, line 1160, in call
return _end_unary_response_blocking(state, call, False, None)
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\grpc_channel.py”, line 1003, in _end_unary_response_blocking
raise _InactiveRpcError(state) # pytype: disable=not-instantiable
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = “Connection reset”
debug_error_string = “UNKNOWN:Error received from peer {created_time:“2024-02-17T19:36:29.1458308+00:00”, grpc_status:14, grpc_message:“Connection reset”}”

Traceback (most recent call last):
File “saleae_capture_10s_glitch_10ns.py”, line 120, in
I2c_JLR = Logic_capture()
File “saleae_capture_10s_glitch_10ns.py”, line 77, in init
capture.save_capture(filepath=capture_filepath)
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\saleae\automation\capture.py”, line 391, in exit
self.close()
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\saleae\automation\capture.py”, line 347, in close
self.manager.stub.CloseCapture(request)
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\grpc_channel.py”, line 1160, in call
return _end_unary_response_blocking(state, call, False, None)
File “C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\grpc_channel.py”, line 1003, in _end_unary_response_blocking
raise _InactiveRpcError(state) # pytype: disable=not-instantiable
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = “failed to connect to all addresses; last error: UNAVAILABLE: ipv4:127.0.0.1:10430: Connection refused”
debug_error_string = “UNKNOWN:Error received from peer {created_time:“2024-02-18T21:50:41.563288+00:00”, grpc_status:14, grpc_message:“failed to connect to all addresses; last error: UNAVAILABLE: ipv4:127.0.0.1:10430: Connection refused”}”

---------------------------------------- python code ----------------------------------------
import serial
import serial.tools.list_ports as sp
from saleae import automation
import time
import os
import os.path
from datetime import datetime
from saleae.automation import GlitchFilterEntry

import keyboard
import serial
from time import sleep

class Logic_capture:
def init(self):
with automation.Manager.connect(port=10430) as manager:

        # Configure the capturing device to record on digital channels 0, 1, 2, and 3,
        # with a sampling rate of 10 MSa/s, and a logic level of 3.3V.
        # The settings chosen here will depend on your device's capabilities and what
        # you can configure in the Logic 2 UI.
        device_configuration = automation.LogicDeviceConfiguration(
            enabled_digital_channels=[0, 1, 2, 3],
            digital_sample_rate=12_500_000, #50_000_000, 
            digital_threshold_volts=3.3,
             glitch_filters=[GlitchFilterEntry(channel_index=0, pulse_width_seconds=100e-9), GlitchFilterEntry(channel_index=1, pulse_width_seconds=100e-9), 
                             GlitchFilterEntry(channel_index=2, pulse_width_seconds=100e-9), GlitchFilterEntry(channel_index=3, pulse_width_seconds=100e-9)]
                            
            #enabled_analog_channels=[0, 1, 2, 3],
            #analog_sample_rate=6_250_000, 
            #analog_threshold_volts=3.3,
        )

    # Record 5 seconds of data before stopping the capture
        capture_configuration = automation.CaptureConfiguration(
            capture_mode=automation.TimedCaptureMode(duration_seconds=60.0)
        )

        # Start a capture - the capture will be automatically closed when leaving the `with` block
        # Note: The serial number 'F4241' is for the Logic Pro 16 demo device.
        #       To use a real device, you can:
        #         1. Omit the `device_id` argument. Logic 2 will choose the first real (non-simulated) device.
        #         2. Use the serial number for your device. See the "Finding the Serial Number
        #            of a Device" section for information on finding your device's serial number.
        with manager.start_capture(
                device_id='7E4E7CEB20BF0697', #심 : BCE6FA60BA0A8B8A #  device_id='F4241' #범석: EAF42608AC81977D # 유욱재:16bit 7E4E7CEB20BF0697
                device_configuration=device_configuration,
                capture_configuration=capture_configuration) as capture:

            # Wait until the capture has finished
            # This will take about 5 seconds because we are using a timed capture mode
            #sleep(10)
            #capture.stop()
            capture.wait()

            # Add an analyzer to the capture
            # Note: The simulator output is not actual SPI data
            # add_analyzer(name, *, label=None, settings=None)
            # add_high_level_analyzer(extension_directory, name, *, input_analyzer, settings=None, label=None)
           # i2c_analyzer = capture.add_analyzer('I2C', label=f'I2C Analyzer', settings={'SDA' : 1, 'SCL' : 0},)
            i2c_analyzer = capture.add_analyzer('I2C', label=f'I2C_issue', settings={'SDA' : 0, 'SCL' : 1},)
            i2c_analyzer2 = capture.add_analyzer('I2C', label=f'I2C_normal', settings={'SDA' : 2, 'SCL' : 3},)
            #i2c_analyzer3 = capture.add_analyzer('I2C Transactions', settings={'input' : 'I2C_issue'},)
            # spi_analyzer = capture.add_analyzer('SPI', label=f'Test Analyzer', settings={
                # 'MISO': 0,
                # 'Clock': 1,
                # 'Enable': 2,
                # 'Bits per Transfer': '8 Bits per Transfer (Standard)'
            # })

            # Store output in a timestamped directory
            output_dir = os.path.join(os.getcwd(), 'logic' )
            if not os.path.exists(output_dir):  
                os.makedirs(output_dir)
            capture_filepath = os.path.join(output_dir, f'output-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}'+'.sal')
            capture.save_capture(filepath=capture_filepath)

class Serial_read:

def init(self):

self.MIK_boardrate = 115200

self.ack_bytearray = bytearray()

def initial_setting(self):

com_list = sp.comports()

com_list_str =

for i in com_list:

com_list_str.append(i.device)

print("All com ports are : ", str(com_list_str))

self.comport = input(“write the comport :” )

self.ser - serial.Serial(port = self.comport, baudrate = self.MIK_boardrate, timeout = 3)

def close_uart(self):

self.ser.close()

def make_stauts(self):

timestr = time.strftime(“%Y%m%d-%H%M%S”)

self.fp = open(timestr + “JLR_status.txt”, ‘at’)

def close_status(self):

self.fp.close()

# def read_status(self):
#     read_data = self.ser.read(self.ser.in_waiting)
#     self.ack_bytearray.extend(read_data)
#     index = self.ack_bytearray.find(bytearray([0x02, 0xB1, 0x00, 0x32]))

#     data_status = self.ack_bytearray[index+4:index + 54]

    #result = read_data.hex()

if name == “main”:
print(“JLR I2C read start !!”)
# JLR = Serial_read()
# JLR.initial_setting()
loop = 0
while True:
print(‘loop:{}’.format(loop))
I2c_JLR = Logic_capture()
time.sleep(0.01)
loop+=1
if keyboard.is_pressed(‘esc’):
print(“finish!”)
# JLR.close_uart()
# JLR.close_status()
break

@ukjaeyu Sorry to hear about this! The formatting of the Python script gets pretty messy when posted directly as text.

Can you send over your .py Python file? We would be happy to take a look once you send that over.

Can you share your mail address.
We will send the code to you. (ukjaeyu is my collegue)

@sooseok.sim1 Sure thing. We can move our discussion to email if you prefer. You can contact us via email using the link below and can send us your Python script as an attachment.
https://contact.saleae.com/hc/en-us/requests/new

In the description section, just make sure to provide a link to this forum post and let us know that it’s you.

automation_test.py (5.7 KB)

Thank you tim. i attached the py file.

@ukjaeyu Thanks for sending that over. First, I’d like to share our general guidelines for automating long captures below for quick reference.

Next, with regards to your Python script, I’m unable to run it due to some missing dependencies. Based on the error reports you shared however, it looks like automation API loses connection with the software during the recording since the software likely crashed.

Can you share more details of the issue below?

  • Can you confirm the exact behavior of the crashes you are seeing? For example, does the software crash when the error occurs? What happens after it crashes?
  • Can you provide a high level summary of how your script operates? It looks your automation script simply performs a single 60 second captures. How many 60 seconds captures do you perform, and do you call your automation script multiple times?

If the software crashes, your next attempt at running your script will fail since the software needs to be running for automation.Manager.connect(port=10430) to work properly.

One workaround for this may be to use with automation.Manager.launch() as manager: to launch the software instead of connecting to a running session of the software. The software will need to be closed before running it, and the software will automatically close itself when the script is complete.

That way, if any crashes occur during the capture, the next call of the script will simply re-launch the software.

I think that this issue.

Error Message: ReadTimeout - Saleae Support

Solution :

  1. device management → USB Controllers → Power mangement → disable : Allow the computer to turn of this devices to save power

  2. click mouse periodic.

@sooseok.sim1 I’m glad to hear you were able to solve the issue by disabling your USB host controllers power saving feature. Feel free to let me know if you continue to run into any further issues.

@timreyes After we’ve setted the disabling of our PC’s USB host controller power saving feature, The issue is occured again.
Now, we are testing . We add the code of the mouse click one times, after waveform capture 1 cycle.

@ukjaeyu When you say that the issue is occurring again, are you saying that you are getting ReadTimeout errors that are causing your automation script to stop? Is this the main issue you are looking to solve?

If so, can you share the results of all of the troubleshooting steps in our ReadTimeout support article linked above? This will help us determine the source of the ReadTimeout errors (whether it’s an issue with USB bandwidth, your USB cable, Logic hardware, PC, or something else).

Please also share the information requested under the “Contacting Support for Additional Help” section.