On this page

Usage Guide

This guide provides examples of how to use the Saleae MSO API for common tasks. For basic setup and your first capture, see the Getting Started guide.

Initiating a mixed-signal capture#

from pathlib import Path
from saleae import mso_api

mso = mso_api.MSO()

capture_config = mso_api.CaptureConfig(
    enabled_channels=[
        mso_api.AnalogChannel(channel=0, name="clock"),
        mso_api.DigitalChannel(port=0, channel=0, name="MOSI", threshold_volts=1.6),
    ],
    analog_settings=mso_api.AnalogSettings(sample_rate=100e6),
    capture_settings=mso_api.TimedCapture(capture_length_seconds=0.1),
)

save_dir = Path('my-capture')
capture = mso.capture(capture_config, save_dir)

Loading a previously saved (or exported) capture#

The Logic2 software can export analog waveforms in a binary format using File > Export Data (not save!)

To load a capture from a directory containing those binary export files, use the following:

from pathlib import Path

from saleae import mso_api

# Specify the directory containing the capture files
cap_dir = Path("../tests/data/capture1")

# Load the capture
cap = mso_api.Capture.from_dir(cap_dir)

# Print information about the capture
print(f"Channels: {cap.analog_channel_names}")
print(f"Sample rate: {cap.analog_sample_rate} Hz")
print(f"Duration: {cap.analog_stop_time - cap.analog_start_time:.6f} seconds")

Working with Triggers#

You can define triggers to identify specific events in your captures:

from saleae.mso_api import EdgeTrigger, EdgeTriggerDirection

# Create a trigger for rising edges on channel 1 (channel_index 0) at 0V
trigger = EdgeTrigger(
    channel_index=0,
    threshold_volts=0,
    direction=EdgeTriggerDirection.RISING
)

# Create a trigger for falling edges on the "clock" channel at 1.65V with a 1ms holdoff
trigger_with_holdoff = EdgeTrigger(
    channel_name="clock",
    threshold_volts=1.65,
    direction=EdgeTriggerDirection.FALLING,
    holdoff_seconds=0.001
)

Applying Synthetic Triggers#

If you have a long capture that you need to split into multiples, use split_capture()

from pathlib import Path

from saleae import mso_api
from saleae.mso_api.synthetic_trigger import split_capture

# Load a capture
cap_dir = Path("../tests/data/capture1")
cap = mso_api.Capture.from_dir(cap_dir)

# Set up a new trigger to split on
trigger = mso_api.EdgeTrigger(
    channel_index=0, threshold_volts=0, direction=mso_api.EdgeTriggerDirection.RISING
)

# Split the capture
caps = split_capture(cap, trigger, pre_trigger_seconds=-6e-6, post_trigger_seconds=56e-6)
print(f"Number of triggered segments: {len(caps)}")
# Output: Number of triggered segments: 13810

Processing Triggered Segments#

Once you have split a capture into triggered segments, you can process each segment:

# Process each triggered segment
for i, segment in enumerate(caps[:5]):  # Process just the first 5 segments as an example
    print(f"Segment {i}:")
    print(f"  Duration: {segment.analog_stop_time - segment.analog_start_time:.9f} seconds")
    print(f"  Samples: {segment.num_analog_samples}")

    # You can perform analysis on each segment
    for ch_name, ch_data in segment.analog_data.items():
        print(f"    {ch_name} min: {ch_data.voltages.min():.3f}V, max: {ch_data.voltages.max():.3f}V")
AI/LLM users: see llms-mso-api.txt for machine-readable documentation.