Giter Club home page Giter Club logo

python-saleae's Introduction

python-saleae

Build Status Documentation Status

This library implements the control protocol for the Saleae Logic Analyzer. It is based off of the documentation and example here: https://github.com/saleae/SaleaeSocketApi

IMPORTANT: You must enable the 'Remote Scripting Server' in Saleae. Click on "Options" in the top-right, the "Developer" tab, and check "Enable scripting socket server". This should not require a restart.

This library requires Saleae Logic 1.2.x or greater. Unfortunately there is no way to check the version of Logic running using the scripting protocol so this is difficult to check at runtime.

Note: Unfortunately, the new Logic2 software does not yet support remote access, so you will have to use the original Logic software.

You can track Logic2 remote access progress on this thread from Saleae: https://discuss.saleae.com/t/scripting-socket-api/108/3

Update: July 2022: Saleae is developing an official remote scripting inteface and library for Logic2. Check out the alpha/beta and give feedback: https://discuss.saleae.com/t/saleae-logic-2-automation-api/1685/13

Currently, this is basically a direct mapping of API calls with some small sanity checking and conveniences. It has not been extensively tested beyond my immediate needs, but it also should not have any known problems.

To get a feel for how the library works and what it can do, try the built-in demo:

#!/usr/bin/env python3
import saleae
saleae.demo()

Issues, updates, pull requests, etc should be directed to github.

Installation

The easiest method is to simply use pip:

(sudo) pip install saleae

Usage

import saleae
s = saleae.Saleae()
s.capture_to_file('/tmp/test.logicdata')

License

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

python-saleae's People

Contributors

aschulm avatar bkmurawski-silabs avatar brainelectronics avatar hexfet avatar jkesanen avatar jonathangjertsen avatar kblomqvist avatar kevinvalk avatar leonardmh avatar lorant-v avatar maltekliemann avatar marcus10110 avatar mnaberez avatar mprinn avatar nicholasbuse avatar ohhorob avatar ppannuto avatar proto3 avatar sophiekovalevsky avatar stawiski avatar timreyes avatar tris-ares avatar vegarwe avatar zorce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-saleae's Issues

Python 2.7 support

There is no mention of this in the README so I'm guessing it's unsupported but I'm unable to get this package working in Python 2.7.10 (which I unfortunately have to use).

I installed through pip and initially had an import error where it was failing to import enum so then I did a pip install enum and tried again but the script is now failing with AttributError: 'module' object has no attribute 'unique' in reference to the enum module.

export_analyzer returns before csv file is completed

Hi,

I'm seeing an erratic behavior when running loops around the export_analyzer functionality.
As far as I see the function returns before the CSV file is complete - this means that subsequent reads of the csv return less data than intended.

Is that something on the python-wrapper level though, or a trouble with the C++ API?
Or - obviously - am I doing sth wrong?

Doc for set_triggers_for_all_channels should specify digital channels

The documentation for set_triggers_for_all_channels should specify "digital" channels for each of the mentions of channels. For example if you have the following channel config:

analog_channels = [0,1,2,3,4,5,6]
digital_channels = [7]

Then you should only pass one trigger parameter into set_triggers_for_all_channels, just for the ditgital channel, even though there are a total of 8 active channels. Ideally this function would call get_active_channels and return a helpful error that says you only need to pass triggers for X digital channels.

get_analyzers raises IndexError

I have everything running under Debian 10. Logic Pro 16 is connected and I have Logic 1.2.18. When I run the sample code below:

#!/bin/python3
import saleae
import time
s = saleae.Saleae()
s.close_all_tabs()
s.set_active_channels(digital=range(16))
s.set_trigger_one_channel(1,saleae.Trigger.NoTrigger)
s.set_capture_seconds(1)
s.set_sample_rate(s.get_all_sample_rates()[0])
s.capture_start()
time.sleep(1)
while True:
    if s.is_processing_complete():
        break
    time.sleep(0.1)
print(s.get_analyzers())

I get:

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    print(s.get_analyzers())
  File "/home/tester/.local/lib/python3.7/site-packages/saleae/saleae.py", line 1014, in get_analyzers
    analyzer_index = int(line.split(',')[1])
IndexError: list index out of range

The content of the line in saleae.py should have been:
I2C, 1
instead I get:
TRUE
and then the library raises an index error.

Implement several missing methods.

There are several methods that have not added to the wrapper which I list below:

  • GetCaptureRange
  • GetViewState
  • SetViewState

Would be great if these can be implemented over the api. For that, I will create a PR for you to review.

erratic behavior after calling get_analyzer

Disclaimer: I just started using this module, so I may not be using it correctly.

I am using the saleae module in my application to capture serial communication to and from a device. Before calling capture_start(), I use the get_analyzers() and get_active_channels() calls to verify that the saleae is setup correctly. The first capture works fine, but subsequent captures raise an exception when calling get_analzyers(). A little debugging showed that the _recv() routine was returning 'TRUE' in response to the 'GET_ANALYZERS' command. It appears there is some sort or synchronization problem and the get_analzyers() is getting the response to a previous is_processing_complete().

My workaround was to use a try block around the get_analyzers() call and loop until successful. The first call raises an exception (except for first time) that I ignore and the second call is successful. This resyncs the socket communication and no further problems (so far).

capture_start() does not immediately return

capture_start() runs _cmd() which waits for an ACK

I guess we could consider a parameter to _cmd that specifies if it should wait for ACK or not, or we can just build the _send right into capture_start(), but that's kinda hacky.

set_active_channels does not send a valid command to Logic

Passing a list argument to saleae.set_active_channels() fails with the following error:

File "C:\PA_Tools\Python27\lib\site-packages\saleae\saleae.py", line 109, in _finish
ret = self._cmd(', '.join(self._to_send))
TypeError: sequence item 2: expected string or Unicode, list found

Simple fix is to just ','.join(['{0:d}'.format(ch) for ch in digital]) on line 483 and ','.join(['{0:d}'.format(ch) for ch in analog]) on line 486.

NAK errors

It looks like this is partially working but I'm getting some NAK Errors and the program crashes when the analyzer starts to capture data.

Using Python 3.5.0

saleae.demo()
Running Saleae connection demo.

Saleae connected.
Press Enter to continue...

Set performance to full.
Press Enter to continue...

Connected devices:
<saleae.ConnectedDevice #1 LOGIC_PRO_8_DEVICE Logic Pro 8 (ffcda53224bbb23a) ACTIVE>
Only one Saleae device. Skipping device selection
Press Enter to continue...

Setting active channels (digital=[0, 1, 2, 3, 4], analog=[0, 1])
Press Enter to continue...

Reading back active channels:
digital=[0, 1, 2, 3, 4]
analog=[0, 1]
Press Enter to continue...

Setting to capture 2e6 samples
Press Enter to continue...

Setting to sample rate to at least digitial 4 MS/s, analog 100 S/s
Set to (100000000, 100)
Press Enter to continue...

Starting a capture
Traceback (most recent call last):
File "", line 1, in
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 546, in demo
while not s.is_processing_complete():
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 360, in is_processing_complete
resp = self._cmd('IS_PROCESSING_COMPLETE')
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 116, in _cmd
ret = self._recv()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 107, in _recv
raise self.CommandNAKedError
saleae.saleae.CommandNAKedError

s = saleae.Saleae()
s.capture_to_file('~/Desktop/test.logicdata')
Traceback (most recent call last):
File "", line 1, in
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 354, in capture_to_file
self._cmd('CAPTURE_TO_FILE, ' + file_path_on_target_machine)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 116, in _cmd
ret = self._recv()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/saleae/saleae.py", line 107, in _recv
raise self.CommandNAKedError
saleae.saleae.CommandNAKedError

Saleae Init function doesn't take logic_path variable

I'm trying to use the standalone version of the Saleae logic SW on Windows and am running into the issue where I can't get the path to the stand alone software passed to the "launch_logic" function in the Saleae class _init_ function. I found #58 which seemed to address the issue but it looks like the logic path doesn't quite make it from the Saleae() init function to the "launch_logic" function.

	def __init__(self, host='localhost', port=10429, quiet=False, args=None):
		self._to_send = []
		self.sample_rates = None
		self.connected_devices = None

		try:
			self._s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			self._s.connect((host, port))
		except ConnectionRefusedError:
			log.info("Could not connect to Logic software, attempting to launch it now")
			Saleae.launch_logic(quiet=quiet, host=host, port=port, args=args)

	def launch_logic(timeout=15, quiet=False, host='localhost', port=10429, logic_path=None, args=None):
		'''Attempts to open Saleae Logic software
		:param timeout: Time in seconds to wait for the Logic software to launch
		:param quiet: Silence terminal output from Logic (Linux only, otherwise ignored)
		:param logic_path:
			Full path to Logic executable. If not provided, attempt to find Logic
			at a standard location.
		:param args:
			Optional argument string to pass to Logic executable
			Examples:
			-disablepopups (suppress notifications)
			-uploaderrors (accept the upload errors dialog and close it)
		:returns True if the Logic software launched and accepted a socket connection within the timeout
		'''
		if platform.system() == 'Darwin':
			logic_path = logic_path or '/Applications/Logic.app'
			if args is not None:
				logic_path += ' --args {}'.format(args)
			if os.system('open {}'.format(logic_path)) != 0:
				raise OSError("Failed to open Logic software")
		elif platform.system() == 'Linux':
			if quiet:
				mode = ' > /dev/null 2>&1 &'
			else:
				mode = ' &'
			arg_string = ''
			if args is not None:
				arg_string = ' ' + args
			if logic_path is not None:
				os.system(logic_path + arg_string + mode)
			elif PY2K:
				log.warn("PY2K support limited. If `Logic` is not on your PATH it will not open.")
				os.system("Logic" + arg_string + mode)
			else:
				path = shutil.which('Logic')
				if path is None:
					raise OSError("Cannot find Logic software. Is 'Logic' in your PATH?")
				os.system(path + arg_string + mode)
		elif platform.system() == 'Windows':
			if logic_path is not None:
				p = logic_path
			else:
				p = os.path.join("C:", os.sep, "Program Files", "Saleae Inc", "Logic.exe")
				if not os.path.exists(p):
					p = os.path.join("C:", os.sep, "Program Files", "Saleae LLC", "Logic.exe")

			popen_args = [p]
			if args is not None:
				popen_args.extend(args.split())

			subprocess.Popen(popen_args)

I think I'm missing something where or does the _init_ function need a variable "logic_path" which can be passed along to "launch_logic"?

Strange behaviour, nothing captured, CommandNAKedError.

I have checked "Enable scripting socket server" in Logic. Using Arch Linux.

In python3 shell, when I first run s = saleae.Saleae(), Logic opens up, but the python line never returns (not even after closing Logic).

When I Ctrl-C in python shell, I get this error:

  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 136, in __init__
    self._s.connect((host, port))
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 139, in __init__
    Saleae.launch_logic()
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 91, in launch_logic
    raise OSError("Failed to open Logic software. Is 'Logic' in your PATH?")
OSError: Failed to open Logic software. Is 'Logic' in your PATH?

Earlier, I changed /usr/bin/logic to /usr/bin/Logic. I'm using the saleae-logic package in Arch Linux (from AUR) - version 1.2.11.

Now, if I run sudo Logic in advance, s = saleae.Saleae() returns immediately.

After running s.capture_start_and_wait_until_finished(), then s.export_data2 always makes a file that has this content:

Time[s], Data[Hex]
0.000000000000000, 0

Here is a sequence of function calls that has some problematic output as well:

>>> s.set_capture_seconds(.5)
>>> s.capture_start_and_wait_until_finished()
>>> s.is_processing_complete()
False
>>> s.is_processing_complete()
False
>>> s.capture_stop()
False
>>> s.get_active_channels()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 517, in get_active_channels
    device = self.get_active_device()
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 485, in get_active_device
    self.get_connected_devices()
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 465, in get_connected_devices
    devices = self._cmd('GET_CONNECTED_DEVICES')
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 200, in _cmd
    ret = self._recv(expect_nak=expect_nak)
  File "/usr/lib/python3.6/site-packages/saleae/saleae.py", line 191, in _recv
    raise self.CommandNAKedError
saleae.saleae.CommandNAKedError

It might be relevant that I have to run Logic with sudo in order for it to be able to find the logic analyser device. But since I already have to run sudo Logic in advance to make s = saleae.Saleae() return, I guess this is fine.

enum34 should not be required above Python 3.4

As Python 3.4 introduced enum module to the standard library, the requirement to install enum34 should be conditional to Python 2.7.

Current situation (unconditional requirement) breaks other modules depending on Enum (e.g. installing PyInstaller on Python 3.6 after installation of Saleae fails with 'enum' module has no 'IntFlag' due to enum34 being imported before standard enum)

Environment: Python 3.6.8, Windows 10

Error using export2

The logic analyzer generate the following error when using the exprot_data2 with a file name and digital_channels selected.

Exporting data [ /home/build/ob_logic/Source/LogicWindow_Automation.cpp; SocketExportData2; 2319 ]
export2 command error: unable to parse any selected channels. Make sure you are using the new format: 1 ANALOG, 2 DIGITAL, etc [ /home/build/ob_logic/Source/LogicWindow_Automation.cpp; SocketExportData2; 2526 ]

The error seems to indicate a newer commad format.
What version of saleae does the python-saleae support?

Is there a way to get ACK when the capture starts

TL;DR Is there a way to start a capture and get an acknowledgment for when the capture starts?

The problem, roughly, is the following: If capture_start is called and a signal arrives at the recording device, say, a nanosecond later, will that signal be recorded? Probably not. What about a second later? Probably. I would like to know for sure, in other words, I would like to get an acknowledgment which, one received by the host, guarantees that the recording is running. I'm fine with waiting a couple of seconds. So, for example:

handle = s.capture_start()
# The recording may or may not be running at this point.
handle.wait()
# Now the recording is guaranteed to be running.
time.sleep(1.0)
s.capture_stop()
# The recording is at least 1.0 seconds long.

Currently, capture_start returns immediately, and doesn't return any kind of callback functionality. It appears that the wrapped C# API may not have this functionality either, see saleae/SaleaeSocketApi#15.

#18 may be related.

documentation suggests sudo pip install

sudo pip install can potentially break an operating system and should be removed from the documentation.
Instead use pip install --user or better use a virtual environment.

Initial Update

The initial setup worked, but all your packages are up to date. You can safely close this issue.

Windows str.replace not implemented properly

You often have a line such as this to fix windows file paths:

# Fix windows path if needed
file_path_on_target_machine.replace('\\', '/')

This does not actually edit the variable but instead returns a new variable as described here (https://docs.python.org/2/library/string.html#string.replace)

I suggest your code should be updated to file_path_on_target_machine = file_path_on_target_machine.replace('\\', '/')

This will remove the need for users to do this themselves before the saleae methods a file_path if using Windows

Error running on windows

Connected devices:
<saleae.ConnectedDevice #1 LOGIC_4_DEVICE Logic 4 (4d7e795b740921b3) ACTIVE>
Only one Saleae device. Skipping device selection
Press Enter to continue...

Setting active channels (digital=[0, 1, 2, 3, 4], analog=[0, 1])
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\benka\Desktop\python-saleae-master\saleae\saleae.py", line 959, in demo
s.set_active_channels(digital, analog)
File "C:\Users\benka\Desktop\python-saleae-master\saleae\saleae.py", line 556, in set_active_channels
self._finish()
File "C:\Users\benka\Desktop\python-saleae-master\saleae\saleae.py", line 167, in _finish
ret = self._cmd(', '.join(self._to_send))
File "C:\Users\benka\Desktop\python-saleae-master\saleae\saleae.py", line 200, in _cmd
ret = self._recv(expect_nak=expect_nak)
File "C:\Users\benka\Desktop\python-saleae-master\saleae\saleae.py", line 191, in _recv
raise self.CommandNAKedError
saleae.saleae.CommandNAKedError

Error running demo()

I am trying to run the demo and I get the following error

>>> saleae.demo()
Running Saleae connection demo.

Saleae connected.
Press Enter to continue...

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/saleae/saleae.py", line 493, in demo
    s.set_performance(PerformanceOption.Full)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/saleae/saleae.py", line 267, in set_performance
    self._cmd('SET_PERFORMANCE, {}'.format(performance.value))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/saleae/saleae.py", line 112, in _cmd
    self._send(s)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/saleae/saleae.py", line 99, in _send
    self._s.send(bytes(s + '\0', 'UTF-8'))
TypeError: str() takes at most 1 argument (2 given)

capture_start function returns an ACK or NAK, but the library never reads it.

The "CAPTURE" command returns an ACK or NAK when the capture has completed. However, the capture_start function does not wait for or read this reply, and there is no corresponding function to explicitly read it later. That means that at some point after the CAPTURE command is sent, the read buffer will receive an ACK or a NAK, but it will not be explicitly read as the reply to the capture command.

There are several problems with this:

  1. The API was not set up to have multiple overlapping commands. Although this works in some cases, there is no way to identify which command originated an incoming ACK/NAK reply.
  2. A future command that is waiting for a reply might pick up the ACK/NAK reply from the CAPTURE command.
  3. The "IS_PROCESSING_COMPLETE" was not set up to work while a capture was in progress, it was designed to be used after a capture completed.

The "STOP_CAPTURE" command is an exception to this. There is special handling code in the Logic software to deal with this, and the "STOP_CAPTURE" command only works when there is a capture in progress. If a capture is in progress, the software will NOT reply with an ACK or NAK. It will NAK if there is no capture in progress. This is because the next expected response from the software is the ACK or NAK from the currently executing command. (this response is returned normally)

The correct capture flow should be:
issue "CAPTURE" or "CAPTURE_TO_FILE" command.

optionally end the capture with the "STOP_CAPTURE" command, but only if the original capture command has not returned yet.

wait for ACK/NAK response from software.

If ACK, then start polling "IS_PROCESSING_COMPLETE"
Note: even if you use the command "CAPTURE_TO_FILE" You must wait for "IS_PROCESSING_COMPLETE" before you start another capture or change any capture settings. This is because the "CAPTURE_TO_FILE" command is very basic, and was designed for saving only the capture tab.

If you are exporting and analyzer, and once "IS_PROCESSING_COMPLETE" has returned true, then you can start polling "IS_ANALYZER_COMPLETE"

Anyway, I think this could be causing other weird issues. For instance, when polling "IS_PROCESSING_COMPLETE" it might get an early ACK when then the capture finishes under the current process. However, then an extra NAK will show up in the buffer next, which will get interpreted as the response to the very next function. This could explain a lot of weird issues with this library.

The capture_start_and_wait_until_finished function has the same problem - it doesn't actually wait for the reply from the "CAPTURE" command, instead it calls the regular capture function and then polls the processing progress.

I think the right solution would be to add a wait_for_capture_finished function. After a start_capture call, all other functions should throw exceptions or otherwise be un-callable except for the new wait_for_capture_finished function and the stop_capture function.

The stop_capture and the wait_for_capture_finished function should both wait for the main capture command to ACK or NAK before returning. Then they should unlock the rest of the functions so they can be used again.

Unfortunately, I haven't had a chance to test this properly. If I'm missing something that does process the reply from the capture command, please let me know!

Add parameter to launch_logic allowing the caller to specify path

It would be useful to be able to specify the path to the Logic application when calling launch_logic so that users with Logic installed in a non-standard location can still use this method.

Suggested change:

@staticmethod
def launch_logic(timeout=5, quiet=False, logic_path=None):
    '''Attempts to open Saleae Logic software'''
    if platform.system() == 'Darwin':
        logic_path = logic_path or '/Applications/Logic.app'
        if os.system('open {}'.format(logic_path)) != 0:
            raise OSError("Failed to open Logic software")
    elif platform.system() == 'Linux':
        if quiet:
            mode = ' > /dev/null 2>&1 &'
        else:
            mode = ' &'

        if logic_path is not None:
            os.system(logic_path + mode)
        elif PY2K:
            log.warn("PY2K support limited. If `Logic` is not on your PATH it will not open.")
            os.system("Logic" + mode)
        else:
            path = shutil.which('Logic')
            if path is None:
                raise OSError("Cannot find Logic software. Is 'Logic' in your PATH?")
            os.system(path + mode)
    elif platform.system() == 'Windows':
        if logic_path is not None:
            p = logic_path
        else:
            p = os.path.join("C:", os.sep, "Program Files", "Saleae Inc", "Logic.exe")
            if not os.path.exists(p):
                p = os.path.join("C:", os.sep, "Program Files", "Saleae LLC", "Logic.exe")
        os.startfile(p)
    else:
        raise NotImplementedError("Unknown platform " + platform.system())

    # Try to intelligently wait for Logic to be ready, but can't wait
    # forever because user may not have enabled the scripting server
    while timeout > 0:
        with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
            if sock.connect_ex(('localhost', 10429)) == 0:
                break
        log.debug('launch_logic: port not yet open, sleeping 1s')
        time.sleep(1)
        timeout -= 1

sleep fails in export_data()

"time" is a parameter in export_data() is a parameter and also there is the python library "time", so time.sleep() fails.

Maybe we can rename the "time" parameter to "time_span" to fix this.

Problem with export_data2

Hi, I am trying to export data with time span. For that purpose, I am using the export_data2. However, it constantly gives error that is given below. How can I cope with that error?
Also, when I tried to run the demo, it also gave same error. I guess it is NAK error, however, I couldnot find any solution.

File "c:\Users\clori\test\main.py", line 49, in
s.export_data2(file_path_on_target_machine=path, digital_channels=[0,3], time_span= [1.0,2.0])
File "C:\Users\New\Desktop\Saleae\venv\Lib\site-packages\saleae\saleae.py", line 1048, in export_data2
digital_active, analog_active = self.get_active_channels()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\clori\test\venv\Lib\site-packages\saleae\saleae.py", line 651, in get_active_channels
device = self.get_active_device()
^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\clori\test\venv\Lib\site-packages\saleae\saleae.py", line 619, in get_active_device
self.get_connected_devices()
File "c:\Users\clori\test\venv\Lib\site-packages\saleae\saleae.py", line 595, in get_connected_devices
devices = self._cmd('GET_CONNECTED_DEVICES')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\clori\test\venv\Lib\site-packages\saleae\saleae.py", line 275, in _cmd
ret = self._recv(expect_nak=expect_nak)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\clori\test\venv\Lib\site-packages\saleae\saleae.py", line 259, in _recv
self._rxbuf += self._s.recv(1024).decode('UTF-8')

Random CommandNAKedError occurrence during "capture_to_file(log_file)" call

I created a small python application which shall sample my hardware during boot. Therefore, I start the board every second overnight.
Unfortunately, my application raise a CommandNAKedError already after my approx. 10 reboots. Until the error occurs, the script works as expected.

Any idea how to get them stable?

Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "av_kit_mdio_analyzer.py", line 35, in logic_task
    device.capture_to_file(log_file)
  File "/localdisk/twesterm/projects/AVKIT/venv/local/lib/python2.7/site-packages/saleae/saleae.py", line 711, in capture_to_file
    self._cmd('CAPTURE_TO_FILE, ' + file_path_on_target_machine)
  File "/localdisk/twesterm/projects/AVKIT/venv/local/lib/python2.7/site-packages/saleae/saleae.py", line 257, in _cmd
    ret = self._recv(expect_nak=expect_nak)
  File "/localdisk/twesterm/projects/AVKIT/venv/local/lib/python2.7/site-packages/saleae/saleae.py", line 248, in _recv
    raise self.CommandNAKedError
CommandNAKedError

Issues with Logic 8

When using a Logic 8 (both in demo mode and when one is plugged into the computer), self.set_sample_rate_by_minimum() asserts that self.sample_rates[0][0] >= self.sample_rates[-1][0], and it seems like the Logic 8 does the opposite (it returns it sorted lowest to highest). Is this intentional, or a bug somewhere (and thus we should check for which device we are using).

get_capture_range throws ValueError

I use the following code snippet:

from saleae import Saleae, Trigger

s = Saleae()
s.set_active_channels(digital=[0], analog=[1])
s.set_sample_rate((500000000, 50000000))
s.set_digital_voltage_option(2)
s.set_trigger_one_channel(digital_channel=0, trigger=Trigger.Posedge)
s.set_capture_seconds(0.4)
s.capture_start_and_wait_until_finished()
s.get_capture_range()

This results in:

>>> INFO:saleae.saleae:Connected.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:/Users/X.X/Documents/project/capture.py", line 10, in <module>
    s.get_capture_range()
  File "C:\Users\X.X\AppData\Roaming\Python\Python39\site-packages\saleae\saleae.py", line 755, in get_capture_range
    index_samples = list(map(int, map(str.strip, indexes.split(','))))
ValueError: invalid literal for int() with base 10: 'TRUE'

This is in W10 with Python3.9

"CommandNAKedError" received while exporting data using export_analyzer

While running the following script

import os
import saleae
import time
s = saleae.Saleae()
s.get_analyzers()
s.set_capture_seconds(10)
s.capture_start_and_wait_until_finished()
save_path = os.path.join(os.getcwd(), "file_name.csv")
# 0 is simple parallel
while not s.is_analyzer_complete(0):
    time.sleep(1)
time.sleep(10)
s.export_analyzer(0,save_path)

i get the following error


CommandNAKedError Traceback (most recent call last)
in ()
2 time.sleep(1)
3 time.sleep(10)
----> 4 s.export_analyzer(0,save_path)
5 # s.export_data2(save_path)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\saleae\saleae.py in export_analyzer(self, analyzer_index, save_path, wait_for_processing, data_response)
972 '''Export analyzer index N and save to absolute path save_path. The analyzer must be finished processing'''
973 if wait_for_processing:
--> 974 while not self.is_analyzer_complete(analyzer_index):
975 time.sleep(0.1)
976 self._build('EXPORT_ANALYZER')

~\AppData\Local\Continuum\anaconda3\lib\site-packages\saleae\saleae.py in is_analyzer_complete(self, analyzer_index)
986 self._build('IS_ANALYZER_COMPLETE')
987 self._build(str(analyzer_index))
--> 988 resp = self._finish()
989 return resp.strip().upper() == 'TRUE'
990

~\AppData\Local\Continuum\anaconda3\lib\site-packages\saleae\saleae.py in _finish(self, s)
181 self._build(s)
182 try:
--> 183 ret = self._cmd(', '.join(self._to_send))
184 finally:
185 self._to_send = []

~\AppData\Local\Continuum\anaconda3\lib\site-packages\saleae\saleae.py in _cmd(self, s, wait_for_ack, expect_nak)
214 ret = None
215 if wait_for_ack:
--> 216 ret = self._recv(expect_nak=expect_nak)
217 return ret
218

~\AppData\Local\Continuum\anaconda3\lib\site-packages\saleae\saleae.py in _recv(self, expect_nak)
205 return None
206 else:
--> 207 raise self.CommandNAKedError
208 ret, self._rxbuf = self._rxbuf.split('ACK', 1)
209 return ret

CommandNAKedError:

Is something wrong with my script ?

Logic16 CommandNAKedError on save_to_file while in loop

I am attempting to write a test utility which will capture and save a new waveform every 20 seconds. After the first 2-3 successful iterations in the loop, the SaveDataToFile routine is raising CommandNAKedError which to my understanding of the docs means that the capture isn't complete when called or there is an issue with the filepath. As the first few files saved successfully, I doubt that the filepath is the issue, though watching the GUI the capture is definitely finished when I call save_to_file

I have attempted to wrap your library in a class of my own to allow for easy reuse.

I was having trouble with the capture_start_and_wait_until_finished function, so I took the code in it and built my own which catches the NAK exception and ignores it. Is this the correct method for dealing with the NAK when calling this function before capture is complete?

I'm using Python 3.5 / Logic 1.2.5

Here is the loop I am currently attempting to run and my class

l.StartCapture()
l.WaitUntilCaptureComplete()
l.SaveDataToFile(filepath + "\Error_" + str(count) + ".logicdata")
time.sleep(20)

class LogicAnalyzer:

    s = 0

    # Initializes the Saleae API
    def __init__(self, host='localhost', port=10429):
        self.s = saleae.Saleae(host,port)

        print("Connected to Logic")

        return

    # Starts the capture sequence
    def StartCapture(self):
        print("Starting capture")
        self.s.capture_start()
        return

    def WaitUntilCaptureComplete(self):
        done = False
        while done == False:
            try:    
                while not self.s.is_processing_complete():
                    print("\t..waiting for capture to complete")
                    time.sleep(1)

                print("Capture complete")

                done = True

            except self.s.CommandNAKedError:
                # This exception is raised if processing of capture is not complete on the
                # side of the analyzer. This is expected for the first few calls, therefore we 
                # simply ignore it until is_processing_complete returns true
                pass

    # Will save last capture in given output location/file
    # Filename must be absolute path
    # Folder must exist for file to be written
    def SaveDataToFile(self, filename):

        self.s.save_to_file(filename)
        print("File Saved")
        return

Not sure if it will help but I also made a log as requested in analog-io's thread.
logfile.txt

is_analyzer_complete raising self.CommandNAKedError when using custom analyzer

s = saleae.Saleae()
index = s.get_analyzers()[0][1]
s.set_capture_seconds(0.25)
s.capture_start()

while not (s.is_analyzer_complete(index)):
time.sleep(0.1)

Traceback (most recent call last):
File "", line 1, in
File "/Users/zach/Docmuents/developer/lib/python3.7/site-packages/saleae/saleae.py", line 1035, in is_analyzer_complete
resp = self._finish()
File "/Users/zach/Docmuents/developer/lib/python3.7/site-packages/saleae/saleae.py", line 224, in _finish
ret = self._cmd(', '.join(self._to_send))
File "/Users/zach/Docmuents/developer/lib/python3.7/site-packages/saleae/saleae.py", line 257, in _cmd
ret = self._recv(expect_nak=expect_nak)
File "/Users/zach/Docmuents/developer/lib/python3.7/site-packages/saleae/saleae.py", line 248, in _recv
raise self.CommandNAKedError
saleae.saleae.Saleae.CommandNAKedError

Path manipulation doesn't work when Logic is running on different OS than the Python module

Logic analyser running on a windows machine,
From a linux machine:

import saleae
la = saleae.Saleae("hostname")
la.save_to_file('c:/test_file.logicdata')
la.load_from_file('c:/test_file.logicdata')

doesn't work.
The same does work on a windows machine.
I believe this is because in linux,
os.path.abspath('c:/test_file.logicdata')
returns
/current/linux/working/directory/C:/test_file.logicdata

Would using os.path.normpath() work better here?

Logic 2 Automation Interface - Feedback Request

Hi @ppannuto, and everyone else currently using the Logic 1.x automation API!

This is Mark from Saleae. We're working on a new automation interface for Logic 2, and would love to get your feedback. You can find more information, including samples here:
https://discuss.saleae.com/t/saleae-logic-2-automation-api/1685

We would really appreciate it if you took a look and let us know what you think! I know the Logic 1.x socket API is quite painful to work with directly (thanks again for creating this awesome python library). We're trying to address as much of that as we can in the new interface.

The new interface uses gRPC, and we'll be publishing the proto file for that, as well as a python library of our own, to maximize flexibility while also providing an easy to use python starting place, inspired in part by this library.

to_send string not cleared in _finish()

How to reproduce:

logic = saleae.Saleae()
logic.set_active_channels([7], [0,1,2,3,4,5,6])
logic.set_capture_seconds(options.trace_time)
logic.set_sample_rate_by_minimum(1e6, 10e3)
logic.set_triggers_for_all_channels([
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.NoTrigger,
saleae.Trigger.Posedge
])

Traceback (most recent call last):
File "./trace-xu3.py", line 396, in
main()
File "./trace-xu3.py", line 195, in main
saleae.Trigger.Posedge
File "/home/aschulm/Projects/battor_research/third_party/python-saleae/saleae/saleae.py", line 145, in set_triggers_for_all_channels
self._finish()
File "/home/aschulm/Projects/battor_research/third_party/python-saleae/saleae/saleae.py", line 88, in _finish
return self._cmd(', '.join(self._to_send))
File "/home/aschulm/Projects/battor_research/third_party/python-saleae/saleae/saleae.py", line 113, in _cmd
return self._recv()
File "/home/aschulm/Projects/battor_research/third_party/python-saleae/saleae/saleae.py", line 106, in _recv
raise self.CommandNAKedError
saleae.CommandNAKedError

How to solve:

self._to_send = [] in finish().

*I'd be happy to fix if you add me as a contributor.

Error reading time_span

File: python-saleae/saleae/saleae.py

It appears that there is a bug in the function export_data2.
For start time and end time you want to use first and second element of array time_span.

elif len(time_span) == 2:
   self._build(['TIME_SPAN', '{0:f}'.format(time_span[0]), '{0:f}'.format(time_span[0])])

I think it should be:

elif len(time_span) == 2:
   self._build(['TIME_SPAN', '{0:f}'.format(time_span[0]), '{0:f}'.format(time_span[1])])

parameter in command set_trigger

Hi,Pannuto
I'm trying to use saleae to do something .
I try the function set_trigger_one_channel and I find out that I am not able to use it to set the channel int Trigger.High/Trigger.Low mode.but Trigger.Posedge/Trigger.Negedge is ok.
I check the API docs in saleae/SaleaeSocketApi/Doc/Logic Socket API Users Guide.md and I found that Python version don't implement the SET_TRIGGER command competely.
Did I misunderstand this point ?
Looking forward to your reply .

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.