GithubHelp home page GithubHelp logo

meatysolutions / pico-sdk Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 4.0 285 KB

Continuous streaming from Pico Technology oscilloscopes

License: MIT License

Rust 100.00%
oscilloscope-drivers pico-sdk pico picoscope

pico-sdk's Introduction

pico-sdk

Crates.io docs.rs

Unofficial Rust bindings and wrappers for Pico Technology oscilloscope drivers

This is a meta-crate re-exporting functionality from a number of sub-crates. These crates expose common, high-performance, high-level APIs that hide the differences between the numerous Pico drivers.

Sub Crates

  • pico-common Crates.io

    Common enums, structs and traits.
  • pico-sys-dynamic Crates.io

    Dynamically loaded unsafe bindings for every Pico oscilloscope driver. This crate contains unsafe code.
  • pico-driver Crates.io

    Common, safe wrappers implementing the PicoDriver trait. This crate contains unsafe code.
  • pico-download Crates.io

    Download missing drivers on any platform.
  • pico-device Crates.io

    Device abstraction over PicoDriver trait. Detects available channels and valid ranges.
  • pico-enumeration Crates.io

    Cross driver device enumeration. Detects devices via USB Vendor ID and only loads the required drivers.
  • pico-streaming Crates.io

    Implements continuous gap-less streaming on top of PicoDevice.

Prerequisites

On linux pico-enumeration requires libudev-dev to be installed.

Tests

Some tests open and stream from devices and these fail if devices are not available, for example when run in CI. To run these tests, ensure that ignored tests are run too:

cargo test -- --ignored

Examples

There are a number of examples which demonstrate how the wrappers can be used

cargo run --example streaming_cli

Displays an interactive command line interface that allows selection of device, channel configuration and sample rate. Once capturing, the streaming rate is displayed along with channel values.

cargo run --example enumerate

Attempts to enumerate devices and downloads drivers which were not found in the cache location.

cargo run --example open <driver> <serial>

Loads the specified driver and attempts open the optionally specified device serial.

Usage Examples

Opening and configuring a specific ps2000 device as a PicoDevice:

use std::sync::Arc;
use pico_sdk::prelude::*;

let driver = Driver::PS2000.try_load()?;
let device = PicoDevice::try_open(&driver, Some("ABC/123"))?;

Enumerate all required Pico oscilloscope drivers, configure the first device that's returned and stream gap-less data from it:

use std::sync::Arc;
use pico_sdk::prelude::*;

let enumerator = DeviceEnumerator::new();
// Enumerate, ignore all failures and get the first device
let enum_device = enumerator
                .enumerate()
                .into_iter()
                .flatten()
                .next()
                .expect("No device found");

let device = enum_device.open()?;

// Get a streaming device
let stream_device = device.into_streaming_device();

// Enable and configure 2 channels
stream_device.enable_channel(PicoChannel::A, PicoRange::X1_PROBE_2V, PicoCoupling::DC);
stream_device.enable_channel(PicoChannel::B, PicoRange::X1_PROBE_1V, PicoCoupling::AC);

struct StdoutHandler;

impl NewDataHandler for StdoutHandler {
    fn handle_event(&self, event: &StreamingEvent) {
        println!("Sample count: {}", event.length);
    }
}

// When handler goes out of scope, the subscription is dropped
let handler = Arc::new(StdoutHandler);

// Subscribe to streaming events
stream_device.new_data.subscribe(handler.clone());

// Start streaming with 1k sample rate
stream_device.start(1_000)?;

Enumerate all required Pico oscilloscope drivers. If a device is found but no matching driver is available, attempt to download missing drivers and try enumerating again:

use pico_sdk::prelude::*;

let enumerator = DeviceEnumerator::with_resolution(cache_resolution());

loop {
    let results = enumerator.enumerate();

    println!("{:#?}", results);

    let missing_drivers = results.missing_drivers();

    if !missing_drivers.is_empty() {
        download_drivers_to_cache(&missing_drivers)?;
    } else {
        break;
    }
}

License: MIT

pico-sdk's People

Contributors

timfish avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pico-sdk's Issues

Support for AWG?

Is there any support for Arbitrary Waveform Generator?
All I've seen is Streaming for incoming data, and I only see 2 channels being shown (A, B) on my 2204A.

I've skimmed through most of the crates in this repo but haven't seen a way of using the AWG.

EDIT:
More information about the AWG can be seen at 2.11.47 here.
People seem to be calling it directly from the dll.

Capture rate not working in the rust SDK (Picoscope 2207)

Hi there,
I have noticed using the Rust SDK example code with a Picoscope 2207, that the capture rate is not changing depending on the capture rate chosen in the CLI. It streams at a non-consistent rate, as low as the data points being ~75 ms apart (13Hz), to the fastest I have seen of the data points being ~3 ms apart (300Hz), quite below anything useable for my purposes.

Proberly related, the prompt misses the 1Gz option, and the 100 MS/s errors when chosen with this error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PicoError { status: INVALID_SAMPLE_INTERVAL, context: Some("start_streaming") }', src/main.rs:108:42 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Panic in Arbiter thread.

I haven't tested if this issue is still a problem in the feat/improve branch, let me know if you want me too, or anything else.

Other than the capture rate weirdness, this is an amazing library that is a whole lot better than the official libraries from Picoscope, I really hope I will be able to use this than switching languages to use the official libraries.

Edits: Updated the actual streaming rate info

Error: failed to run custom build command for 'libffi-sys v1.1.0'

Hello,

I have recently tried to incorporate this crate into my project and get the following error when building:

error: failed to run custom build command for `libffi-sys v1.1.0`

Caused by:
  process didn't exit successfully: `/Users/john/Documents/picoscope/target/debug/build/libffi-sys-553610b39d60f72f/build-script-build` (exit code: 101)
  --- stderr
  autogen.sh: line 2: exec: autoreconf: not found
  thread 'main' panicked at 'Generating configure', /Users/john/.cargo/registry/src/github.com-1ecc6299db9ec823/libffi-sys-1.1.0/build/common.rs:8:5
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed

I have also tried to add libffi = "1.0.0" and libffi-sys = "1.1.0" to my dependencies list with no luck.

For reference, I am building on macOS with the latest pico-sdk package downloaded from picotech.

Do you have any tips to get this to work? Thank you!

Exposing the Functionality to Set the Resolution

Hi! This software is amazing and I am making some good use of it. I am using it through python.

I have a PicoScope 5442D. As far as I understand, this device supports 16 bit resolution when using up to 2 channels. However, it seems to me that the data is always acquired at 14 Bit resolution (even when using 1 or 2 channels only).

My questions are:

  • Is there a way to set the resolution? (I couldn't find any)
  • If this functionality is not exposed, would it be possible to add it? Maybe a desired resolution could be set by the enable_channel method, or the start_streaming method (of course, these function would figure out whether that is possible and fallback to the closest possible resolution if not).

Trigger support?

Hello,
first of all thank you for the rust picoscope library.

Played around with it briefly and can say that it is complete enough for my use cases. I do miss trigger setup though. Have seen it in *-sys but not implemented on e.g. the streaming level. Did I miss something, or does the library need some more love?

Thanks,
Jiri

ps6000a driver assumes that every channel gets the same number of samples

Hi!

I'm writing a C++ wrapper/driver for PicoSDK and browsed through your repository to see how others handled the very poorly documented API around continuous streaming. Especially the buffer management is quite mysterious in the PDF and the header files, unfortunately ...

I noticed that you assume that ps6000aGetStreamingLatestValues will give the same noOfSamples_ in the streaming data info for every queried channel, so you use the value of the first structure:

callback(info[0].startIndex_ as usize, info[0].noOfSamples_ as usize);

Unfortunately, I can tell you from experience that this is definitely not the case :-( It is most of the time, but not always. I don't know the exact conditions that trigger this, but it's probably related to some buffer wraparound in the SDK. You'll then get a smaller number of samples in the first call for the second channel (in case you have 2 enabled channels), but they'll catch up again on the second call or so (i.e., you get a higher number of samples).

I'm not using this library myself, but I thought it might be useful for you to know about this quirk. Feel free to close this issue if you don't see this in your usage scenario.

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.