├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── PULL_REQUEST_TEMPLATE.md └── issue_template.md ├── .gitignore ├── LICENSE.md ├── README.md ├── discontinuedExamples └── anyScopeExamples │ └── block.py ├── picohrdlExamples ├── picohrdlSingleModeExample.py └── picohrdlStreamingModeExample.py ├── picosdk ├── PicoConnectProbes.py ├── PicoDeviceEnums.py ├── PicoDeviceStructs.py ├── __init__.py ├── constants.py ├── ctypes_wrapper.py ├── device.py ├── discover.py ├── errors.py ├── functions.py ├── functionsExhibitions.py ├── library.py ├── picoMeasurements.py ├── picohrdl.py ├── picosynth.py ├── pl1000.py ├── ps2000.py ├── ps2000a.py ├── ps3000.py ├── ps3000a.py ├── ps4000.py ├── ps4000a.py ├── ps5000.py ├── ps5000a.py ├── ps6000.py ├── ps6000a.py ├── psospa.py ├── psospaBlockExample.py ├── usbDrDaq.py ├── usbPT104.py └── usbtc08.py ├── picosynthExamples └── picosynthFrequencySweepExample.py ├── pl1000Examples ├── pl1000SingleModeExample.py └── pl1000StreamingModeExample.py ├── ps2000Examples ├── advanced triggers │ ├── trigger_read_dropout.py │ ├── trigger_read_interval.py │ ├── trigger_read_pwq.py │ ├── trigger_read_runt.py │ ├── trigger_read_window.py │ └── trigger_read_wpwq.py ├── block_read.py ├── device_info.py ├── gen_sq_wave.py ├── ps2000BlockExample.py ├── ps2000ETSBlockExample.py ├── ps2000SigGen.py └── streaming_mode │ ├── streaming_mode.py │ ├── streaming_mode_gathering.py │ ├── streaming_mode_polling.py │ └── streaming_mode_threaded.py ├── ps2000aExamples ├── ps2000aBlockAdvancedEdgeExample.py ├── ps2000aBlockExample.py ├── ps2000aBlockExampleCallbackMethod.py ├── ps2000aMSOBlockExample.py ├── ps2000aRapidBlockExample.py ├── ps2000aSigGen.py └── ps2000aStreamingExample.py ├── ps3000EExamples ├── ps3000EBlockExample.py ├── ps3000ERapidBlockExample.py └── ps3000EStreamingModeExample.py ├── ps3000aExamples ├── ps3000aBlockAdvancedTriggerExample.py ├── ps3000aBlockExample.py ├── ps3000aBlockMSOExample.py ├── ps3000aRapidBlockExample.py ├── ps3000aSigGen.py └── ps3000aStreamingExample.py ├── ps4000Examples ├── ps4000BlockExample.py └── ps4000StreamingExample.py ├── ps4000aExamples ├── ps4000aBlockAdvancedEdgeTriggerExample.py ├── ps4000aBlockDropoutTriggerExample.py ├── ps4000aRapidBlockExample.py ├── ps4000aRapidBlockWaveformAveragingExample.py ├── ps4000aSigGen.py ├── ps4000aStreamingExample.py ├── ps4444BlockExample.py ├── ps4444BlockPicoConnectProbesExample.py └── ps4824BlockExample.py ├── ps5000Examples ├── ps5000BlockExample.py ├── ps5000RapidBlockExample.py └── ps5000StreamingExample.py ├── ps5000aExamples ├── ps5000aBlockAdvancedTriggerExample.py ├── ps5000aBlockCallbackExample.py ├── ps5000aBlockExample.py ├── ps5000aBlockLevelPulseWidthAdvancedTriggerExample.py ├── ps5000aBlockMSOExample.py ├── ps5000aBlockMSOTriggerExample.py ├── ps5000aBlockWindowPulseWidthAdvancedTriggerExample.py ├── ps5000aRapidBlockExample.py ├── ps5000aSigGen.py └── ps5000aStreamingExample.py ├── ps6000Examples ├── ps6000BlockAdvancedTriggerExample.py ├── ps6000BlockExample.py ├── ps6000GetInfoExample.py ├── ps6000RapidBlockExample.py ├── ps6000RapidBlockTriggerTimestampExample.py ├── ps6000SigGen.py └── ps6000StreamingExample.py ├── ps6000aExamples ├── ps6000aBlockAdvancedTriggerExample.py ├── ps6000aBlockExample.py ├── ps6000aBlockExampleExtClk.py ├── ps6000aBlockExampleTrigTimes.py ├── ps6000aBlockMSODigitalTriggerExample.py ├── ps6000aBlockMSOExample.py ├── ps6000aGetUnitInfo.py ├── ps6000aRapidBlockExample.py ├── ps6000aSigGenExample.py └── ps6000aStreamingModeExample.py ├── pt104Examples ├── pt104EnumerateTestsExample.py └── pt104Example.py ├── requirements-for-examples.txt ├── requirements.txt ├── setup.py ├── setupPicosynth.py ├── test ├── __init__.py ├── run_examples.sh ├── test_discover.py ├── test_get_unit_info.py ├── test_helpers.py ├── test_open_close_unit.py ├── test_set_channel.py └── test_timebase.py ├── usbdrdaqExamples ├── usbdrdaqPhBlockExample.py └── usbdrdaqScopeBlockExample.py └── usbtc08Examples ├── tc08SingleModeExample.py └── tc08StreamingModeExample.py /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at support@picotech.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions to the picosdk-python-examples repository. By contributing to this repository, you agree to abide by our [code of conduct](CODE_OF_CONDUCT.md). 4 | 5 | ## Steps to contribute 6 | 7 | 1. Fork, then clone the repository: 8 | 9 | ``` 10 | git clone https://github.com/YOUR-USERNAME/picosdk-python-wrappers.git 11 | ``` 12 | 13 | 2. Create a new branch - specify a name in lowercase, using hyphens to link words e.g. `fft-example` 14 | 15 | 3. Push to the new branch on your fork, and then submit a pull request. 16 | 17 | We will then review the pull request. 18 | 19 | ## Pull request guidelines 20 | 21 | * Follow the conventions in the other file headers if adding a new file, or changing an existing file 22 | * If contributing a new file, ensure that it is in the appropriate location in the repository directory structure 23 | * [Commit messages](https://chris.beams.io/posts/git-commit/#seven-rules) should clearly communicate the reason for the change -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes #. 2 | 3 | Changes proposed in this pull request: 4 | 5 | * 6 | * 7 | * 8 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Setup 2 | 3 | * Example filename: 4 | * Version of Python: 5 | * Pico Technology device model: 6 | * Driver name, version number and platform (32- or 64-bit): 7 | * Operating system: 8 | * USB port type (e.g. 2.0): 9 | 10 | ### Description 11 | 12 | #### Steps to reproduce the issue 13 | 14 | Use one of two methods to describe the issue: 15 | 16 | 1. A list of steps to reproduce the issue. 17 | 1. A natural language description of what you were doing when the issue occurred if you are unable to work out what the steps are. 18 | 19 | #### Actual Result 20 | 21 | 22 | 23 | #### Expected Result 24 | 25 | 26 | 27 | ### Notes 28 | 29 | Include any other information here. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore file for picosdk-ps6000a-matlab-instrument-driver 2 | # Untracked files/folders to ignore. 3 | 4 | # Windows platforms 5 | 6 | **/*.obj 7 | **/*.lib 8 | **/*.exp 9 | **/*.bak 10 | 11 | # All platforms 12 | 13 | **/*.h 14 | 15 | # Byte-compiled / optimized / DLL files 16 | __pycache__/ 17 | *.py[cod] 18 | 19 | # Distribution / packaging 20 | build/ 21 | dist/ 22 | *.egg-info/ 23 | *.egg -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2019 Pico Technology Ltd. 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # picosdk-python-wrappers 2 | 3 | Welcome to the PicoSDK for Python. It allows you to control PicoScope devices in your own Python programs. 4 | 5 | ## Getting started 6 | 7 | To use this code you will need to install the PicoSDK C libraries. 8 | 9 | ### Microsoft Windows 10 | 11 | Please visit [our Downloads page](https://www.picotech.com/downloads) to download the 32-bit or 64-bit PicoSDK C Libraries for Windows. 12 | Please take care to match the "bitness" of your python to the PicoSDK. 13 | 14 | ### Linux 15 | 16 | Follow the instructions from our [Linux Software & Drivers for Oscilloscopes and Data Loggers page](https://www.picotech.com/downloads/linux) 17 | to install the required driver packages for your product. 18 | 19 | ### macOS 20 | 21 | Please visit [our Downloads page](https://www.picotech.com/downloads) to download the PicoSDK C Libraries for MacOS. 22 | 23 | ## Installing the python driver bindings 24 | 25 | A `distutils` installer is provided. After you have installed the PicoSDK 26 | driver package (see above), the Python package can be installed using the 27 | following command in the top-level directory: 28 | 29 | pip install . 30 | 31 | If you are not using a virtualenv or are not elevated, use: 32 | 33 | python setup.py install 34 | 35 | ======= 36 | For using the AS108 you will need to use the following as well: 37 | 38 | python setupPicosynth.py install 39 | 40 | 41 | On macOS and Linux you will either need to use `sudo` with this command, to 42 | install into the system folders, or to install for the current user only you 43 | can use: 44 | 45 | pip install . --user 46 | 47 | Within python, the library for `import` is called `picosdk`. 48 | 49 | ## Compatibility 50 | 51 | This code is written to be compatible with both Python 2.7 and Python 3 (any version). 52 | 53 | If you find a compatibility problem please raise an [Issue](https://www.picotech.com/tech-support), listing all the versions you can find (python, numpy, 54 | picosdk commit hash, etc.) and your error message(s). 55 | 56 | ## C interface 57 | 58 | You can access C driver functions directly (ctypes calls) by their original C name, following the [Programmer's 59 | Guides](https://github.com/picotech/picosdk-python-wrappers#programmers-guides) exactly. Examples are provided in the folders like `psX000[a]Examples/`. 60 | 61 | ### Programmer's Guides 62 | 63 | You can download Programmer's Guides providing a description of the API functions for the relevant PicoScope or 64 | PicoLog driver from our [Documentation page](https://www.picotech.com/library/documentation). 65 | 66 | ## Python interface 67 | 68 | We are in the process of adding Pythonic wrappers around the C functions. If we haven't got to your feature yet or your device is listed as one of the [unsupported models](https://github.com/picotech/picosdk-python-wrappers#unsupported-models), 69 | let us know that you're waiting in an [Issue](https://www.picotech.com/tech-support) 70 | 71 | ### Unsupported models 72 | 73 | The following drivers and devices are not yet supported: 74 | 75 | * `plcm3` - PicoLog CM3 Current Data Logger 76 | * `ps3000` - PicoScope 3204, 3205, 3206, 3223, 3224, 3423 & 3423 77 | 78 | ### Dependencies 79 | 80 | As well as depending on the C libraries, the Python wrappers use some Python libraries like `numpy`. Many of the 81 | examples scripts also use the `matplotlib` plotting library. You can install these dependencies with pip as follows: 82 | 83 | pip install -r requirements.txt 84 | pip install -r requirements-for-examples.txt 85 | 86 | ### Driver-agnostic examples 87 | 88 | The `anyScopeExamples` folder contains examples in pure python which do the same thing as the C-style examples, but 89 | in a driver-generic way. These examples are currently not being developed further but are still avaliable to use 90 | and develop futher yourself. 91 | 92 | ### Python Classes 93 | 94 | #### Library 95 | 96 | `picosdk.library.Library` contains a base class for each of the driver classes. It does the job of translating python 97 | types into C ones, and back again, and some unit conversions to get rid of nano, micro and milli-style prefixes. It also 98 | handles any differences in programming API between PicoScope driver versions. 99 | 100 | #### Device 101 | 102 | `picosdk.device.Device` contains the concrete class which represents a PicoScope with a valid handle. It caches some 103 | information about the device state, like the currently selected voltage ranges of the channels. 104 | 105 | It is implemented in terms of the Library class' public interface, and deals almost entirely with python types. The 106 | main exception is its handling of numpy arrays - it (knowing the voltage ranges) is responsible for converting the raw 107 | ADC counts that the driver uses for amplitude into physical units. 108 | 109 | ## Testing this code 110 | 111 | Check which device driver your device uses, and check the constants at the top of test/test_helpers.py to enable the 112 | relevant drivers for connected-device tests. (most tests use this). 113 | 114 | To check which driver your device uses, you can use `picosdk.discover`: 115 | 116 | from picosdk.discover import find_all_units 117 | 118 | scopes = find_all_units() 119 | 120 | for scope in scopes: 121 | print(scope.info) 122 | scope.close() 123 | 124 | You should then configure test/test_helpers.py's list of connected devices, so it can run all the tests we have 125 | on your device. 126 | 127 | To run the unit tests, you will need to install nose (e.g. `pip install nose`.) Then, run `nosetests` in the root of 128 | the repo. 129 | 130 | ## Obtaining support 131 | 132 | Please visit our [Support page](https://www.picotech.com/tech-support) to contact us directly or visit our [Test and Measurement Forum](https://www.picotech.com/support/forum17.html) to post questions. 133 | 134 | ## Copyright and licensing 135 | 136 | See [LICENSE.md](LICENSE.md) for license terms. 137 | 138 | *PicoScope*, *PicoLog* and *PicoSDK* are registered trademarks of Pico Technology Ltd. 139 | 140 | *Windows* is a registered trademark of Microsoft Corporation. 141 | 142 | *macOS* is a registered trademark of Apple Inc. 143 | 144 | *Linux* is the registered trademark of Linus Torvalds in the U.S. and other countries. 145 | 146 | Copyright © 2018-2019 Pico Technology Ltd. All rights reserved. 147 | -------------------------------------------------------------------------------- /discontinuedExamples/anyScopeExamples/block.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | from __future__ import print_function 5 | from picosdk.discover import find_unit 6 | from picosdk.device import ChannelConfig, TimebaseOptions 7 | import matplotlib.pyplot as plt 8 | 9 | with find_unit() as device: 10 | 11 | print("found PicoScope: %s" % (device.info,)) 12 | 13 | channel_configs = [ChannelConfig('A', True, 'DC', 5.)] 14 | microsecond = 1.e-6 15 | # the entry-level scopes only have about 8k-samples of memory onboard for block mode, so only ask for 6k samples. 16 | timebase_options = TimebaseOptions(microsecond, None, 6000 * microsecond) 17 | 18 | times, voltages, overflow_warnings = device.capture_block(timebase_options, channel_configs) 19 | 20 | for channel, data in voltages.items(): 21 | label = "Channel %s" % channel 22 | if channel in overflow_warnings: 23 | label += " (over range)" 24 | plt.plot(times, data, label=label) 25 | 26 | plt.xlabel('Time / s') 27 | plt.ylabel('Amplitude / V') 28 | plt.legend() 29 | plt.show() 30 | 31 | -------------------------------------------------------------------------------- /picohrdlExamples/picohrdlSingleModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PICOLOG HIGH RESOLUTION DATA LOGGER SINGLE MODE EXAMPLE 5 | # 6 | # This example demonstrates how to capture a single value from an ADC-20 or ADC-24 Precision Data Logger. 7 | 8 | 9 | import ctypes 10 | import numpy as np 11 | from picosdk.picohrdl import picohrdl as hrdl 12 | from picosdk.functions import assert_pico2000_ok 13 | 14 | # Create chandle and status ready for use 15 | chandle = ctypes.c_int16() 16 | status = {} 17 | 18 | # Open unit 19 | status["openUnit"] = hrdl.HRDLOpenUnit() 20 | assert_pico2000_ok(status["openUnit"]) 21 | chandle=status["openUnit"] 22 | 23 | # Set mains noise rejection 24 | # Reject 50 Hz mains noise 25 | status["mainsRejection"] = hrdl.HRDLSetMains(chandle, 0) 26 | assert_pico2000_ok(status["mainsRejection"]) 27 | 28 | # Set single reading 29 | range = hrdl.HRDL_VOLTAGERANGE["HRDL_2500_MV"] 30 | conversionTime = hrdl.HRDL_CONVERSIONTIME["HRDL_100MS"] 31 | overflow = ctypes.c_int16(0) 32 | value = ctypes.c_int32() 33 | status["getSingleValue"] = hrdl.HRDLGetSingleValue(chandle, 5, range, conversionTime, 1, ctypes.byref(overflow), ctypes.byref(value)) 34 | assert_pico2000_ok(status["getSingleValue"]) 35 | 36 | # Display value 37 | print(value.value) 38 | 39 | # Close unit 40 | status["closeUnit"] = hrdl.HRDLCloseUnit(chandle) 41 | assert_pico2000_ok(status["closeUnit"]) 42 | 43 | # Print status 44 | print(status) -------------------------------------------------------------------------------- /picohrdlExamples/picohrdlStreamingModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PICOLOG HIGH RESOLUTION DATA LOGGER STREAMING MODE EXAMPLE 5 | # 6 | # This example demonstrates how to capture data streaming from an ADC-20 or ADC-24 Precision Data Logger. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.picohrdl import picohrdl as hrdl 11 | from picosdk.functions import assert_pico2000_ok 12 | import matplotlib.pyplot as plt 13 | import time 14 | 15 | # Create chandle and status ready for use 16 | chandle = ctypes.c_int16(16384) 17 | status = {} 18 | maxSamples = 200 #1_000 19 | 20 | status["closeUnit"] = hrdl.HRDLCloseUnit(chandle) 21 | 22 | # Open unit 23 | status["openUnit"] = hrdl.HRDLOpenUnit() 24 | assert_pico2000_ok(status["openUnit"]) 25 | chandle = status["openUnit"] 26 | 27 | # Set mains noise rejection 28 | # Reject 50 Hz mains noise 29 | status["mainsRejection"] = hrdl.HRDLSetMains(chandle, 0) 30 | assert_pico2000_ok(status["mainsRejection"]) 31 | 32 | # Setup Channel(s) 33 | range = ctypes.c_int16(0) 34 | range = hrdl.HRDL_VOLTAGERANGE["HRDL_2500_MV"] 35 | overflow = ctypes.c_int16(0) 36 | value = ctypes.c_int32() 37 | 38 | channel = ctypes.c_int16(1) # (Ch number) ADC-20: Ch1 to Ch8 , ADC-24: Ch1 to Ch16 39 | enabled = ctypes.c_int16(1) 40 | singleEnded = ctypes.c_int16(1) # 0: differential, Not 0: for single ended 41 | 42 | status["SetAnalogInChannel"] = hrdl.HRDLSetAnalogInChannel(chandle, channel, enabled, range, singleEnded) 43 | assert_pico2000_ok(status["SetAnalogInChannel"]) 44 | 45 | # Streaming 46 | # sampleInterval_ms = conversionTime x NumberOfChannels + 20ms 47 | # 20ms = 1/3 of the fastest sample time for one channel 48 | sampleInterval_ms = ctypes.c_int32(100 * 1 + 20) 49 | conversionTime = hrdl.HRDL_CONVERSIONTIME["HRDL_100MS"] 50 | status["SetInterval"] = hrdl.HRDLSetInterval(chandle, sampleInterval_ms, conversionTime) 51 | assert_pico2000_ok(status["SetInterval"]) 52 | 53 | nValues = ctypes.c_int32(20) 54 | method = ctypes.c_int16(2) # BM_STREAM (2) 55 | status["Run"] = hrdl.HRDLRun(chandle, nValues, method) 56 | assert_pico2000_ok(status["Run"]) 57 | 58 | TotalValues = 0 59 | # Buffers 60 | TempBuffer = (ctypes.c_int32 * 100)() 61 | BufValues = [] 62 | 63 | myready = ctypes.c_int16(0) 64 | check = ctypes.c_int16(0) 65 | # Check for data collection 66 | while TotalValues < maxSamples: 67 | while myready.value == check.value: 68 | myready.value = hrdl.HRDLReady(chandle) 69 | time.sleep(0.02) # 20ms = 1/3 of the fastest sample time for one channel 70 | # print("ready = ", myready) # DEBUG 71 | noOfValues = ctypes.c_int32(20) # Ask for 20 samples 72 | noOfValues = hrdl.HRDLGetValues(chandle, ctypes.byref(TempBuffer), ctypes.byref(overflow), noOfValues) 73 | TotalValues = TotalValues + int(noOfValues) 74 | print("TotalValues = ",TotalValues ,", noOfValues = ", int(noOfValues) ) # DEBUG 75 | #sleep (sampleInterval_ms - 20ms /1000) 76 | time.sleep( ((100 * 1 + 20) - 20) /1000) 77 | 78 | #for i in range(noOfValues): 79 | ####TempBuffer[i] = adc2mV(TempBuffer[i], channelRange, maxADC) 80 | #BufValues.append(float(TempBuffer[i])) 81 | #if(noOfValues != 0): 82 | # BufValues.append(float(TempBuffer[0])) 83 | 84 | # Convert to mV and Append values App Buffer 85 | loop = noOfValues 86 | while (loop != 0): 87 | loop = loop -1 88 | # TempBuffer[loop] = adc2mVpl1000(TempBuffer[loop], 2500, 8388607) # adc2mVpl1000(value, Max range in mV, Max ADC count) 89 | #TempBuffer[loop] = (TempBuffer[loop] * 2500) / 8388607 90 | BufValues.append(float((TempBuffer[loop] * 2500) / 8388607)) 91 | 92 | # Stop data collection 93 | hrdl.HRDLStop(chandle) 94 | 95 | # Create time data 96 | timeMs = np.linspace(0, (len(BufValues) -1) * 0.1, len(BufValues)) 97 | 98 | # plot data 99 | plt.plot(timeMs, BufValues[:]) 100 | plt.xlabel('Time (s)') 101 | plt.ylabel('Voltage (mV)') 102 | plt.show() 103 | 104 | # Close unit 105 | status["closeUnit"] = hrdl.HRDLCloseUnit(chandle) 106 | assert_pico2000_ok(status["closeUnit"]) 107 | 108 | # Print status 109 | print(status) -------------------------------------------------------------------------------- /picosdk/PicoConnectProbes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | This is a Python module defining the enumerations from the PicoConnectProbes.h C header 6 | file for use with various PicoScope oscilloscopes driver API functions. 7 | """ 8 | 9 | from ctypes import * 10 | from picosdk.constants import make_enum 11 | from picosdk.library import Library 12 | 13 | class PicoConnectProbeslib(Library): 14 | def __init__(self): 15 | super(PicoConnectProbeslib, self).__init__("picoConnectProbes") 16 | 17 | 18 | picoConnectProbes = PicoConnectProbeslib() 19 | 20 | def _define_pico_probe_range_info(): 21 | PICO_PROBE_NONE_NV = 0 22 | PICO_X1_PROBE_NV = 1 23 | PICO_X10_PROBE_NV = 10 24 | 25 | return {k.upper(): v for k, v in locals().items() if k.startswith("PICO")} 26 | 27 | picoConnectProbes.PICO_PROBE_RANGE_INFO = _define_pico_probe_range_info -------------------------------------------------------------------------------- /picosdk/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | -------------------------------------------------------------------------------- /picosdk/ctypes_wrapper.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # Copyright (C) 2018-2019 Pico Technology Ltd. See LICENSE file for terms. 4 | # 5 | import ctypes 6 | import sys 7 | 8 | if sys.platform == 'win32': 9 | C_CALLBACK_FUNCTION_FACTORY = ctypes.WINFUNCTYPE 10 | else: 11 | C_CALLBACK_FUNCTION_FACTORY = ctypes.CFUNCTYPE 12 | -------------------------------------------------------------------------------- /picosdk/discover.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | from picosdk.errors import DeviceNotFoundError 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.ps2000a import ps2000a 7 | from picosdk.ps3000 import ps3000 8 | from picosdk.ps3000a import ps3000a 9 | from picosdk.ps4000 import ps4000 10 | from picosdk.ps4000a import ps4000a 11 | from picosdk.ps5000a import ps5000a 12 | from picosdk.ps6000 import ps6000 13 | from picosdk.ps6000a import ps6000a 14 | 15 | 16 | # the A drivers are faster to enumerate devices, so search them first. 17 | drivers = [ 18 | ps2000a, 19 | ps3000a, 20 | ps4000a, 21 | ps5000a, 22 | ps6000a, 23 | ps6000, 24 | ps2000, 25 | ps3000, 26 | ps4000, 27 | ] 28 | 29 | 30 | def find_unit(): 31 | """Search for, open and return the first device connected, on any driver.""" 32 | for driver in drivers: 33 | try: 34 | device = driver.open_unit() 35 | except DeviceNotFoundError: 36 | continue 37 | return device 38 | raise DeviceNotFoundError("Could not find any devices on any drivers.") 39 | 40 | 41 | def find_all_units(): 42 | """Search for, open and return ALL devices on ALL pico drivers (supported in this SDK wrapper).""" 43 | devices = [] 44 | for driver in drivers: 45 | try: 46 | device = driver.open_unit() 47 | except DeviceNotFoundError: 48 | continue 49 | devices.append(device) 50 | if not devices: 51 | raise DeviceNotFoundError("Could not find any devices on any drivers.") 52 | return devices -------------------------------------------------------------------------------- /picosdk/errors.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | 5 | 6 | class PicoError(Exception): 7 | """All errors thrown explicitly by this package will be PicoError's.""" 8 | pass 9 | 10 | 11 | class FeatureNotSupportedError(PicoError): 12 | """raised when a feature is not supported on the connected device.""" 13 | pass 14 | 15 | 16 | class CannotFindPicoSDKError(PicoError, IOError): 17 | pass 18 | 19 | 20 | class CannotOpenPicoSDKError(PicoError, IOError): 21 | pass 22 | 23 | 24 | class DeviceNotFoundError(PicoError, IOError): 25 | pass 26 | 27 | 28 | class ArgumentOutOfRangeError(PicoError, ValueError): 29 | pass 30 | 31 | 32 | class ValidRangeEnumValueNotValidForThisDevice(FeatureNotSupportedError, ValueError): 33 | pass 34 | 35 | 36 | class DeviceCannotSegmentMemoryError(FeatureNotSupportedError, TypeError): 37 | pass 38 | 39 | 40 | class InvalidMemorySegmentsError(PicoError, ValueError): 41 | pass 42 | 43 | 44 | class InvalidTimebaseError(PicoError, ValueError): 45 | pass 46 | 47 | 48 | class InvalidTriggerParameters(PicoError, ValueError): 49 | pass 50 | 51 | 52 | class InvalidCaptureParameters(PicoError, ValueError): 53 | pass 54 | 55 | 56 | class PicoSDKCtypesError(PicoError, IOError): 57 | pass 58 | 59 | 60 | class ClosedDeviceError(PicoError, IOError): 61 | pass 62 | 63 | 64 | class NoChannelsEnabledError(PicoError, ValueError): 65 | pass 66 | 67 | 68 | class NoValidTimebaseForOptionsError(PicoError, ValueError): 69 | pass 70 | 71 | 72 | class UnknownConstantError(PicoError, TypeError): 73 | pass 74 | -------------------------------------------------------------------------------- /picosdk/functionsExhibitions.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | 5 | import numpy as np 6 | import openpyxl 7 | from math import floor, log2, log10 8 | import shutil 9 | import os 10 | import toml 11 | 12 | def dataImporter(name): 13 | 14 | workbook = openpyxl.load_workbook(name, data_only = True) 15 | 16 | sheet = workbook['filterParameters'] 17 | 18 | noOfChannels = sheet.cell(row = 2, column = 1).value 19 | bits = sheet.cell(row = 2, column = 2).value 20 | samplingRate = sheet.cell(row = 2, column = 3).value 21 | sampleLength = sheet.cell(row = 2, column = 4).value 22 | 23 | return noOfChannels, bits, samplingRate, sampleLength 24 | 25 | 26 | def ps6000aTimebase(samplingRate): 27 | 28 | sampleInterval = (1/samplingRate)/1000000 #s 29 | 30 | breakPoint = 6.4/1000000000 31 | 32 | if sampleInterval >= breakPoint: 33 | timebase = floor((sampleInterval * 156250000)+5) 34 | else: 35 | timebase = floor(log2(sampleInterval * 5000000000)) 36 | 37 | return timebase 38 | 39 | def ps5000aTimebase(samplingRate): 40 | 41 | sampleInterval = (1/samplingRate)/1000000 #s 42 | 43 | breakPoint = 8/1000000000 44 | 45 | if sampleInterval >= breakPoint: 46 | timebase = floor((sampleInterval * 125000000)+2) 47 | else: 48 | timebase = floor(log2(sampleInterval * 1000000000)) 49 | 50 | return timebase 51 | 52 | def ps3000aTimebase(samplingRate): 53 | 54 | sampleInterval = (1/samplingRate)/1000000 #s 55 | 56 | breakPoint = 8/1000000000 57 | 58 | if sampleInterval >= breakPoint: 59 | timebase = floor((sampleInterval * 125000000)+2) 60 | else: 61 | timebase = floor(log2(sampleInterval * 1000000000)) 62 | 63 | return timebase 64 | 65 | def ps4000aTimebase(samplingRate): 66 | 67 | timebase = floor((80/samplingRate)-1) 68 | 69 | return timebase 70 | 71 | def ps2000aTimebase(samplingRate): 72 | 73 | sampleInterval = (1/samplingRate)/1000000 #s 74 | 75 | breakPoint = 4/1000000000 76 | 77 | if sampleInterval>= breakPoint: 78 | timebase = floor((sampleInterval*125000000)+2) 79 | else: 80 | timebase = floor(log2(sampleInterval * 1000000000)) 81 | 82 | return timebase 83 | 84 | def ps2000Timebase(sampleRate): 85 | #assumes sample rate is in Hz 86 | #assumes sample interval in s 87 | 88 | sampleInterval = (1/sampleRate) 89 | 90 | timebase = floor(log10(sampleInterval*1000000000)) 91 | 92 | return timebase 93 | 94 | 95 | def BitEnumSelector(bits): 96 | 97 | if bits <= 8: 98 | enum = 0 99 | elif bits <= 10: 100 | enum = 10 101 | else: 102 | enum = 1 103 | 104 | return enum 105 | 106 | def saveConfigFile(channels, bits, sampleRate,captureLength, segments): 107 | 108 | # configValues = [channels, bits, sampleRate, captureLength, segments] 109 | data = { 110 | "Active Channels" : int(channels), 111 | "Scope Bit Resolution" : int(bits), 112 | "Sampling Rate (MHz)" : float(sampleRate), 113 | "Capture Length (Samples)" : int(captureLength), 114 | "Number of Capture Segments for Rapid Block" : int(segments), 115 | } 116 | # # Save the list to a text file 117 | with open('configValues.toml', 'w') as file: 118 | toml.dump(data,file) 119 | 120 | 121 | return 122 | 123 | def loadConfigValues(): 124 | 125 | with open('configValues.toml', 'r') as file: 126 | restored_configValues = toml.load(file) 127 | 128 | channels = int(restored_configValues["Active Channels"]) 129 | bits = int(restored_configValues["Scope Bit Resolution"]) 130 | sampleRate = float(restored_configValues["Sampling Rate (MHz)"]) 131 | captureLength = int(float(restored_configValues["Capture Length (Samples)"])) 132 | segments = int(restored_configValues["Number of Capture Segments for Rapid Block"]) 133 | 134 | return channels, bits, sampleRate, captureLength, segments 135 | 136 | def copyFile(source_directory, filename): 137 | 138 | destination_directory = 'D:/' 139 | 140 | # Define the destination file path 141 | source_file = os.path.join(source_directory, filename) 142 | destination_file = os.path.join(destination_directory, filename) 143 | 144 | # Copy the file to the new location 145 | shutil.copy(source_file, destination_file) 146 | 147 | return -------------------------------------------------------------------------------- /picosdk/picoMeasurements.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | 5 | import numpy as np 6 | -------------------------------------------------------------------------------- /picosdk/picohrdl.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | This is a Python module defining the functions from the picohrdl.h C header file 6 | for ADC-20/24 Data Loggers using the picohrdl driver API functions. 7 | """ 8 | 9 | from ctypes import * 10 | from picosdk.library import Library 11 | from picosdk.errors import ArgumentOutOfRangeError 12 | from picosdk.constants import make_enum 13 | 14 | class picohrdllib(Library): 15 | def __init__(self): 16 | super(picohrdllib, self).__init__("picohrdl") 17 | 18 | picohrdl = picohrdllib() 19 | 20 | picohrdl.HRDL_VOLTAGERANGE = make_enum([ 21 | "HRDL_2500_MV", 22 | "HRDL_1250_MV", 23 | "HRDL_625_MV", 24 | "HRDL_313_MV", 25 | "HRDL_156_MV", 26 | "HRDL_78_MV", 27 | "HRDL_39_MV", 28 | ]) 29 | 30 | picohrdl.HRDL_CONVERSIONTIME = make_enum([ 31 | "HRDL_60MS", 32 | "HRDL_100MS", 33 | "HRDL_180MS", 34 | "HRDL_340MS", 35 | "HRDL_660MS", 36 | ]) 37 | 38 | doc = """ int16_t HRDLCloseUnit 39 | ( 40 | int16_t handle 41 | ); """ 42 | picohrdl.make_symbol("_closeUnit_", "HRDLCloseUnit", c_int16, [c_int16], doc) 43 | 44 | doc = """ int16_t HRDLCollectSingleValueAsync 45 | ( 46 | int16_t handle, 47 | int16_t channel, 48 | int16_t range, 49 | int16_t conversionTime, 50 | int16_t singleEnded 51 | ); """ 52 | picohrdl.make_symbol("_collectSingleValue_Async_", "HRDLCollectSingleValueAsync", c_int16, [c_int16, c_int16, c_int16, c_int16, c_int16], doc) 53 | 54 | doc = """ int16_t HRDLGetMinMaxAdcCounts 55 | ( 56 | int16_t handle, 57 | int32_t *minAdc, 58 | int32_t *maxAdc, 59 | int16_t channel 60 | ); """ 61 | picohrdl.make_symbol("_getMinMaxAdcCounts_", "HRDLGetMinMaxAdcCounts", c_int16, [c_int16, c_void_p, c_void_p, c_int16], doc) 62 | 63 | doc = """ int16_t HRDLGetNumberOfEnabledChannels 64 | ( 65 | int16_t handle, 66 | int16_t *nEnabledChannels 67 | ); """ 68 | picohrdl.make_symbol("_getNumberOfEnabledChannels_", "HRDLGetNumberOfEnabledChannels", c_int16, [c_int16, c_void_p], doc) 69 | 70 | doc = """ int16_t HRDLGetSingleValue 71 | ( 72 | int16_t handle, 73 | int16_t channel, 74 | int16_t range, 75 | int16_t conversionTime, 76 | int16_t singleEnded, 77 | int16_t *overflow, 78 | int32_t *value 79 | ); """ 80 | picohrdl.make_symbol("_getSingleValue_", "HRDLGetSingleValue", c_int16, [c_int16, c_int16, c_int16, c_int16, c_int16, c_void_p, c_void_p], doc) 81 | 82 | doc = """ int16_t HRDLGetSingleValueAsync 83 | ( 84 | int16_t handle, 85 | int32_t *value, 86 | int16_t *overflow 87 | ); """ 88 | picohrdl.make_symbol("_getSingleValueAsync_", "HRDLGetSingleValueAsync", c_int16, [c_int16, c_void_p, c_void_p], doc) 89 | 90 | doc = """ int32_t HRDLGetTimesAndVAlues 91 | ( 92 | int16_t handle, 93 | int32_t *times, 94 | int32_t *values, 95 | int16_t *overflow, 96 | int32_t noOfValues 97 | ); """ 98 | picohrdl.make_symbol("_getTimesAndValues_", "HRDLGetTimesAndValues", c_int16, [c_int16, c_void_p, c_void_p, c_void_p, c_int32], doc) 99 | 100 | doc = """ int16_t HRDLGetUnitInfo 101 | ( 102 | int16_t handle, 103 | int8_t *string, 104 | int16_t stringLength, 105 | int16_t info 106 | ); """ 107 | picohrdl.make_symbol("_getUnitInfo_", "HRDLGetUnitInfo", c_int16, [c_int16, c_void_p, c_int16, c_int16], doc) 108 | 109 | doc = """ int32_t HRDLGetValues 110 | ( 111 | int16_t handle, 112 | int32_t *values, 113 | int16_t *overflow, 114 | int32_t noOfValues 115 | ); """ 116 | picohrdl.make_symbol("_getValues_", "HRDLGetValues", c_int16, [c_int16, c_void_p, c_void_p, c_int32], doc) 117 | 118 | doc = """ int16_t HRDLOpenUnit 119 | ( 120 | void 121 | ); """ 122 | picohrdl.make_symbol("_openUnit_", "HRDLOpenUnit", c_int16, [], doc) 123 | 124 | doc = """ int16_t HRDLOpenUnitAsync 125 | ( 126 | void 127 | ); """ 128 | picohrdl.make_symbol("_openUnitAsync_", "HRDLOpenUnitAsync", c_int16, [], doc) 129 | 130 | doc = """ int16_t HRDLOpenUnitProgress 131 | ( 132 | int16_t *handle, 133 | int16_t *progress 134 | ); """ 135 | picohrdl.make_symbol("_openUnitProgress_", "HRDLOpenUnitProgress", c_int16, [c_void_p, c_void_p], doc) 136 | 137 | doc = """ int16_t HRDLReady 138 | ( 139 | int16_t handle 140 | ); """ 141 | picohrdl.make_symbol("_ready_", "HRDLReady", c_int16, [c_int16], doc) 142 | 143 | doc = """ int16_t HRDLRun 144 | ( 145 | int16_t handle, 146 | int32_t nValues, 147 | int16_t method 148 | ); """ 149 | picohrdl.make_symbol("_run_", "HRDLRun", c_int16, [c_int16, c_int32, c_int16], doc) 150 | 151 | doc = """ int16_t HRDLSetAnalogInChannel 152 | ( 153 | int16_t handle, 154 | int16_t channel, 155 | int16_t enabled, 156 | int16_t range, 157 | int16_t singleEnded 158 | ); """ 159 | picohrdl.make_symbol("_setAnalogInChannel_", "HRDLSetAnalogInChannel", c_int16, [c_int16, c_int16, c_int16, c_int16, c_int16], doc) 160 | 161 | doc = """ int16_t HRDLSetDigitalIOChannel 162 | ( 163 | int16_t handle, 164 | int16_t directionOut, 165 | int16_t digitalOutPinState, 166 | int16_t enabledDigitalIn 167 | ); """ 168 | picohrdl.make_symbol("_setDigitalIOChannel_", "HRDLSetDigitalIOChannel", c_int16, [c_int16, c_int16, c_int16, c_int16], doc) 169 | 170 | doc = """ int16_t HRDLSetInterval 171 | ( 172 | int16_t handle, 173 | int32_t samplesInterval_ms, 174 | int16_t conversionTime 175 | ); """ 176 | picohrdl.make_symbol("_setInterval_", "HRDLSetInterval", c_int16, [c_int16, c_int32, c_int16], doc) 177 | 178 | doc = """ int16_t HRDLSetMains 179 | ( 180 | int16_t handle, 181 | int16_t sixtyHertz 182 | ); """ 183 | picohrdl.make_symbol("_setMains_", "HRDLSetMains", c_int16, [c_int16, c_int16], doc) 184 | 185 | doc = """ void HRDLStop 186 | ( 187 | int16_t handle 188 | ); """ 189 | picohrdl.make_symbol("_stop_", "HRDLStop", c_int16, [c_int16], doc) -------------------------------------------------------------------------------- /picosdk/pl1000.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | This is a Python module defining the functions from the pl1000.h C header 6 | file for PicoLog 1000 Series datalogger using the pl1000 driver API functions. 7 | """ 8 | 9 | from ctypes import * 10 | from picosdk.ctypes_wrapper import C_CALLBACK_FUNCTION_FACTORY 11 | from picosdk.library import Library 12 | from picosdk.constants import make_enum 13 | 14 | class Pl1000lib(Library): 15 | def __init__(self): 16 | super(Pl1000lib, self).__init__("pl1000") 17 | 18 | pl1000 = Pl1000lib() 19 | 20 | def _pl1000Inputs(): 21 | PL1000_CHANNEL_1 = 1 22 | PL1000_CHANNEL_2 = 2 23 | PL1000_CHANNEL_3 = 3 24 | PL1000_CHANNEL_4 = 4 25 | PL1000_CHANNEL_5 = 5 26 | PL1000_CHANNEL_6 = 6 27 | PL1000_CHANNEL_7 = 7 28 | PL1000_CHANNEL_8 = 8 29 | PL1000_CHANNEL_9 = 9 30 | PL1000_CHANNEL_10 = 10 31 | PL1000_CHANNEL_11 = 11 32 | PL1000_CHANNEL_12 = 12 33 | PL1000_CHANNEL_13 = 13 34 | PL1000_CHANNEL_14 = 14 35 | PL1000_CHANNEL_15 = 15 36 | PL1000_CHANNEL_16 = 16 37 | PL1000_MAX_CHANNEL = PL1000_CHANNEL_16 38 | 39 | return {k.upper(): v for k, v in locals().items() if k.startswith("PL1000")} 40 | 41 | pl1000.PL1000Inputs = _pl1000Inputs() 42 | 43 | pl1000.PL1000DO_Channel = make_enum([ 44 | 'PL1000_DO_CHANNEL_0', 45 | 'PL1000_DO_CHANNEL_1', 46 | 'PL1000_DO_CHANNEL_2', 47 | 'PL1000_DO_CHANNEL_3', 48 | 'PL1000_DO_CHANNEL_MAX', 49 | ]) 50 | 51 | pl1000.PL1000OpenProgress = { 52 | 'PL1000_OPEN_PROGRESS_FAIL' : -1, 53 | 'PL1000_OPEN_PROGRESS_PENDING': 0, 54 | 'PL1000_OPEN_PROGRESS_COMPLETE' : 1, 55 | } 56 | 57 | pl1000.PL1000_BLOCK_METHOD = make_enum([ 58 | "BM_SINGLE", 59 | "BM_WINDOW", 60 | "BM_STREAM", 61 | ]) 62 | 63 | doc = """ PICO_STATUS pl1000CloseUnit 64 | ( 65 | int16_t handle 66 | ); """ 67 | pl1000.make_symbol("_CloseUnit_", "pl1000CloseUnit", c_uint32, [c_int16], doc) 68 | 69 | doc = """ PICO_STATUS pl1000GetSingle 70 | ( 71 | int16_t handle, 72 | PL1000_INPUTS channel, 73 | unit16_t *value 74 | ); """ 75 | pl1000.make_symbol("_GetSingle_", "pl1000GetSingle", c_uint32, [c_int16, c_int32, c_void_p], doc) 76 | 77 | doc = """ PICO_STATUS pl1000GetUnitInfo 78 | ( 79 | int16_t handle, 80 | int8_t *string, 81 | int16_t stringLength, 82 | int16_t *requiredSize, 83 | PICO_INFO info 84 | ); """ 85 | pl1000.make_symbol("_GetUnitInfo_", "pl1000GetUnitInfo", c_uint32, [c_int16, c_void_p, c_int16, c_void_p, c_int32], doc) 86 | 87 | doc = """ PICO_STATUS pl1000GetValues 88 | ( 89 | int16_t handle, 90 | uint16_t *values, 91 | uint32_t *noOfValues, 92 | unit16_t *overflow, 93 | uint32_t *triggerIndex 94 | ); """ 95 | pl1000.make_symbol("_GetValues_", "pl1000GetValues", c_uint32, [c_int16, c_void_p, c_void_p, c_void_p, c_void_p], doc) 96 | 97 | doc = """ PICO_STATUS pl1000MaxValue 98 | ( 99 | int16_t handle, 100 | uint16_t *maxValue 101 | ); """ 102 | pl1000.make_symbol("_MaxValue_", "pl1000MaxValue", c_uint32, [c_int16, c_void_p], doc) 103 | 104 | doc = """ PICO_STATUS pl1000OpenUnit 105 | ( 106 | int16_t *handle 107 | ); """ 108 | pl1000.make_symbol("_OpenUnit_", "pl1000OpenUnit", c_uint32, [c_void_p], doc) 109 | 110 | doc = """ PICO_STATUS pl1000OpenUnitAsync 111 | ( 112 | int16_t *status 113 | ); """ 114 | pl1000.make_symbol("_OpenUnitAsync_", "pl1000OpenUnitAsync", c_uint32, [c_void_p], doc) 115 | 116 | doc = """ PICO_STATUS pl1000OpenUnitProgress 117 | ( 118 | int16_t *handle, 119 | int16_t *progress, 120 | int16_t *complete 121 | ); """ 122 | pl1000.make_symbol("_OpenUnitProgress_", "pl1000OpenUnitProgress", c_uint32, [c_void_p, c_void_p, c_void_p], doc) 123 | 124 | doc = """ PICO_STATUS pl1000PingUnit 125 | ( 126 | int16_t handle 127 | ); """ 128 | pl1000.make_symbol("_PingUnit_", "pl1000PingUnit", c_uint32, [c_int16], doc) 129 | 130 | doc = """ PICO_STATUS pl1000Ready 131 | ( 132 | int16_t handle, 133 | int16_t *ready 134 | ); """ 135 | pl1000.make_symbol("_Ready_", "pl1000Ready", c_uint32, [c_int16, c_void_p], doc) 136 | 137 | doc = """ PICO_STATUS pl1000Run 138 | ( 139 | int16_t handle, 140 | uint32_t no_of_values, 141 | BLOCK_METHOD method 142 | ); """ 143 | pl1000.make_symbol("_Run_", "pl1000Run", c_uint32, [c_int16, c_uint32, c_int32], doc) 144 | 145 | doc = """ PICO_STATUS pl1000SetDo 146 | ( 147 | int16_t handle, 148 | int16_t do_value, 149 | int16_t doNo 150 | ); """ 151 | pl1000.make_symbol("_SetDo_", "pl1000SetDo", c_uint32, [c_int16, c_int16, c_int16], doc) 152 | 153 | doc = """ PICO_STATUS pl1000SetInterval 154 | ( 155 | int16_t handle, 156 | uint32_t *us_for_block, 157 | uint32_t ideal_no_of_samples, 158 | int16_t *channels, 159 | int16_t no_of_channels 160 | ); """ 161 | pl1000.make_symbol("_SetInterval_", "pl1000SetInterval", c_uint32, [c_int16, c_void_p, c_uint32, c_void_p, c_int16], doc) 162 | 163 | doc = """ PICO_STATUS pl1000SetPulseWidth 164 | ( 165 | int16_t handle, 166 | uint16_t period, 167 | uint8_t cycle 168 | ); """ 169 | pl1000.make_symbol("_SetPulseWidth_", "pl1000SetPulseWidth", c_uint32, [c_int16, c_int16, c_int8], doc) 170 | 171 | doc = """ PICO_STATUS pl1000SetTrigger 172 | ( 173 | int16_t handle, 174 | uint16_t enabled, 175 | uint16_t auto_trigger, 176 | uint16_t auto_ms, 177 | uint16_t channel, 178 | uint16_t dir, 179 | uint16_t threshold, 180 | uint16_t hysteresis, 181 | float delay 182 | ); """ 183 | pl1000.make_symbol("_SetTrigger_", "pl1000SetTrigger", c_uint32, [c_int16, c_uint16, c_uint16, c_uint16, c_uint16, c_uint16, c_uint16, c_uint16, c_float], doc) 184 | 185 | doc = """ PICO_STATUS pl1000Stop 186 | ( 187 | int16_t handle 188 | ); """ 189 | pl1000.make_symbol("_Stop_", "pl1000Stop", c_uint32, [c_int16], doc) 190 | 191 | -------------------------------------------------------------------------------- /picosdk/psospaBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PSOSPA BLOCK MODE EXAMPLE 5 | # This example opens a psospa driver device, sets up two channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.psospa import psospa as ps 11 | from picosdk.PicoDeviceEnums import picoEnum as enums 12 | from picosdk.PicoDeviceStructs import picoStruct as structs 13 | # from picosdk.PicoConnectProbes import picoConnectProbes as probes 14 | import matplotlib.pyplot as plt 15 | from picosdk.functions import adc2mVV2, mV2adcV2, assert_pico_ok 16 | 17 | # Create chandle and status ready for use 18 | chandle = ctypes.c_int16() 19 | status = {} 20 | 21 | # Open a psospa driver device 22 | # returns handle for future API functions 23 | resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"] 24 | status["openUnit"] = ps.psospaOpenUnit(ctypes.byref(chandle), None, resolution, None) 25 | assert_pico_ok(status["openUnit"]) 26 | 27 | # Set channel A on 28 | # handle = chandle 29 | channelA = enums.PICO_CHANNEL["PICO_CHANNEL_A"] 30 | coupling = enums.PICO_COUPLING["PICO_DC"] 31 | rangeMax = 2000000000 #nV 32 | rangeMin = -rangeMax #nV 33 | rangeType = 0 #probes.PICO_PROBE_RANGE_INFO["PICO_PROBE_NONE_NV"] 34 | analogueOffset = 0 35 | bandwidth = enums.PICO_BANDWIDTH_LIMITER["PICO_BW_FULL"] 36 | status["setChannelA"] = ps.psospaSetChannelOn(chandle, channelA, coupling, rangeMin, rangeMax, rangeType, analogueOffset, bandwidth) 37 | assert_pico_ok(status["setChannelA"]) 38 | 39 | # set channel B-D off 40 | for x in range (1, 3, 1): 41 | channel = x 42 | status["setChannel",x] = ps.psospaSetChannelOff(chandle,channel) 43 | assert_pico_ok(status["setChannel",x]) 44 | 45 | # get max ADC value 46 | # handle = chandle 47 | minADC = ctypes.c_int16() 48 | maxADC = ctypes.c_int16() 49 | status["getAdcLimits"] = ps.psospaGetAdcLimits(chandle, resolution, ctypes.byref(minADC), ctypes.byref(maxADC)) 50 | assert_pico_ok(status["getAdcLimits"]) 51 | 52 | # Set simple trigger on channel A, 1 V rising with 1 s autotrigger 53 | # handle = chandle 54 | # enable = 1 55 | source = channelA 56 | # threshold = 100 mV 57 | direction = enums.PICO_THRESHOLD_DIRECTION["PICO_RISING"] 58 | # delay = 0 s 59 | # autoTriggerMicroSeconds = 1000000 us 60 | status["setSimpleTrigger"] = ps.psospaSetSimpleTrigger(chandle, 1, source, mV2adcV2(100,rangeMax,maxADC), direction, 0, 1000000) 61 | assert_pico_ok(status["setSimpleTrigger"]) 62 | 63 | # Get fastest available timebase 64 | # handle = chandle 65 | enabledChannelFlags = enums.PICO_CHANNEL_FLAGS["PICO_CHANNEL_A_FLAGS"] 66 | timebase = ctypes.c_uint32(0) 67 | timeInterval = ctypes.c_double(0) 68 | # resolution = resolution 69 | status["getMinimumTimebaseStateless"] = ps.psospaGetMinimumTimebaseStateless(chandle, enabledChannelFlags, ctypes.byref(timebase), ctypes.byref(timeInterval), resolution) 70 | print("timebase = ", timebase.value) 71 | print("sample interval =", timeInterval.value, "s") 72 | 73 | # Set number of samples to be collected 74 | noOfPreTriggerSamples = 500000 75 | noOfPostTriggerSamples = 1000000 76 | nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples 77 | 78 | # Create buffers 79 | bufferAMax = (ctypes.c_int16 * nSamples)() 80 | bufferAMin = (ctypes.c_int16 * nSamples)() # used for downsampling which isn't in the scope of this example 81 | 82 | # Set data buffers 83 | # handle = chandle 84 | # channel = channelA 85 | # bufferMax = bufferAMax 86 | # bufferMin = bufferAMin 87 | # nSamples = nSamples 88 | dataType = enums.PICO_DATA_TYPE["PICO_INT16_T"] 89 | waveform = 0 90 | downSampleMode = enums.PICO_RATIO_MODE["PICO_RATIO_MODE_RAW"] 91 | clear = enums.PICO_ACTION["PICO_CLEAR_ALL"] 92 | add = enums.PICO_ACTION["PICO_ADD"] 93 | action = clear|add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"] 94 | status["setDataBuffers"] = ps.psospaSetDataBuffers(chandle, channelA, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), nSamples, dataType, waveform, downSampleMode, action) 95 | assert_pico_ok(status["setDataBuffers"]) 96 | 97 | # Run block capture 98 | # handle = chandle 99 | # timebase = timebase 100 | timeIndisposedMs = ctypes.c_double(0) 101 | # segmentIndex = 0 102 | # lpReady = None Using IsReady rather than a callback 103 | # pParameter = None 104 | status["runBlock"] = ps.psospaRunBlock(chandle, noOfPreTriggerSamples, noOfPostTriggerSamples, timebase, ctypes.byref(timeIndisposedMs), 0, None, None) 105 | assert_pico_ok(status["runBlock"]) 106 | 107 | # Check for data collection to finish using psospaIsReady 108 | ready = ctypes.c_int16(0) 109 | check = ctypes.c_int16(0) 110 | while ready.value == check.value: 111 | status["isReady"] = ps.psospaIsReady(chandle, ctypes.byref(ready)) 112 | 113 | # Get data from scope 114 | # handle = chandle 115 | # startIndex = 0 116 | noOfSamples = ctypes.c_uint64(nSamples) 117 | # downSampleRatio = 1 118 | # segmentIndex = 0 119 | overflow = ctypes.c_int16(0) 120 | status["getValues"] = ps.psospaGetValues(chandle, 0, ctypes.byref(noOfSamples), 1, downSampleMode, 0, ctypes.byref(overflow)) 121 | assert_pico_ok(status["getValues"]) 122 | 123 | 124 | 125 | # # convert ADC counts data to mV 126 | adc2mVChAMax = adc2mVV2(bufferAMax, rangeMax, maxADC) 127 | 128 | # Create time data 129 | time = np.linspace(0, (nSamples -1) * timeInterval.value * 1000000000, nSamples) 130 | 131 | # plot data from channel A and B 132 | plt.plot(time, bufferAMax[:]) 133 | plt.xlabel('Time (ns)') 134 | plt.ylabel('Voltage (mV)') 135 | plt.show() 136 | 137 | # Close the psospa driver device 138 | status["closeUnit"] = ps.psospaCloseUnit(chandle) 139 | assert_pico_ok(status["closeUnit"]) 140 | 141 | print(status) -------------------------------------------------------------------------------- /picosdk/usbPT104.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | This is a Python module defining the functions from the usbPT104Api.h C header 6 | file for Pico USB PT-104 datalogger using the usb PT104 driver API functions. 7 | """ 8 | 9 | from ctypes import * 10 | from picosdk.library import Library 11 | from picosdk.ctypes_wrapper import C_CALLBACK_FUNCTION_FACTORY 12 | from picosdk.constants import make_enum 13 | 14 | class usbpt104lib(Library): 15 | def __init__(self): 16 | super(usbpt104lib, self).__init__("usbpt104") 17 | 18 | 19 | usbPt104 = usbpt104lib() 20 | 21 | usbPt104.PT104_CHANNELS = { 22 | 'USBPT104_CHANNEL_1' : 1, 23 | 'USBPT104_CHANNEL_2' : 2, 24 | 'USBPT104_CHANNEL_3' : 3, 25 | 'USBPT104_CHANNEL_4' : 4, 26 | 'USBPT104_CHANNEL_5' : 5, 27 | 'USBPT104_CHANNEL_6' : 6, 28 | 'USBPT104_CHANNEL_7' : 7, 29 | 'USBPT104_CHANNEL_8' : 8, 30 | 'USBPT104_MAX_CHANNELS' : 8 31 | } 32 | 33 | usbPt104.PT104_DATA_TYPE = make_enum([ 34 | 'USBPT104_OFF', 35 | 'USBPT104_PT100', 36 | 'USBPT104_PT1000', 37 | 'USBPT104_RESISTANCE_TO_375R', 38 | 'USBPT104_RESISTANCE_TO_10K', 39 | 'USBPT104_DIFFERENTIAL_TO_115MV', 40 | 'USBPT104_DIFFERENTIAL_TO_2500MV', 41 | 'USBPT104_SINGLE_ENDED_TO_115MV', 42 | 'USBPT104_SINGLE_ENDED_TO_2500MV', 43 | 'USBPT104_MAX_DATA_TYPES' 44 | ]) 45 | 46 | usbPt104.IP_DETAILS_TYPE = make_enum([ 47 | 'IDT_GET' 48 | 'IDT_SET' 49 | ]) 50 | 51 | def _define_communication_type(): 52 | CT_USB = 0x00000001 53 | CT_ETHERNET = 0x00000002 54 | CT_ALL = 0xFFFFFFFF 55 | 56 | return {k.upper(): v for k, v in locals().items() if k.startswith("CT")} 57 | 58 | usbPt104.COMMUNICATION_TYPE = _define_communication_type() 59 | 60 | doc = """ PICO_STATUS UsbPt104CloseUnit 61 | ( 62 | int16_t handle 63 | ); """ 64 | usbPt104.make_symbol("_CloseUnit", "UsbPt104CloseUnit", c_uint32, [c_int16], doc) 65 | 66 | doc = """ PICO_STATUS UsbPt104Enumerate 67 | ( 68 | int8_t *details, 69 | uint32_t *length, 70 | COMMUNICATION_TYPE type 71 | ); """ 72 | usbPt104.make_symbol("_Enumerate", "UsbPt104Enumerate", c_uint32, [c_void_p, c_void_p, c_uint32], doc) 73 | 74 | doc = """ PICO_STATUS UsbPt104GetUnitInfo 75 | ( 76 | int16_t handle, 77 | int8_t *string, 78 | int16_t stringLength, 79 | int16_t *requiredSize, 80 | PICO_INFO info 81 | ); """ 82 | usbPt104.make_symbol("_GetUnitInfo", "UsbPt104GetUnitInfo", c_uint32, [c_int16, c_void_p, c_int16, c_void_p, c_uint32], doc) 83 | 84 | doc = """ PICO_STATUS UsbPt104GetValue 85 | ( 86 | int16_t handle, 87 | USBPT104_CHANNELS channel, 88 | int32_t *value, 89 | int16_t filtered 90 | ); """ 91 | usbPt104.make_symbol("_GetValue", "UsbPt104GetValue", c_uint32, [c_int16, c_uint32, c_void_p, c_int16], doc) 92 | 93 | doc = """ PICO_STATUS UsbPt104IpDetails 94 | ( 95 | int16_t handle, 96 | int16_t *enabled, 97 | int8_t *ipaddress, 98 | uint16_t *length, 99 | uint16_t *listeningPort, 100 | IP_DETAILS_TYPE type 101 | ); """ 102 | usbPt104.make_symbol("_IpDetails", "UsbPt104IpDetails", c_uint32, [c_int16, c_void_p, c_void_p, c_void_p, c_void_p, c_uint32], doc) 103 | 104 | doc = """ PICO_STATUS UsbPt104OpenUnit 105 | ( 106 | int16_t *handle, 107 | int8_t *serial 108 | ); """ 109 | usbPt104.make_symbol("_OpenUnit", "UsbPt104OpenUnit", c_uint32, [c_void_p, c_void_p], doc) 110 | 111 | doc = """ PICO_STATUS UsbPt104OpenUnitViaIp 112 | ( 113 | int16_t *handle, 114 | int8_t *serial, 115 | int8_t *ipAddress 116 | ); """ 117 | usbPt104.make_symbol("_OpenUnitViaIp", "UsbPt104OpenUnitViaIp", c_uint32, [c_void_p, c_void_p, c_void_p], doc) 118 | 119 | doc = """ PICO_STATUS UsbPt104SetChannel 120 | ( 121 | int16_t handle, 122 | USBPT104_CHANNELS channel, 123 | USBPT104_DATA_TYPES type, 124 | int16_t noOfWires 125 | ); """ 126 | usbPt104.make_symbol("_SetChannel", "UsbPt104SetChannel", c_uint32, [c_int16, c_uint32, c_uint32, c_int16], doc) 127 | 128 | doc = """ PICO_STATUS UsbPt104SetMains 129 | ( 130 | int16_t handle, 131 | uint16_t sixty_hertz 132 | ); """ 133 | usbPt104.make_symbol("_SetMains", "UsbPt104SetMains", c_uint32, [c_int16, c_uint16], doc) 134 | -------------------------------------------------------------------------------- /picosdk/usbtc08.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | This is a Python module defining the functions from the usbtc08.h C header file 6 | for TC-08 Thermocouple Data Logger using the usbtc08 driver API functions. 7 | """ 8 | 9 | from ctypes import * 10 | from picosdk.library import Library 11 | from picosdk.errors import ArgumentOutOfRangeError 12 | from picosdk.constants import make_enum 13 | 14 | class usbtc08lib(Library): 15 | def __init__(self): 16 | super(usbtc08lib, self).__init__("usbtc08") 17 | 18 | 19 | usbtc08 = usbtc08lib() 20 | 21 | usbtc08.USBTC08_UNITS = make_enum([ 22 | "USBTC08_UNITS_CENTIGRADE", 23 | "USBTC08_UNITS_FAHRENHEIT", 24 | "USBTC08_UNITS_KELVIN", 25 | "USBTC08_UNITS_RANKINE", 26 | ]) 27 | 28 | class USBTC08_INFO(Structure): 29 | _pack_ = 1 30 | _fields_ = [("size", c_int16), 31 | ("DriverVersion", c_char * 12), 32 | ("PicoppVersion", c_int16), 33 | ("HardwareVersion", c_int16), 34 | ("Variant", c_int16), 35 | ("szSerial[USBTC08_MAX_SERIAL_CHAR]", c_char * 11), 36 | ("szCalDate[USBTC08_MAX_DATE_CHARS]", c_char * 9)] 37 | 38 | doc = """ int16_t usb_tc08_open_unit 39 | ( 40 | void 41 | ); """ 42 | usbtc08.make_symbol("_open_unit_","usb_tc08_open_unit", c_int16, [], doc) 43 | 44 | doc = """ int16_t usb_tc08_open_unit_async 45 | ( 46 | void 47 | ); """ 48 | usbtc08.make_symbol("_open_unit_async_","usb_tc08_open_unit_async", c_int16, [], doc) 49 | 50 | doc = """ int16_t usb_tc08_open_unit_progress 51 | ( 52 | int16_t *handle, 53 | int16_t *progress 54 | ); """ 55 | usbtc08.make_symbol("_open_unit_progress_","usb_tc08_open_unit_progress", c_int16, [c_void_p, c_void_p], doc) 56 | 57 | doc = """ int16_t usb_tc08_close_unit 58 | ( 59 | int16_t handle 60 | ); """ 61 | usbtc08.make_symbol("_close_unit_","usb_tc08_close_unit", c_int16, [c_int16], doc) 62 | 63 | doc = """ int16_t usb_tc08_stop 64 | ( 65 | int16_t handle 66 | ); """ 67 | usbtc08.make_symbol("_stop_","usb_tc08_stop", c_int16, [c_int16], doc) 68 | 69 | doc = """ int16 usb_tc08_set_mains 70 | ( 71 | int16_t handle, 72 | int16_t sixty_hertz 73 | ); """ 74 | usbtc08.make_symbol("_set_mains_","usb_tc08_set_mains", c_int16, [c_int16, c_int16], doc) 75 | 76 | doc = """ int32_t usb_tc08_get_minimum_interval_ms 77 | ( 78 | int16_t handle 79 | ); """ 80 | usbtc08.make_symbol("_get_minimum_interval_ms_","usb_tc08_get_minimum_interval_ms", c_int16, [c_int16], doc) 81 | 82 | doc = """ int16_t usb_tc08_get_unit_info 83 | ( 84 | int16_t handle 85 | USBTC08_INFO *info 86 | ); """ 87 | usbtc08.make_symbol("_get_unit_info_","usb_tc08_get_unit_info", c_int16, [c_int16, c_void_p], doc) 88 | 89 | doc = """ int16_t usb_tc08_get_unit_info2 90 | ( 91 | int16_t handle, 92 | int8_t *string, 93 | int16_t string_length, 94 | int16_t line 95 | ); """ 96 | usbtc08.make_symbol("_get_unit_info2_","usb_tc08_get_unit_info2", c_int16, [c_int16, c_void_p, c_int16, c_int16], doc) 97 | 98 | doc = """ int16_t usb_tc08_get_formatted_info 99 | ( 100 | int16_t handle, 101 | int8_t *unit_info, 102 | int16_t string_length 103 | ); """ 104 | usbtc08.make_symbol("_get_formatted_info_","usb_tc08_get_formatted_info", c_int16, [c_int16, c_void_p, c_int16], doc) 105 | 106 | doc = """ int16_t usb_tc08_get_last_error 107 | ( 108 | int16_t handle 109 | ); """ 110 | usbtc08.make_symbol("_get_last_error_","usb_tc08_get_last_error", c_int16, [c_int16], doc) 111 | 112 | doc = """ int16_t usb_tc08_set_channel 113 | ( 114 | int16_t handle, 115 | int16_t channel, 116 | int8_t tc_type 117 | ); """ 118 | usbtc08.make_symbol("_set_channel_","usb_tc08_set_channel", c_int16, [c_int16, c_int16, c_int8], doc) 119 | 120 | doc = """ int32_t usb_tc08_run 121 | ( 122 | int16_t handle, 123 | int32_t interval 124 | ); """ 125 | usbtc08.make_symbol("_run_","usb_tc08_run", c_int16, [c_int16, c_int32], doc) 126 | 127 | doc = """ int16_t usb_tc08_get_single 128 | ( 129 | int16_t handle, 130 | float *temp, 131 | int16_t *overflow_flags, 132 | int16_t units 133 | ); """ 134 | usbtc08.make_symbol("_get_single_","usb_tc08_get_single", c_int16, [c_int16, c_void_p, c_void_p, c_int16], doc) 135 | 136 | doc = """ int32_t usb_tc08_get_temp 137 | ( 138 | int16_t handle, 139 | float *temp_buffer, 140 | int32_t *times_ms_buffer, 141 | int32_t buffer_length, 142 | int16_t *overflow, 143 | int16_t channel, 144 | int16_t units, 145 | int16_t fill_missing 146 | ); """ 147 | usbtc08.make_symbol("_get_temp_","usb_tc08_get_temp", c_int16, [c_int16, c_void_p, c_void_p, c_int32, c_void_p, c_void_p, c_int16, c_int16], doc) 148 | 149 | doc = """ int32_t usb_tc08_get_temp_deskew 150 | ( 151 | int16_t handle, 152 | float *temp_buffer, 153 | int32_t *times, 154 | int32_t buffer_length, 155 | int16_t *overflow, 156 | int16_t channel, 157 | int16_t units, 158 | int16_t fill_missing 159 | ); """ 160 | usbtc08.make_symbol("_get_temp_deskew_","usb_tc08_get_temp_deskew", c_int16, [c_int16, c_void_p, c_void_p, c_int32, c_void_p, c_int16, c_int16, c_int16], doc) -------------------------------------------------------------------------------- /picosynthExamples/picosynthFrequencySweepExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PicoSource AS108 Agile Synthesizer Example 5 | # This example demonstrates how to use the PicoSource AS108 picosynth driver API functions to set up the signal generator to output a frequency sweep. 6 | # 7 | 8 | import ctypes 9 | from picosdk.picosynth import picosynth as ps 10 | import time 11 | from picosdk.functions import assert_pico_ok 12 | 13 | # setup needed variables 14 | status = {} 15 | chandle = ctypes.c_uint32() 16 | 17 | # open AS108 device 18 | status["openunit"] = ps.picosynthOpenUnit(ps.PICO_SOURCE_MODEL["PICO_SYNTH"], ctypes.byref(chandle),0) 19 | assert_pico_ok(status["openunit"]) 20 | 21 | # set up a frequency sweep 22 | # handle = chandle 23 | startFreqHz = 300000 #Hz 24 | stopFreqHz = 1000000 #Hz 25 | startLevel = 2 26 | stopLevel = 2 27 | levelUnit = 1 # VoltsPkToPk 28 | dwellTimeUs = 100 29 | pointsInSweep = 1000 30 | mode = 0 #SweepAndFlyback 31 | triggerMode = 0 # InternalTrigger 32 | 33 | status["setFrequencyAndLevelSweep"] = ps.picosynthSetFrequencyAndLevelSweep(chandle,startFreqHz,stopFreqHz,startLevel,stopLevel,levelUnit,dwellTimeUs,pointsInSweep,mode,triggerMode) 34 | assert_pico_ok(status["setFrequencyAndLevelSweep"]) 35 | 36 | time.sleep(10) 37 | 38 | # close AS108 device 39 | status["closeunit"] = ps.picosynthCloseUnit(chandle) 40 | assert_pico_ok(status["closeunit"]) 41 | 42 | time.sleep(20) 43 | 44 | # open AS108 device 45 | status["openunit"] = ps.picosynthOpenUnit(ps.PICO_SOURCE_MODEL["PICO_SYNTH"], ctypes.byref(chandle),0) 46 | assert_pico_ok(status["openunit"]) 47 | 48 | # set output off 49 | status["setOutputOff"] = ps.picosynthSetOutputOff(chandle) 50 | 51 | # close AS108 device 52 | status["closeunit"] = ps.picosynthCloseUnit(chandle) 53 | assert_pico_ok(status["closeunit"]) 54 | 55 | # Displays the status returns 56 | print(status) -------------------------------------------------------------------------------- /pl1000Examples/pl1000SingleModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PL1000 SINGLE MODE EXAMPLE 5 | # This example opens a pl1000 device, sets up the device for capturing data from channel 1. 6 | # Then this example collect a sample from channel 1 and displays it on the console. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.pl1000 import pl1000 as pl 11 | import matplotlib.pyplot as plt 12 | from picosdk.functions import adc2mV, assert_pico_ok 13 | 14 | # Create chandle and status ready for use 15 | chandle = ctypes.c_int16() 16 | status = {} 17 | 18 | # open PicoLog 1000 device 19 | status["openUnit"] = pl.pl1000OpenUnit(ctypes.byref(chandle)) 20 | assert_pico_ok(status["openUnit"]) 21 | 22 | value = ctypes.c_int16() 23 | # get a single ADC count value from channel 1 24 | status["getSingle"] = pl.pl1000GetSingle(chandle, pl.PL1000Inputs["PL1000_CHANNEL_1"], ctypes.byref(value)) 25 | assert_pico_ok(status["getSingle"]) 26 | print(value.value) 27 | 28 | # close PicoLog 1000 device 29 | status["closeUnit"] = pl.pl1000CloseUnit(chandle) 30 | assert_pico_ok(status["closeUnit"]) 31 | 32 | # display status returns 33 | print(status) 34 | -------------------------------------------------------------------------------- /pl1000Examples/pl1000StreamingModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PL1000 STREAMING MODE EXAMPLE 5 | # This example opens a PicoLog 1000 device, configures streaming mode to capture data from channel 1 at 6 | # a sampling rate of 100 kS/s for 10 seconds, retrieves the data, and displays it on a plot. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.pl1000 import pl1000 as pl 11 | import matplotlib.pyplot as plt 12 | from picosdk.functions import adc2mVpl1000, assert_pico_ok 13 | from time import sleep 14 | 15 | # Create chandle and status ready for use 16 | chandle = ctypes.c_int16() 17 | status = {} 18 | 19 | # open PicoLog 1000 device 20 | status["openUnit"] = pl.pl1000OpenUnit(ctypes.byref(chandle)) 21 | assert_pico_ok(status["openUnit"]) 22 | 23 | # set sampling interval 24 | usForBlock = ctypes.c_uint32(10000000) 25 | noOfValues = ctypes.c_uint32(1000000) 26 | channels = ctypes.c_int16(1) 27 | 28 | status["setInterval"] = pl.pl1000SetInterval(chandle, ctypes.byref(usForBlock), noOfValues, ctypes.byref(channels), 1) 29 | assert_pico_ok(status["setInterval"]) 30 | 31 | # start streaming 32 | mode = pl.PL1000_BLOCK_METHOD["BM_STREAM"] 33 | status["run"] = pl.pl1000Run(chandle, 1000000, mode) 34 | assert_pico_ok(status["run"]) 35 | 36 | sleep(usForBlock.value / 1000000) 37 | 38 | values = (ctypes.c_uint16 * noOfValues.value)() 39 | oveflow = ctypes.c_uint16() 40 | 41 | status["getValues"] = pl.pl1000GetValues(chandle, ctypes.byref(values), ctypes.byref(noOfValues), ctypes.byref(oveflow), None) 42 | assert_pico_ok(status["getValues"]) 43 | 44 | # convert ADC counts data to mV 45 | maxADC = ctypes.c_uint16() 46 | status["maxValue"] = pl.pl1000MaxValue(chandle, ctypes.byref(maxADC)) 47 | assert_pico_ok(status["maxValue"]) 48 | inputRange = 2500 49 | mVValues = adc2mVpl1000(values, inputRange, maxADC) 50 | 51 | # create time data 52 | interval = (0.001 * usForBlock.value)/(noOfValues.value * 1) 53 | 54 | timeMs = np.linspace(0, (len(mVValues) -1) * interval, len(mVValues)) 55 | 56 | # plot data 57 | 58 | plt.plot(timeMs, mVValues[:]) 59 | plt.xlabel('Time (ms)') 60 | plt.ylabel('Voltage (mV)') 61 | plt.show() 62 | 63 | # close PicoLog 1000 device 64 | status["closeUnit"] = pl.pl1000CloseUnit(chandle) 65 | assert_pico_ok(status["closeUnit"]) 66 | 67 | # display status returns 68 | print(status) 69 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_dropout.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 80.0 14 | ADC_THRESHOLD = 1000 15 | 16 | THRESHOLD_DIRECTION = { 17 | 'PS2000_ABOVE': 0, 18 | 'PS2000_BELOW': 1, 19 | 'PS2000_ADV_RISING': 2, 20 | 'PS2000_ADV_FALLING': 3, 21 | 'PS2000_ADV_RISING_OR_FALLING': 4, 22 | 'PS2000_INSIDE': 0, 23 | 'PS2000_OUTSIDE': 1, 24 | 'PS2000_ENTER': 2, 25 | 'PS2000_EXIT': 3, 26 | 'PS2000_ENTER_OR_EXIT': 4, 27 | 'PS2000_ADV_NONE': 2, 28 | } 29 | 30 | 31 | class TriggerConditions(Structure): 32 | _fields_ = [ 33 | ('channelA', c_int32), 34 | ('channelB', c_int32), 35 | ('channelC', c_int32), 36 | ('channelD', c_int32), 37 | ('external', c_int32), 38 | ('pulseWidthQualifier', c_int32), 39 | ] 40 | 41 | 42 | class PwqConditions(Structure): 43 | _fields_ = [ 44 | ('channelA', c_int32), 45 | ('channelB', c_int32), 46 | ('channelC', c_int32), 47 | ('channelD', c_int32), 48 | ('external', c_int32), 49 | ] 50 | 51 | 52 | class TriggerChannelProperties(Structure): 53 | _fields_ = [ 54 | ("thresholdMajor", c_int16), 55 | ("thresholdMinor", c_int16), 56 | ("hysteresis", c_uint16), 57 | ("channel", c_int16), 58 | ("thresholdMode", c_int16), 59 | ] 60 | 61 | 62 | def get_timebase(device, wanted_time_interval): 63 | current_timebase = 1 64 | 65 | old_time_interval = None 66 | time_interval = c_int32(0) 67 | time_units = c_int16() 68 | max_samples = c_int32() 69 | 70 | while ps2000.ps2000_get_timebase( 71 | device.handle, 72 | current_timebase, 73 | SAMPLES, 74 | byref(time_interval), 75 | byref(time_units), 76 | 1, 77 | byref(max_samples)) == 0 \ 78 | or time_interval.value < wanted_time_interval: 79 | 80 | current_timebase += 1 81 | old_time_interval = time_interval.value 82 | 83 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 84 | raise Exception('No appropriate timebase was identifiable') 85 | 86 | return current_timebase - 1, old_time_interval 87 | 88 | 89 | with ps2000.open_unit() as device: 90 | print('Device info: {}'.format(device.info)) 91 | 92 | res = ps2000.ps2000_set_channel( 93 | device.handle, 94 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 95 | True, 96 | picoEnum.PICO_COUPLING['PICO_DC'], 97 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV'] 98 | ) 99 | assert_pico2000_ok(res) 100 | 101 | trigger_conditions = TriggerConditions(0, 0, 0, 0, 0, 1) 102 | 103 | res = ps2000.ps2000SetAdvTriggerChannelConditions( 104 | device.handle, 105 | byref(trigger_conditions), 106 | 1 107 | ) 108 | assert_pico2000_ok(res) 109 | 110 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 111 | assert_pico2000_ok(res) 112 | 113 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 114 | device.handle, 115 | THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'], 116 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 117 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 118 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 119 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 120 | ) 121 | assert_pico2000_ok(res) 122 | 123 | trigger_properties = TriggerChannelProperties( 124 | ADC_THRESHOLD, 125 | -ADC_THRESHOLD, 126 | 0, 127 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 128 | picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW'] 129 | ) 130 | 131 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 132 | assert_pico2000_ok(res) 133 | 134 | pwq_conditions = PwqConditions(1, 0, 0, 0, 0) 135 | 136 | res = ps2000.ps2000SetPulseWidthQualifier( 137 | device.handle, 138 | byref(pwq_conditions), 139 | 1, 140 | THRESHOLD_DIRECTION['PS2000_ENTER'], 141 | 200, 142 | 0, 143 | picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN'] 144 | ) 145 | assert_pico2000_ok(res) 146 | 147 | # calculate timebase 148 | timebase_a, interval = get_timebase(device, 20_000) 149 | 150 | collection_time = c_int32() 151 | 152 | fig, ax = plt.subplots() 153 | ax.set_xlabel('time/ms') 154 | ax.set_ylabel('ADC counts') 155 | 156 | res = ps2000.ps2000_run_block( 157 | device.handle, 158 | SAMPLES, 159 | timebase_a, 160 | OVERSAMPLING, 161 | byref(collection_time) 162 | ) 163 | assert_pico2000_ok(res) 164 | 165 | # wait for ready signal 166 | while ps2000.ps2000_ready(device.handle) == 0: 167 | sleep(0.1) 168 | 169 | times = (c_int32 * SAMPLES)() 170 | 171 | buffer_a = (c_int16 * SAMPLES)() 172 | 173 | res = ps2000.ps2000_get_times_and_values( 174 | device.handle, 175 | byref(times), 176 | byref(buffer_a), 177 | None, 178 | None, 179 | None, 180 | None, 181 | 2, 182 | SAMPLES, 183 | ) 184 | assert_pico2000_ok(res) 185 | 186 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 187 | 188 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 189 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 190 | 191 | ps2000.ps2000_stop(device.handle) 192 | 193 | plt.show() 194 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_interval.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 80.0 14 | 15 | THRESHOLD_DIRECTION = { 16 | 'PS2000_ABOVE': 0, 17 | 'PS2000_BELOW': 1, 18 | 'PS2000_ADV_RISING': 2, 19 | 'PS2000_ADV_FALLING': 3, 20 | 'PS2000_ADV_RISING_OR_FALLING': 4, 21 | 'PS2000_INSIDE': 0, 22 | 'PS2000_OUTSIDE': 1, 23 | 'PS2000_ENTER': 2, 24 | 'PS2000_EXIT': 3, 25 | 'PS2000_ENTER_OR_EXIT': 4, 26 | 'PS2000_ADV_NONE': 2, 27 | } 28 | 29 | 30 | class TriggerConditions(Structure): 31 | _fields_ = [ 32 | ('channelA', c_int32), 33 | ('channelB', c_int32), 34 | ('channelC', c_int32), 35 | ('channelD', c_int32), 36 | ('external', c_int32), 37 | ('pulseWidthQualifier', c_int32), 38 | ] 39 | 40 | 41 | class PwqConditions(Structure): 42 | _fields_ = [ 43 | ('channelA', c_int32), 44 | ('channelB', c_int32), 45 | ('channelC', c_int32), 46 | ('channelD', c_int32), 47 | ('external', c_int32), 48 | ] 49 | 50 | 51 | class TriggerChannelProperties(Structure): 52 | _fields_ = [ 53 | ("thresholdMajor", c_int16), 54 | ("thresholdMinor", c_int16), 55 | ("hysteresis", c_uint16), 56 | ("channel", c_int16), 57 | ("thresholdMode", c_int16), 58 | ] 59 | 60 | 61 | def get_timebase(device, wanted_time_interval): 62 | current_timebase = 1 63 | 64 | old_time_interval = None 65 | time_interval = c_int32(0) 66 | time_units = c_int16() 67 | max_samples = c_int32() 68 | 69 | while ps2000.ps2000_get_timebase( 70 | device.handle, 71 | current_timebase, 72 | SAMPLES, 73 | byref(time_interval), 74 | byref(time_units), 75 | 1, 76 | byref(max_samples)) == 0 \ 77 | or time_interval.value < wanted_time_interval: 78 | 79 | current_timebase += 1 80 | old_time_interval = time_interval.value 81 | 82 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 83 | raise Exception('No appropriate timebase was identifiable') 84 | 85 | return current_timebase - 1, old_time_interval 86 | 87 | 88 | with ps2000.open_unit() as device: 89 | print('Device info: {}'.format(device.info)) 90 | 91 | res = ps2000.ps2000_set_channel( 92 | device.handle, 93 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 94 | True, 95 | picoEnum.PICO_COUPLING['PICO_DC'], 96 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV'] 97 | ) 98 | assert_pico2000_ok(res) 99 | 100 | trigger_conditions = TriggerConditions(1, 0, 0, 0, 0, 1) 101 | 102 | res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1) 103 | assert_pico2000_ok(res) 104 | 105 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 106 | assert_pico2000_ok(res) 107 | 108 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 109 | device.handle, 110 | THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'], 111 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 112 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 113 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 114 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 115 | ) 116 | assert_pico2000_ok(res) 117 | 118 | trigger_properties = TriggerChannelProperties( 119 | 32000, 120 | 2048, 121 | 328, 122 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 123 | picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW'] 124 | ) 125 | 126 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 127 | assert_pico2000_ok(res) 128 | 129 | pwq_conditions = PwqConditions(1, 0, 0, 0, 0) 130 | 131 | res = ps2000.ps2000SetPulseWidthQualifier( 132 | device.handle, 133 | byref(pwq_conditions), 134 | 1, 135 | THRESHOLD_DIRECTION['PS2000_ENTER_OR_EXIT'], 136 | 600, 137 | 0, 138 | picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN'] 139 | ) 140 | assert_pico2000_ok(res) 141 | 142 | timebase_a, interval = get_timebase(device, 4_000) 143 | 144 | collection_time = c_int32() 145 | 146 | fig, ax = plt.subplots() 147 | ax.set_xlabel('time/ms') 148 | ax.set_ylabel('ADC counts') 149 | 150 | res = ps2000.ps2000_run_block( 151 | device.handle, 152 | SAMPLES, 153 | timebase_a, 154 | OVERSAMPLING, 155 | byref(collection_time) 156 | ) 157 | assert_pico2000_ok(res) 158 | 159 | while ps2000.ps2000_ready(device.handle) == 0: 160 | sleep(0.1) 161 | 162 | times = (c_int32 * SAMPLES)() 163 | 164 | buffer_a = (c_int16 * SAMPLES)() 165 | 166 | res = ps2000.ps2000_get_times_and_values( 167 | device.handle, 168 | byref(times), 169 | byref(buffer_a), 170 | None, 171 | None, 172 | None, 173 | None, 174 | 2, 175 | SAMPLES, 176 | ) 177 | assert_pico2000_ok(res) 178 | 179 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 180 | 181 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 182 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 183 | 184 | ps2000.ps2000_stop(device.handle) 185 | 186 | plt.show() 187 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_pwq.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 10.0 14 | ADC_THRESHOLD = 8192 15 | 16 | THRESHOLD_DIRECTION = { 17 | 'PS2000_ABOVE': 0, 18 | 'PS2000_BELOW': 1, 19 | 'PS2000_ADV_RISING': 2, 20 | 'PS2000_ADV_FALLING': 3, 21 | 'PS2000_ADV_RISING_OR_FALLING': 4, 22 | 'PS2000_INSIDE': 0, 23 | 'PS2000_OUTSIDE': 1, 24 | 'PS2000_ENTER': 2, 25 | 'PS2000_EXIT': 3, 26 | 'PS2000_ENTER_OR_EXIT': 4, 27 | 'PS2000_ADV_NONE': 2, 28 | } 29 | 30 | 31 | class TriggerConditions(Structure): 32 | _fields_ = [ 33 | ('channelA', c_int32), 34 | ('channelB', c_int32), 35 | ('channelC', c_int32), 36 | ('channelD', c_int32), 37 | ('external', c_int32), 38 | ('pulseWidthQualifier', c_int32), 39 | ] 40 | 41 | 42 | class PwqConditions(Structure): 43 | _fields_ = [ 44 | ('channelA', c_int32), 45 | ('channelB', c_int32), 46 | ('channelC', c_int32), 47 | ('channelD', c_int32), 48 | ('external', c_int32), 49 | ] 50 | 51 | 52 | class TriggerChannelProperties(Structure): 53 | _fields_ = [ 54 | ("thresholdMajor", c_int16), 55 | ("thresholdMinor", c_int16), 56 | ("hysteresis", c_uint16), 57 | ("channel", c_int16), 58 | ("thresholdMode", c_int16), 59 | ] 60 | 61 | 62 | def get_timebase(device, wanted_time_interval): 63 | current_timebase = 1 64 | 65 | old_time_interval = None 66 | time_interval = c_int32(0) 67 | time_units = c_int16() 68 | max_samples = c_int32() 69 | 70 | while ps2000.ps2000_get_timebase( 71 | device.handle, 72 | current_timebase, 73 | SAMPLES, 74 | byref(time_interval), 75 | byref(time_units), 76 | 1, 77 | byref(max_samples)) == 0 \ 78 | or time_interval.value < wanted_time_interval: 79 | 80 | current_timebase += 1 81 | old_time_interval = time_interval.value 82 | 83 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 84 | raise Exception('No appropriate timebase was identifiable') 85 | 86 | return current_timebase - 1, old_time_interval 87 | 88 | 89 | with ps2000.open_unit() as device: 90 | print('Device info: {}'.format(device.info)) 91 | 92 | res = ps2000.ps2000_set_channel( 93 | device.handle, 94 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 95 | True, 96 | picoEnum.PICO_COUPLING['PICO_DC'], 97 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'] 98 | ) 99 | assert_pico2000_ok(res) 100 | 101 | trigger_conditions = TriggerConditions(1, 0, 0, 0, 0, 1) 102 | 103 | res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1) 104 | assert_pico2000_ok(res) 105 | 106 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 107 | assert_pico2000_ok(res) 108 | 109 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 110 | device.handle, 111 | THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'], 112 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 113 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 114 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 115 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 116 | ) 117 | assert_pico2000_ok(res) 118 | 119 | trigger_properties = TriggerChannelProperties( 120 | ADC_THRESHOLD, 121 | ADC_THRESHOLD, 122 | 328, 123 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 124 | picoEnum.PICO_THRESHOLD_MODE['PICO_LEVEL'] 125 | ) 126 | 127 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 128 | assert_pico2000_ok(res) 129 | 130 | pwq_conditions = PwqConditions(1, 0, 0, 0, 0) 131 | 132 | res = ps2000.ps2000SetPulseWidthQualifier( 133 | device.handle, 134 | byref(pwq_conditions), 135 | 1, 136 | THRESHOLD_DIRECTION['PS2000_ADV_RISING_OR_FALLING'], 137 | 1000, 138 | 0, 139 | picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN'] 140 | ) 141 | assert_pico2000_ok(res) 142 | 143 | timebase_a, interval = get_timebase(device, 20_000) 144 | 145 | collection_time = c_int32() 146 | 147 | fig, ax = plt.subplots() 148 | ax.set_xlabel('time/ms') 149 | ax.set_ylabel('ADC counts') 150 | 151 | res = ps2000.ps2000_run_block( 152 | device.handle, 153 | SAMPLES, 154 | timebase_a, 155 | OVERSAMPLING, 156 | byref(collection_time) 157 | ) 158 | assert_pico2000_ok(res) 159 | 160 | while ps2000.ps2000_ready(device.handle) == 0: 161 | sleep(0.1) 162 | 163 | times = (c_int32 * SAMPLES)() 164 | 165 | buffer_a = (c_int16 * SAMPLES)() 166 | 167 | res = ps2000.ps2000_get_times_and_values( 168 | device.handle, 169 | byref(times), 170 | byref(buffer_a), 171 | None, 172 | None, 173 | None, 174 | None, 175 | 2, 176 | SAMPLES, 177 | ) 178 | assert_pico2000_ok(res) 179 | 180 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 181 | 182 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 183 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), [ADC_THRESHOLD for _ in times[:]], color='red') 184 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 185 | 186 | ps2000.ps2000_stop(device.handle) 187 | 188 | plt.show() 189 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_runt.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 80.0 14 | ADC_THRESHOLDS = (12000, 2048) 15 | 16 | THRESHOLD_DIRECTION = { 17 | 'PS2000_ABOVE': 0, 18 | 'PS2000_BELOW': 1, 19 | 'PS2000_ADV_RISING': 2, 20 | 'PS2000_ADV_FALLING': 3, 21 | 'PS2000_ADV_RISING_OR_FALLING': 4, 22 | 'PS2000_INSIDE': 0, 23 | 'PS2000_OUTSIDE': 1, 24 | 'PS2000_ENTER': 2, 25 | 'PS2000_EXIT': 3, 26 | 'PS2000_ENTER_OR_EXIT': 4, 27 | 'PS2000_ADV_NONE': 2, 28 | } 29 | 30 | 31 | class TriggerConditions(Structure): 32 | _fields_ = [ 33 | ('channelA', c_int32), 34 | ('channelB', c_int32), 35 | ('channelC', c_int32), 36 | ('channelD', c_int32), 37 | ('external', c_int32), 38 | ('pulseWidthQualifier', c_int32), 39 | ] 40 | 41 | 42 | class PwqConditions(Structure): 43 | _fields_ = [ 44 | ('channelA', c_int32), 45 | ('channelB', c_int32), 46 | ('channelC', c_int32), 47 | ('channelD', c_int32), 48 | ('external', c_int32), 49 | ] 50 | 51 | 52 | class TriggerChannelProperties(Structure): 53 | _fields_ = [ 54 | ("thresholdMajor", c_int16), 55 | ("thresholdMinor", c_int16), 56 | ("hysteresis", c_uint16), 57 | ("channel", c_int16), 58 | ("thresholdMode", c_int16), 59 | ] 60 | 61 | 62 | def get_timebase(device, wanted_time_interval): 63 | current_timebase = 1 64 | 65 | old_time_interval = None 66 | time_interval = c_int32(0) 67 | time_units = c_int16() 68 | max_samples = c_int32() 69 | 70 | while ps2000.ps2000_get_timebase( 71 | device.handle, 72 | current_timebase, 73 | SAMPLES, 74 | byref(time_interval), 75 | byref(time_units), 76 | 1, 77 | byref(max_samples)) == 0 \ 78 | or time_interval.value < wanted_time_interval: 79 | 80 | current_timebase += 1 81 | old_time_interval = time_interval.value 82 | 83 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 84 | raise Exception('No appropriate timebase was identifiable') 85 | 86 | return current_timebase - 1, old_time_interval 87 | 88 | 89 | with ps2000.open_unit() as device: 90 | print('Device info: {}'.format(device.info)) 91 | 92 | res = ps2000.ps2000_set_channel( 93 | device.handle, 94 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 95 | True, 96 | picoEnum.PICO_COUPLING['PICO_DC'], 97 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV'] 98 | ) 99 | assert_pico2000_ok(res) 100 | 101 | trigger_conditions = TriggerConditions(0, 0, 0, 0, 0, 1) 102 | 103 | res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1) 104 | assert_pico2000_ok(res) 105 | 106 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 107 | assert_pico2000_ok(res) 108 | 109 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 110 | device.handle, 111 | THRESHOLD_DIRECTION['PS2000_EXIT'], 112 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 113 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 114 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 115 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 116 | ) 117 | assert_pico2000_ok(res) 118 | 119 | trigger_properties = TriggerChannelProperties( 120 | max(ADC_THRESHOLDS), 121 | min(ADC_THRESHOLDS), 122 | 328, 123 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 124 | picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW'] 125 | ) 126 | 127 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 128 | assert_pico2000_ok(res) 129 | 130 | pwq_conditions = PwqConditions(1, 0, 0, 0, 0) 131 | 132 | res = ps2000.ps2000SetPulseWidthQualifier( 133 | device.handle, 134 | byref(pwq_conditions), 135 | 1, 136 | THRESHOLD_DIRECTION['PS2000_ENTER'], 137 | 100, 138 | 0, 139 | picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN'] 140 | ) 141 | assert_pico2000_ok(res) 142 | 143 | timebase_a, interval = get_timebase(device, 4_000) 144 | 145 | collection_time = c_int32() 146 | 147 | fig, ax = plt.subplots() 148 | ax.set_xlabel('time/ms') 149 | ax.set_ylabel('ADC counts') 150 | 151 | res = ps2000.ps2000_run_block( 152 | device.handle, 153 | SAMPLES, 154 | timebase_a, 155 | OVERSAMPLING, 156 | byref(collection_time) 157 | ) 158 | assert_pico2000_ok(res) 159 | 160 | while ps2000.ps2000_ready(device.handle) == 0: 161 | sleep(0.1) 162 | 163 | times = (c_int32 * SAMPLES)() 164 | 165 | buffer_a = (c_int16 * SAMPLES)() 166 | 167 | res = ps2000.ps2000_get_times_and_values( 168 | device.handle, 169 | byref(times), 170 | byref(buffer_a), 171 | None, 172 | None, 173 | None, 174 | None, 175 | 2, 176 | SAMPLES, 177 | ) 178 | assert_pico2000_ok(res) 179 | 180 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 181 | 182 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 183 | for threshold in ADC_THRESHOLDS: 184 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), [threshold for _ in times[:]], color='red') 185 | 186 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 187 | 188 | ps2000.ps2000_stop(device.handle) 189 | 190 | plt.show() 191 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_window.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 25.0 14 | ADC_THRESHOLD = 8192 15 | 16 | THRESHOLD_DIRECTION = { 17 | 'PS2000_ABOVE': 0, 18 | 'PS2000_BELOW': 1, 19 | 'PS2000_ADV_RISING': 2, 20 | 'PS2000_ADV_FALLING': 3, 21 | 'PS2000_ADV_RISING_OR_FALLING': 4, 22 | 'PS2000_INSIDE': 0, 23 | 'PS2000_OUTSIDE': 1, 24 | 'PS2000_ENTER': 2, 25 | 'PS2000_EXIT': 3, 26 | 'PS2000_ENTER_OR_EXIT': 4, 27 | 'PS2000_ADV_NONE': 2, 28 | } 29 | 30 | 31 | class TriggerConditions(Structure): 32 | _fields_ = [ 33 | ('channelA', c_int32), 34 | ('channelB', c_int32), 35 | ('channelC', c_int32), 36 | ('channelD', c_int32), 37 | ('external', c_int32), 38 | ('pulseWidthQualifier', c_int32), 39 | ] 40 | 41 | 42 | class PwqConditions(Structure): 43 | _fields_ = [ 44 | ('channelA', c_int32), 45 | ('channelB', c_int32), 46 | ('channelC', c_int32), 47 | ('channelD', c_int32), 48 | ('external', c_int32), 49 | ] 50 | 51 | 52 | class TriggerChannelProperties(Structure): 53 | _fields_ = [ 54 | ("thresholdMajor", c_int16), 55 | ("thresholdMinor", c_int16), 56 | ("hysteresis", c_uint16), 57 | ("channel", c_int16), 58 | ("thresholdMode", c_int16), 59 | ] 60 | 61 | 62 | def get_timebase(device, wanted_time_interval): 63 | current_timebase = 1 64 | 65 | old_time_interval = None 66 | time_interval = c_int32(0) 67 | time_units = c_int16() 68 | max_samples = c_int32() 69 | 70 | while ps2000.ps2000_get_timebase( 71 | device.handle, 72 | current_timebase, 73 | SAMPLES, 74 | byref(time_interval), 75 | byref(time_units), 76 | 1, 77 | byref(max_samples)) == 0 \ 78 | or time_interval.value < wanted_time_interval: 79 | 80 | current_timebase += 1 81 | old_time_interval = time_interval.value 82 | 83 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 84 | raise Exception('No appropriate timebase was identifiable') 85 | 86 | return current_timebase - 1, old_time_interval 87 | 88 | 89 | with ps2000.open_unit() as device: 90 | print('Device info: {}'.format(device.info)) 91 | 92 | res = ps2000.ps2000_set_channel( 93 | device.handle, 94 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 95 | True, 96 | picoEnum.PICO_COUPLING['PICO_DC'], 97 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'] 98 | ) 99 | assert_pico2000_ok(res) 100 | 101 | trigger_conditions = TriggerConditions(1, 0, 0, 0, 0, 0) 102 | 103 | res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1) 104 | assert_pico2000_ok(res) 105 | 106 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 107 | assert_pico2000_ok(res) 108 | 109 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 110 | device.handle, 111 | THRESHOLD_DIRECTION['PS2000_EXIT'], 112 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 113 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 114 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 115 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 116 | ) 117 | assert_pico2000_ok(res) 118 | 119 | trigger_properties = TriggerChannelProperties( 120 | ADC_THRESHOLD, 121 | -ADC_THRESHOLD, 122 | 2, 123 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 124 | picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW'] 125 | ) 126 | 127 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 128 | assert_pico2000_ok(res) 129 | 130 | timebase_a, interval = get_timebase(device, 20_000) 131 | 132 | collection_time = c_int32() 133 | 134 | fig, ax = plt.subplots() 135 | ax.set_xlabel('time/ms') 136 | ax.set_ylabel('ADC counts') 137 | 138 | res = ps2000.ps2000_run_block( 139 | device.handle, 140 | SAMPLES, 141 | timebase_a, 142 | OVERSAMPLING, 143 | byref(collection_time) 144 | ) 145 | assert_pico2000_ok(res) 146 | 147 | while ps2000.ps2000_ready(device.handle) == 0: 148 | sleep(0.1) 149 | 150 | times = (c_int32 * SAMPLES)() 151 | 152 | buffer_a = (c_int16 * SAMPLES)() 153 | 154 | res = ps2000.ps2000_get_times_and_values( 155 | device.handle, 156 | byref(times), 157 | byref(buffer_a), 158 | None, 159 | None, 160 | None, 161 | None, 162 | 2, 163 | SAMPLES, 164 | ) 165 | assert_pico2000_ok(res) 166 | 167 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 168 | 169 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 170 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), [ADC_THRESHOLD for _ in times[:]], color='red') 171 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), [-ADC_THRESHOLD for _ in times[:]], color='red') 172 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 173 | 174 | ps2000.ps2000_stop(device.handle) 175 | 176 | plt.show() 177 | -------------------------------------------------------------------------------- /ps2000Examples/advanced triggers/trigger_read_wpwq.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_int16, c_int32, sizeof, Structure, c_uint16 2 | from time import sleep 3 | 4 | import numpy as np 5 | from picosdk.ps2000 import ps2000 6 | from picosdk.functions import assert_pico2000_ok, adc2mV 7 | from picosdk.PicoDeviceEnums import picoEnum 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | PRESAMPLE = 80.0 14 | ADC_THRESHOLDS = (6553, 32000) 15 | 16 | THRESHOLD_DIRECTION = { 17 | 'PS2000_ABOVE': 0, 18 | 'PS2000_BELOW': 1, 19 | 'PS2000_ADV_RISING': 2, 20 | 'PS2000_ADV_FALLING': 3, 21 | 'PS2000_ADV_RISING_OR_FALLING': 4, 22 | 'PS2000_INSIDE': 0, 23 | 'PS2000_OUTSIDE': 1, 24 | 'PS2000_ENTER': 2, 25 | 'PS2000_EXIT': 3, 26 | 'PS2000_ENTER_OR_EXIT': 4, 27 | 'PS2000_ADV_NONE': 2, 28 | } 29 | 30 | 31 | class TriggerConditions(Structure): 32 | _fields_ = [ 33 | ('channelA', c_int32), 34 | ('channelB', c_int32), 35 | ('channelC', c_int32), 36 | ('channelD', c_int32), 37 | ('external', c_int32), 38 | ('pulseWidthQualifier', c_int32), 39 | ] 40 | 41 | 42 | class PwqConditions(Structure): 43 | _fields_ = [ 44 | ('channelA', c_int32), 45 | ('channelB', c_int32), 46 | ('channelC', c_int32), 47 | ('channelD', c_int32), 48 | ('external', c_int32), 49 | ] 50 | 51 | 52 | class TriggerChannelProperties(Structure): 53 | _fields_ = [ 54 | ("thresholdMajor", c_int16), 55 | ("thresholdMinor", c_int16), 56 | ("hysteresis", c_uint16), 57 | ("channel", c_int16), 58 | ("thresholdMode", c_int16), 59 | ] 60 | 61 | 62 | def get_timebase(device, wanted_time_interval): 63 | current_timebase = 1 64 | 65 | old_time_interval = None 66 | time_interval = c_int32(0) 67 | time_units = c_int16() 68 | max_samples = c_int32() 69 | 70 | while ps2000.ps2000_get_timebase( 71 | device.handle, 72 | current_timebase, 73 | SAMPLES, 74 | byref(time_interval), 75 | byref(time_units), 76 | 1, 77 | byref(max_samples)) == 0 \ 78 | or time_interval.value < wanted_time_interval: 79 | 80 | current_timebase += 1 81 | old_time_interval = time_interval.value 82 | 83 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 84 | raise Exception('No appropriate timebase was identifiable') 85 | 86 | return current_timebase - 1, old_time_interval 87 | 88 | 89 | with ps2000.open_unit() as device: 90 | print('Device info: {}'.format(device.info)) 91 | 92 | res = ps2000.ps2000_set_channel( 93 | device.handle, 94 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 95 | True, 96 | picoEnum.PICO_COUPLING['PICO_DC'], 97 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'] 98 | ) 99 | assert_pico2000_ok(res) 100 | 101 | trigger_conditions = TriggerConditions(0, 0, 0, 0, 0, 1) 102 | 103 | res = ps2000.ps2000SetAdvTriggerChannelConditions(device.handle, byref(trigger_conditions), 1) 104 | assert_pico2000_ok(res) 105 | 106 | res = ps2000.ps2000SetAdvTriggerDelay(device.handle, 0, -PRESAMPLE) 107 | assert_pico2000_ok(res) 108 | 109 | res = ps2000.ps2000SetAdvTriggerChannelDirections( 110 | device.handle, 111 | THRESHOLD_DIRECTION['PS2000_ENTER'], 112 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 113 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 114 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'], 115 | THRESHOLD_DIRECTION['PS2000_ADV_NONE'] 116 | ) 117 | assert_pico2000_ok(res) 118 | 119 | trigger_properties = TriggerChannelProperties( 120 | max(ADC_THRESHOLDS), 121 | min(ADC_THRESHOLDS), 122 | 328, 123 | ps2000.PS2000_CHANNEL['PS2000_CHANNEL_A'], 124 | picoEnum.PICO_THRESHOLD_MODE['PICO_WINDOW'] 125 | ) 126 | 127 | res = ps2000.ps2000SetAdvTriggerChannelProperties(device.handle, byref(trigger_properties), 1, 0) 128 | assert_pico2000_ok(res) 129 | 130 | pwq_conditions = PwqConditions(1, 0, 0, 0, 0) 131 | 132 | res = ps2000.ps2000SetPulseWidthQualifier( 133 | device.handle, 134 | byref(pwq_conditions), 135 | 1, 136 | THRESHOLD_DIRECTION['PS2000_ENTER'], 137 | 195, 138 | 0, 139 | picoEnum.PICO_PULSE_WIDTH_TYPE['PICO_PW_TYPE_GREATER_THAN'] 140 | ) 141 | assert_pico2000_ok(res) 142 | 143 | timebase_a, interval = get_timebase(device, 20_000) 144 | 145 | collection_time = c_int32() 146 | 147 | fig, ax = plt.subplots() 148 | ax.set_xlabel('time/ms') 149 | ax.set_ylabel('ADC counts') 150 | 151 | res = ps2000.ps2000_run_block( 152 | device.handle, 153 | SAMPLES, 154 | timebase_a, 155 | OVERSAMPLING, 156 | byref(collection_time) 157 | ) 158 | assert_pico2000_ok(res) 159 | 160 | while ps2000.ps2000_ready(device.handle) == 0: 161 | sleep(0.1) 162 | 163 | times = (c_int32 * SAMPLES)() 164 | 165 | buffer_a = (c_int16 * SAMPLES)() 166 | 167 | res = ps2000.ps2000_get_times_and_values( 168 | device.handle, 169 | byref(times), 170 | byref(buffer_a), 171 | None, 172 | None, 173 | None, 174 | None, 175 | 2, 176 | SAMPLES, 177 | ) 178 | assert_pico2000_ok(res) 179 | 180 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 181 | 182 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), buffer_a[:]) 183 | for threshold in ADC_THRESHOLDS: 184 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), [threshold for _ in times[:]], color='red') 185 | 186 | ax.axvline(np.percentile(list(map(lambda x: x * 1e-6, times[:])), PRESAMPLE), color='red', linestyle='dotted') 187 | 188 | ps2000.ps2000_stop(device.handle) 189 | 190 | plt.show() 191 | -------------------------------------------------------------------------------- /ps2000Examples/block_read.py: -------------------------------------------------------------------------------- 1 | from ctypes import byref, c_byte, c_int16, c_int32, sizeof 2 | from time import sleep 3 | 4 | from picosdk.ps2000 import ps2000 5 | from picosdk.functions import assert_pico2000_ok, adc2mV 6 | from picosdk.PicoDeviceEnums import picoEnum 7 | 8 | import matplotlib.pyplot as plt 9 | 10 | 11 | SAMPLES = 2000 12 | OVERSAMPLING = 1 13 | 14 | 15 | def get_timebase(device, wanted_time_interval): 16 | current_timebase = 1 17 | 18 | old_time_interval = None 19 | time_interval = c_int32(0) 20 | time_units = c_int16() 21 | max_samples = c_int32() 22 | 23 | while ps2000.ps2000_get_timebase( 24 | device.handle, 25 | current_timebase, 26 | 2000, 27 | byref(time_interval), 28 | byref(time_units), 29 | 1, 30 | byref(max_samples)) == 0 \ 31 | or time_interval.value < wanted_time_interval: 32 | 33 | current_timebase += 1 34 | old_time_interval = time_interval.value 35 | 36 | if current_timebase.bit_length() > sizeof(c_int16) * 8: 37 | raise Exception('No appropriate timebase was identifiable') 38 | 39 | return current_timebase - 1, old_time_interval 40 | 41 | 42 | with ps2000.open_unit() as device: 43 | print('Device info: {}'.format(device.info)) 44 | 45 | res = ps2000.ps2000_set_channel( 46 | device.handle, 47 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_A'], 48 | True, 49 | picoEnum.PICO_COUPLING['PICO_DC'], 50 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV'], 51 | ) 52 | assert_pico2000_ok(res) 53 | 54 | res = ps2000.ps2000_set_channel( 55 | device.handle, 56 | picoEnum.PICO_CHANNEL['PICO_CHANNEL_B'], 57 | True, 58 | picoEnum.PICO_COUPLING['PICO_DC'], 59 | ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], 60 | ) 61 | assert_pico2000_ok(res) 62 | 63 | timebase_a, interval = get_timebase(device, 4_000) 64 | 65 | collection_time = c_int32() 66 | 67 | res = ps2000.ps2000_run_block( 68 | device.handle, 69 | SAMPLES, 70 | timebase_a, 71 | OVERSAMPLING, 72 | byref(collection_time) 73 | ) 74 | assert_pico2000_ok(res) 75 | 76 | while ps2000.ps2000_ready(device.handle) == 0: 77 | sleep(0.1) 78 | 79 | times = (c_int32 * SAMPLES)() 80 | 81 | buffer_a = (c_int16 * SAMPLES)() 82 | buffer_b = (c_int16 * SAMPLES)() 83 | 84 | overflow = c_byte(0) 85 | 86 | res = ps2000.ps2000_get_times_and_values( 87 | device.handle, 88 | byref(times), 89 | byref(buffer_a), 90 | byref(buffer_b), 91 | None, 92 | None, 93 | byref(overflow), 94 | 2, 95 | SAMPLES, 96 | ) 97 | assert_pico2000_ok(res) 98 | 99 | channel_a_overflow = (overflow.value & 0b0000_0001) != 0 100 | 101 | ps2000.ps2000_stop(device.handle) 102 | 103 | channel_a_mv = adc2mV(buffer_a, ps2000.PS2000_VOLTAGE_RANGE['PS2000_500MV'], c_int16(32767)) 104 | channel_b_mv = adc2mV(buffer_b, ps2000.PS2000_VOLTAGE_RANGE['PS2000_50MV'], c_int16(32767)) 105 | 106 | fig, ax = plt.subplots() 107 | ax.set_xlabel('time/ms') 108 | ax.set_ylabel('voltage/mV') 109 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), channel_a_mv[:]) 110 | ax.plot(list(map(lambda x: x * 1e-6, times[:])), channel_b_mv[:]) 111 | 112 | if channel_a_overflow: 113 | ax.text(0.01, 0.01, 'Overflow present', color='red', transform=ax.transAxes) 114 | 115 | plt.show() 116 | -------------------------------------------------------------------------------- /ps2000Examples/device_info.py: -------------------------------------------------------------------------------- 1 | from picosdk.ps2000 import ps2000 2 | 3 | with ps2000.open_unit() as device: 4 | print('Device info: {}'.format(device.info)) 5 | -------------------------------------------------------------------------------- /ps2000Examples/gen_sq_wave.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import numpy as np 3 | 4 | def gen_square(t, duty, low_thres): 5 | t, w = np.asarray(t), np.asarray(duty) 6 | w = np.asarray(w + (t - t)) 7 | t = np.asarray(t + (w - w)) 8 | if t.dtype.char in ['fFdD']: 9 | ytype = t.dtype.char 10 | else: 11 | ytype = 'd' 12 | 13 | y = np.zeros(t.shape, ytype) 14 | # width must be between 0 and 1 inclusive 15 | mask1 = (w > 1) | (w < 0) 16 | np.place(y, mask1, np.nan) 17 | # on the interval 0 to duty*2*pi the function is 1 18 | tmod = np.mod(t, 2 * np.pi) 19 | 20 | mask2 = (32767-mask1)&(tmod 5_000: 57 | interval_ns /= 1000 58 | unit += 1 59 | 60 | return interval_ns, units[unit] 61 | 62 | 63 | class StreamingDevice: 64 | def __init__(self, gather_values, potential_range=PotentialRange.PS2000_50MV): 65 | self.device = ps2000.open_unit() 66 | self.potential_range = potential_range 67 | 68 | self.gather_values = gather_values 69 | 70 | res = ps2000.ps2000_set_channel(self.device.handle, Channel.PS2000_CHANNEL_A, True, True, potential_range) 71 | assert_pico2000_ok(res) 72 | 73 | # start 'fast-streaming' mode 74 | res = ps2000.ps2000_run_streaming_ns( 75 | self.device.handle, 76 | 500, 77 | TimeUnit.NANOSECOND, 78 | 100_000, 79 | False, 80 | 1, 81 | 50_000 82 | ) 83 | assert_pico2000_ok(res) 84 | 85 | self.start_time = time_ns() 86 | self.end_time = time_ns() 87 | 88 | def close(self): 89 | ps2000.ps2000_stop(self.device.handle) 90 | self.device.close() 91 | 92 | def gather(self): 93 | adc_values = [] 94 | 95 | def get_overview_buffers(buffers, _overflow, _triggered_at, _triggered, _auto_stop, n_values): 96 | adc_values.extend(buffers[0][0:n_values]) 97 | 98 | callback = CALLBACK(get_overview_buffers) 99 | 100 | while len(adc_values) < self.gather_values: 101 | ps2000.ps2000_get_streaming_last_values( 102 | self.device.handle, 103 | callback 104 | ) 105 | 106 | self.end_time = time_ns() 107 | 108 | return adc_to_mv(adc_values, self.potential_range) 109 | 110 | 111 | stream = StreamingDevice(6_000_000) 112 | values = stream.gather() 113 | stream.close() 114 | 115 | print('Values gathered: {}'.format(len(values))) 116 | 117 | fig, ax = plt.subplots() 118 | interval, units = determine_time_unit(stream.end_time - stream.start_time) 119 | 120 | ax.set_xlabel('time/{}'.format(units)) 121 | ax.set_ylabel('voltage/mV') 122 | ax.plot(np.linspace(0, interval, len(values)), values) 123 | 124 | plt.show() 125 | -------------------------------------------------------------------------------- /ps2000Examples/streaming_mode/streaming_mode_polling.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import concurrent.futures 3 | import functools 4 | 5 | from ctypes import POINTER, c_int16, c_uint32 6 | 7 | from picosdk.ps2000 import ps2000 8 | from picosdk.functions import assert_pico2000_ok 9 | from picosdk.ctypes_wrapper import C_CALLBACK_FUNCTION_FACTORY 10 | 11 | from enum import IntEnum 12 | 13 | 14 | class Channel(IntEnum): 15 | PS2000_CHANNEL_A = 0 16 | PS2000_CHANNEL_B = 1 17 | 18 | 19 | class PotentialRange(IntEnum): 20 | PS2000_20MV = 1 21 | PS2000_50MV = 2 22 | PS2000_100MV = 3 23 | PS2000_200MV = 4 24 | PS2000_500MV = 5 25 | PS2000_1V = 6 26 | PS2000_2V = 7 27 | PS2000_5V = 8 28 | PS2000_10V = 9 29 | PS2000_20V = 10 30 | 31 | 32 | CALLBACK = C_CALLBACK_FUNCTION_FACTORY(None, POINTER(POINTER(c_int16)), c_int16, c_uint32, c_int16, c_int16, c_uint32) 33 | 34 | 35 | # reimplement this because the other one only takes ctypes 36 | def adc_to_mv(values, range_, bitness=16): 37 | v_ranges = [10, 20, 50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000] 38 | 39 | return [(x * v_ranges[range_]) / (2**(bitness - 1) - 1) for x in values] 40 | 41 | 42 | class StreamingDevice: 43 | def __init__(self, potential_range=PotentialRange.PS2000_50MV): 44 | self.device = ps2000.open_unit() 45 | self.potential_range = potential_range 46 | # create an event loop 47 | self.loop = asyncio.new_event_loop() 48 | # create a thread-pool executor 49 | self.executor = concurrent.futures.ThreadPoolExecutor() 50 | 51 | self.waiting_blocks = {} 52 | 53 | res = ps2000.ps2000_set_channel(self.device.handle, Channel.PS2000_CHANNEL_A, True, True, potential_range) 54 | assert_pico2000_ok(res) 55 | 56 | # start 'fast-streaming' mode 57 | res = ps2000.ps2000_run_streaming_ns( 58 | self.device.handle, 59 | 100, 60 | 3, 61 | 30_000, 62 | False, 63 | 1, 64 | 15_000 65 | ) 66 | assert_pico2000_ok(res) 67 | 68 | async def process_value(self, mv_value): 69 | # overload 70 | pass 71 | 72 | def get_streamed_values(self, block_id): 73 | def get_overview_buffers(buffers, _overflow, _triggered_at, _triggered, _auto_stop, n_values): 74 | adc_values = buffers[0][0:n_values] 75 | 76 | mv_values = adc_to_mv(adc_values, self.potential_range) 77 | 78 | self.waiting_blocks[block_id] = mv_values 79 | 80 | callback = CALLBACK(get_overview_buffers) 81 | 82 | res = ps2000.ps2000_get_streaming_last_values( 83 | self.device.handle, 84 | callback 85 | ) 86 | assert_pico2000_ok(res) 87 | 88 | def start(self): 89 | async def gather_values(): 90 | block_id = 0 91 | while True: 92 | await asyncio.sleep(0.5) 93 | 94 | await self.loop.run_in_executor(self.executor, functools.partial(self.get_streamed_values, block_id)) 95 | 96 | block_id += 1 97 | 98 | async def poll_waiting(): 99 | next_block = 0 100 | while True: 101 | if block := self.waiting_blocks.get(next_block): 102 | next_block += 1 103 | for n in block: 104 | await self.process_value(n) 105 | 106 | await asyncio.sleep(0.25) 107 | 108 | try: 109 | self.loop.create_task(gather_values()) 110 | self.loop.run_until_complete(poll_waiting()) 111 | finally: 112 | self.loop.close() 113 | ps2000.ps2000_stop(self.device.handle) 114 | ps2000.ps2000_close(self.device.handle) 115 | 116 | 117 | stream = StreamingDevice() 118 | stream.start() 119 | -------------------------------------------------------------------------------- /ps2000Examples/streaming_mode/streaming_mode_threaded.py: -------------------------------------------------------------------------------- 1 | from ctypes import POINTER, c_int16, c_uint32 2 | 3 | from picosdk.ps2000 import ps2000 4 | from picosdk.functions import assert_pico2000_ok 5 | from picosdk.ctypes_wrapper import C_CALLBACK_FUNCTION_FACTORY 6 | 7 | from enum import IntEnum 8 | from concurrent.futures import ThreadPoolExecutor 9 | 10 | import functools 11 | import time 12 | import os 13 | 14 | CALLBACK = C_CALLBACK_FUNCTION_FACTORY(None, POINTER(POINTER(c_int16)), c_int16, c_uint32, c_int16, c_int16, c_uint32) 15 | 16 | THREADPOOL = ThreadPoolExecutor() 17 | 18 | past_mv_values = [] 19 | 20 | term_width = os.get_terminal_size() 21 | 22 | 23 | def process_values(adc_values): 24 | mv_values = adc_to_mv(adc_values, PotentialRange.PS2000_50MV) 25 | 26 | for value in mv_values: 27 | pre = (value + 500) / 500 * term_width 28 | print('{}|'.format(' ' * pre)) 29 | 30 | past_mv_values.extend(mv_values) 31 | 32 | 33 | def get_overview_buffers(buffers, _overflow, _triggered_at, _triggered, _auto_stop, n_values): 34 | adc_values = buffers[0][0:n_values] 35 | 36 | THREADPOOL.submit(functools.partial(process_values, adc_values)) 37 | 38 | 39 | callback = CALLBACK(get_overview_buffers) 40 | 41 | 42 | def adc_to_mv(values, range_, bitness=16): 43 | v_ranges = [10, 20, 50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000] 44 | 45 | return [(x * v_ranges[range_]) / (2**(bitness - 1) - 1) for x in values] 46 | 47 | 48 | class Channel(IntEnum): 49 | PS2000_CHANNEL_A = 0 50 | PS2000_CHANNEL_B = 1 51 | 52 | 53 | class PotentialRange(IntEnum): 54 | PS2000_20MV = 1 55 | PS2000_50MV = 2 56 | PS2000_100MV = 3 57 | PS2000_200MV = 4 58 | PS2000_500MV = 5 59 | PS2000_1V = 6 60 | PS2000_2V = 7 61 | PS2000_5V = 8 62 | PS2000_10V = 9 63 | PS2000_20V = 10 64 | 65 | 66 | with ps2000.open_unit() as device: 67 | res = ps2000.ps2000_set_channel(device.handle, Channel.PS2000_CHANNEL_A, True, True, PotentialRange.PS2000_50MV) 68 | assert_pico2000_ok(res) 69 | 70 | res = ps2000.ps2000_run_streaming_ns( 71 | device.handle, 72 | 500, 73 | 2, 74 | 100_000, 75 | False, 76 | 1, 77 | 50_000 78 | ) 79 | assert_pico2000_ok(res) 80 | 81 | target_samples = 1_000_000 82 | 83 | while True: 84 | ps2000.ps2000_get_streaming_last_values( 85 | device.handle, 86 | callback 87 | ) 88 | 89 | time.sleep(0.01) 90 | -------------------------------------------------------------------------------- /ps3000EExamples/ps3000EBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PSOSPA BLOCK MODE EXAMPLE 5 | # This example opens a psospa driver device, sets up two channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.psospa import psospa as ps 11 | from picosdk.PicoDeviceEnums import picoEnum as enums 12 | from picosdk.PicoDeviceStructs import picoStruct as structs 13 | # from picosdk.PicoConnectProbes import picoConnectProbes as probes 14 | import matplotlib.pyplot as plt 15 | from picosdk.functions import adc2mVV2, mV2adcV2, assert_pico_ok 16 | 17 | # Create chandle and status ready for use 18 | chandle = ctypes.c_int16() 19 | status = {} 20 | 21 | # Open a psospa driver device 22 | # returns handle for future API functions 23 | resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"] 24 | status["openUnit"] = ps.psospaOpenUnit(ctypes.byref(chandle), None, resolution, None) 25 | assert_pico_ok(status["openUnit"]) 26 | 27 | # Set channel A on 28 | # handle = chandle 29 | channelA = enums.PICO_CHANNEL["PICO_CHANNEL_A"] 30 | coupling = enums.PICO_COUPLING["PICO_DC"] 31 | rangeMax = 2000000000 #nV 32 | rangeMin = -rangeMax #nV 33 | rangeType = 0 #probes.PICO_PROBE_RANGE_INFO["PICO_PROBE_NONE_NV"] 34 | analogueOffset = 0 35 | bandwidth = enums.PICO_BANDWIDTH_LIMITER["PICO_BW_FULL"] 36 | status["setChannelA"] = ps.psospaSetChannelOn(chandle, channelA, coupling, rangeMin, rangeMax, rangeType, analogueOffset, bandwidth) 37 | assert_pico_ok(status["setChannelA"]) 38 | 39 | # set channel B-H off 40 | for x in range (1, 3, 1): 41 | channel = x 42 | status["setChannel",x] = ps.psospaSetChannelOff(chandle,channel) 43 | assert_pico_ok(status["setChannel",x]) 44 | 45 | # get max ADC value 46 | # handle = chandle 47 | minADC = ctypes.c_int16() 48 | maxADC = ctypes.c_int16() 49 | status["getAdcLimits"] = ps.psospaGetAdcLimits(chandle, resolution, ctypes.byref(minADC), ctypes.byref(maxADC)) 50 | assert_pico_ok(status["getAdcLimits"]) 51 | 52 | # Set simple trigger on channel A, 1 V rising with 1 s autotrigger 53 | # handle = chandle 54 | # enable = 1 55 | source = channelA 56 | # threshold = 100 mV 57 | direction = enums.PICO_THRESHOLD_DIRECTION["PICO_RISING"] 58 | # delay = 0 s 59 | # autoTriggerMicroSeconds = 1000000 us 60 | status["setSimpleTrigger"] = ps.psospaSetSimpleTrigger(chandle, 1, source, mV2adcV2(100,rangeMax,maxADC), direction, 0, 1000000) 61 | assert_pico_ok(status["setSimpleTrigger"]) 62 | 63 | # Get fastest available timebase 64 | # handle = chandle 65 | enabledChannelFlags = enums.PICO_CHANNEL_FLAGS["PICO_CHANNEL_A_FLAGS"] 66 | timebase = ctypes.c_uint32(0) 67 | timeInterval = ctypes.c_double(0) 68 | # resolution = resolution 69 | status["getMinimumTimebaseStateless"] = ps.psospaGetMinimumTimebaseStateless(chandle, enabledChannelFlags, ctypes.byref(timebase), ctypes.byref(timeInterval), resolution) 70 | print("timebase = ", timebase.value) 71 | print("sample interval =", timeInterval.value, "s") 72 | 73 | # Set number of samples to be collected 74 | noOfPreTriggerSamples = 500000 75 | noOfPostTriggerSamples = 1000000 76 | nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples 77 | 78 | # Create buffers 79 | bufferAMax = (ctypes.c_int16 * nSamples)() 80 | bufferAMin = (ctypes.c_int16 * nSamples)() # used for downsampling which isn't in the scope of this example 81 | 82 | # Set data buffers 83 | # handle = chandle 84 | # channel = channelA 85 | # bufferMax = bufferAMax 86 | # bufferMin = bufferAMin 87 | # nSamples = nSamples 88 | dataType = enums.PICO_DATA_TYPE["PICO_INT16_T"] 89 | waveform = 0 90 | downSampleMode = enums.PICO_RATIO_MODE["PICO_RATIO_MODE_RAW"] 91 | clear = enums.PICO_ACTION["PICO_CLEAR_ALL"] 92 | add = enums.PICO_ACTION["PICO_ADD"] 93 | action = clear|add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"] 94 | status["setDataBuffers"] = ps.psospaSetDataBuffers(chandle, channelA, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), nSamples, dataType, waveform, downSampleMode, action) 95 | assert_pico_ok(status["setDataBuffers"]) 96 | 97 | # Run block capture 98 | # handle = chandle 99 | # timebase = timebase 100 | timeIndisposedMs = ctypes.c_double(0) 101 | # segmentIndex = 0 102 | # lpReady = None Using IsReady rather than a callback 103 | # pParameter = None 104 | status["runBlock"] = ps.psospaRunBlock(chandle, noOfPreTriggerSamples, noOfPostTriggerSamples, timebase, ctypes.byref(timeIndisposedMs), 0, None, None) 105 | assert_pico_ok(status["runBlock"]) 106 | 107 | # Check for data collection to finish using psospaIsReady 108 | ready = ctypes.c_int16(0) 109 | check = ctypes.c_int16(0) 110 | while ready.value == check.value: 111 | status["isReady"] = ps.psospaIsReady(chandle, ctypes.byref(ready)) 112 | 113 | # Get data from scope 114 | # handle = chandle 115 | # startIndex = 0 116 | noOfSamples = ctypes.c_uint64(nSamples) 117 | # downSampleRatio = 1 118 | # segmentIndex = 0 119 | overflow = ctypes.c_int16(0) 120 | status["getValues"] = ps.psospaGetValues(chandle, 0, ctypes.byref(noOfSamples), 1, downSampleMode, 0, ctypes.byref(overflow)) 121 | assert_pico_ok(status["getValues"]) 122 | 123 | 124 | 125 | # # convert ADC counts data to mV 126 | adc2mVChAMax = adc2mVV2(bufferAMax, rangeMax, maxADC) 127 | 128 | # Create time data 129 | time = np.linspace(0, (nSamples -1) * timeInterval.value * 1000000000, nSamples) 130 | 131 | # plot data from channel A and B 132 | plt.plot(time, bufferAMax[:]) 133 | plt.xlabel('Time (ns)') 134 | plt.ylabel('Voltage (mV)') 135 | plt.show() 136 | 137 | # Close the psospa driver device 138 | status["closeUnit"] = ps.psospaCloseUnit(chandle) 139 | assert_pico_ok(status["closeUnit"]) 140 | 141 | print(status) -------------------------------------------------------------------------------- /ps3000aExamples/ps3000aBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS3000A BLOCK MODE EXAMPLE 5 | # This example opens a 3000a driver device, sets up one channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | from picosdk.ps3000a import ps3000a as ps 10 | import numpy as np 11 | import matplotlib.pyplot as plt 12 | from picosdk.functions import adc2mV, assert_pico_ok 13 | 14 | # Create chandle and status ready for use 15 | status = {} 16 | chandle = ctypes.c_int16() 17 | 18 | # Opens the device/s 19 | status["openunit"] = ps.ps3000aOpenUnit(ctypes.byref(chandle), None) 20 | 21 | try: 22 | assert_pico_ok(status["openunit"]) 23 | except: 24 | 25 | # powerstate becomes the status number of openunit 26 | powerstate = status["openunit"] 27 | 28 | # If powerstate is the same as 282 then it will run this if statement 29 | if powerstate == 282: 30 | # Changes the power input to "PICO_POWER_SUPPLY_NOT_CONNECTED" 31 | status["ChangePowerSource"] = ps.ps3000aChangePowerSource(chandle, 282) 32 | # If the powerstate is the same as 286 then it will run this if statement 33 | elif powerstate == 286: 34 | # Changes the power input to "PICO_USB3_0_DEVICE_NON_USB3_0_PORT" 35 | status["ChangePowerSource"] = ps.ps3000aChangePowerSource(chandle, 286) 36 | else: 37 | raise 38 | 39 | assert_pico_ok(status["ChangePowerSource"]) 40 | 41 | # Set up channel A 42 | # handle = chandle 43 | # channel = PS3000A_CHANNEL_A = 0 44 | # enabled = 1 45 | # coupling type = PS3000A_DC = 1 46 | # range = PS3000A_10V = 8 47 | # analogue offset = 0 V 48 | chARange = 8 49 | status["setChA"] = ps.ps3000aSetChannel(chandle, 0, 1, 1, chARange, 0) 50 | assert_pico_ok(status["setChA"]) 51 | 52 | # Sets up single trigger 53 | # Handle = Chandle 54 | # Source = ps3000A_channel_B = 0 55 | # Enable = 0 56 | # Threshold = 1024 ADC counts 57 | # Direction = ps3000A_Falling = 3 58 | # Delay = 0 59 | # autoTrigger_ms = 1000 60 | status["trigger"] = ps.ps3000aSetSimpleTrigger(chandle, 1, 0, 1024, 3, 0, 1000) 61 | assert_pico_ok(status["trigger"]) 62 | 63 | # Setting the number of sample to be collected 64 | preTriggerSamples = 40000 65 | postTriggerSamples = 40000 66 | maxsamples = preTriggerSamples + postTriggerSamples 67 | 68 | # Gets timebase innfomation 69 | # WARNING: When using this example it may not be possible to access all Timebases as all channels are enabled by default when opening the scope. 70 | # To access these Timebases, set any unused analogue channels to off. 71 | # Handle = chandle 72 | # Timebase = 2 = timebase 73 | # Nosample = maxsamples 74 | # TimeIntervalNanoseconds = ctypes.byref(timeIntervalns) 75 | # MaxSamples = ctypes.byref(returnedMaxSamples) 76 | # Segement index = 0 77 | timebase = 2 78 | timeIntervalns = ctypes.c_float() 79 | returnedMaxSamples = ctypes.c_int16() 80 | status["GetTimebase"] = ps.ps3000aGetTimebase2(chandle, timebase, maxsamples, ctypes.byref(timeIntervalns), 1, ctypes.byref(returnedMaxSamples), 0) 81 | assert_pico_ok(status["GetTimebase"]) 82 | 83 | # Creates a overlow location for data 84 | overflow = ctypes.c_int16() 85 | # Creates converted types maxsamples 86 | cmaxSamples = ctypes.c_int32(maxsamples) 87 | 88 | # Starts the block capture 89 | # Handle = chandle 90 | # Number of prTriggerSamples 91 | # Number of postTriggerSamples 92 | # Timebase = 2 = 4ns (see Programmer's guide for more information on timebases) 93 | # time indisposed ms = None (This is not needed within the example) 94 | # Segment index = 0 95 | # LpRead = None 96 | # pParameter = None 97 | status["runblock"] = ps.ps3000aRunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, 1, None, 0, None, None) 98 | assert_pico_ok(status["runblock"]) 99 | 100 | # Create buffers ready for assigning pointers for data collection 101 | bufferAMax = (ctypes.c_int16 * maxsamples)() 102 | bufferAMin = (ctypes.c_int16 * maxsamples)() # used for downsampling which isn't in the scope of this example 103 | 104 | # Setting the data buffer location for data collection from channel A 105 | # Handle = Chandle 106 | # source = ps3000A_channel_A = 0 107 | # Buffer max = ctypes.byref(bufferAMax) 108 | # Buffer min = ctypes.byref(bufferAMin) 109 | # Buffer length = maxsamples 110 | # Segment index = 0 111 | # Ratio mode = ps3000A_Ratio_Mode_None = 0 112 | status["SetDataBuffers"] = ps.ps3000aSetDataBuffers(chandle, 0, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxsamples, 0, 0) 113 | assert_pico_ok(status["SetDataBuffers"]) 114 | 115 | # Creates a overlow location for data 116 | overflow = (ctypes.c_int16 * 10)() 117 | # Creates converted types maxsamples 118 | cmaxSamples = ctypes.c_int32(maxsamples) 119 | 120 | # Checks data collection to finish the capture 121 | ready = ctypes.c_int16(0) 122 | check = ctypes.c_int16(0) 123 | while ready.value == check.value: 124 | status["isReady"] = ps.ps3000aIsReady(chandle, ctypes.byref(ready)) 125 | 126 | # Handle = chandle 127 | # start index = 0 128 | # noOfSamples = ctypes.byref(cmaxSamples) 129 | # DownSampleRatio = 0 130 | # DownSampleRatioMode = 0 131 | # SegmentIndex = 0 132 | # Overflow = ctypes.byref(overflow) 133 | 134 | status["GetValues"] = ps.ps3000aGetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow)) 135 | assert_pico_ok(status["GetValues"]) 136 | 137 | # Finds the max ADC count 138 | # Handle = chandle 139 | # Value = ctype.byref(maxADC) 140 | maxADC = ctypes.c_int16() 141 | status["maximumValue"] = ps.ps3000aMaximumValue(chandle, ctypes.byref(maxADC)) 142 | assert_pico_ok(status["maximumValue"]) 143 | 144 | # Converts ADC from channel A to mV 145 | adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC) 146 | 147 | # Creates the time data 148 | time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value) 149 | 150 | # Plots the data from channel A onto a graph 151 | plt.plot(time, adc2mVChAMax[:]) 152 | plt.xlabel('Time (ns)') 153 | plt.ylabel('Voltage (mV)') 154 | plt.show() 155 | 156 | # Stops the scope 157 | # Handle = chandle 158 | status["stop"] = ps.ps3000aStop(chandle) 159 | assert_pico_ok(status["stop"]) 160 | 161 | # Closes the unit 162 | # Handle = chandle 163 | status["close"] = ps.ps3000aCloseUnit(chandle) 164 | assert_pico_ok(status["close"]) 165 | 166 | # Displays the staus returns 167 | print(status) 168 | 169 | -------------------------------------------------------------------------------- /ps3000aExamples/ps3000aSigGen.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PicoScope 3000 (A API) Series Signal Generator Example 5 | # This example demonstrates how to use the PicoScope 3000 Series (ps3000a) driver API functions to set up the signal generator to do the following: 6 | # 7 | # 1. Output a sine wave 8 | # 2. Output a square wave 9 | # 3. Output a sweep of a square wave signal 10 | 11 | import ctypes 12 | from picosdk.ps3000a import ps3000a as ps 13 | import time 14 | from picosdk.functions import assert_pico_ok 15 | 16 | 17 | # Gives the device a handle 18 | status = {} 19 | chandle = ctypes.c_int16() 20 | 21 | # Opens the device/s 22 | status["openunit"] = ps.ps3000aOpenUnit(ctypes.byref(chandle), None) 23 | 24 | try: 25 | assert_pico_ok(status["openunit"]) 26 | except: 27 | 28 | # powerstate becomes the status number of openunit 29 | powerstate = status["openunit"] 30 | 31 | # If powerstate is the same as 282 then it will run this if statement 32 | if powerstate == 282: 33 | # Changes the power input to "PICO_POWER_SUPPLY_NOT_CONNECTED" 34 | status["ChangePowerSource"] = ps.ps3000aChangePowerSource(chandle, 282) 35 | # If the powerstate is the same as 286 then it will run this if statement 36 | elif powerstate == 286: 37 | # Changes the power input to "PICO_USB3_0_DEVICE_NON_USB3_0_PORT" 38 | status["ChangePowerSource"] = ps.ps3000aChangePowerSource(chandle, 286) 39 | else: 40 | raise 41 | 42 | assert_pico_ok(status["ChangePowerSource"]) 43 | 44 | # Output a sine wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 45 | # handle = chandle 46 | # offsetVoltage = 0 47 | # pkToPk = 2000000 48 | # waveType = ctypes.c_int16(0) = PS3000A_SINE 49 | # startFrequency = 10000 Hz 50 | # stopFrequency = 10000 Hz 51 | # increment = 0 52 | # dwellTime = 1 53 | # sweepType = ctypes.c_int16(1) = PS3000A_UP 54 | # operation = 0 55 | # shots = 0 56 | # sweeps = 0 57 | # triggerType = ctypes.c_int16(0) = PS3000A_SIGGEN_RISING 58 | # triggerSource = ctypes.c_int16(0) = P3000A_SIGGEN_NONE 59 | # extInThreshold = 1 60 | wavetype = ctypes.c_int16(0) 61 | sweepType = ctypes.c_int32(0) 62 | triggertype = ctypes.c_int32(0) 63 | triggerSource = ctypes.c_int32(0) 64 | 65 | status["SetSigGenBuiltIn"] = ps.ps3000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 66 | assert_pico_ok(status["SetSigGenBuiltIn"]) 67 | 68 | # Pauses the script to show signal 69 | time.sleep(10) 70 | 71 | # Output a square wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 72 | # handle = chandle 73 | # offsetVoltage = -1000000 74 | # pkToPk = 1500000 75 | # waveType = ctypes.c_int16(1) = PS3000A_SQUARE 76 | # startFrequency = 10 kHz 77 | # stopFrequency = 10 kHz 78 | # increment = 0 79 | # dwellTime = 1 80 | # sweepType = ctypes.c_int16(1) = PS3000A_UP 81 | # operation = 0 82 | # shots = 0 83 | # sweeps = 0 84 | # triggerType = ctypes.c_int16(0) = PS3000A_SIGGEN_RISING 85 | # triggerSource = ctypes.c_int16(0) = P3000A_SIGGEN_NONE 86 | # extInThreshold = 1 87 | wavetype = ctypes.c_int16(1) 88 | sweepType = ctypes.c_int32(0) 89 | triggertype = ctypes.c_int32(0) 90 | triggerSource = ctypes.c_int32(0) 91 | 92 | status["SetSigGenBuiltIn"] = ps.ps3000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 93 | assert_pico_ok(status["SetSigGenBuiltIn"]) 94 | 95 | # Pauses the script to show signal 96 | time.sleep(10) 97 | 98 | # Output a square wave with an up-down sweep, 10-100 kHz in 5 kHz increments every 1 second. 99 | # handle = chandle 100 | # offsetVoltage = -1000000 101 | # pkToPk = 1500000 102 | # waveType = ctypes.c_int16(1) = PS3000A_Square 103 | # startFrequency = 100 kHz 104 | # stopFrequency = 100 kHz 105 | # increment = 5 kHz 106 | # dwellTime = 1 107 | # sweepType = ctypes.c_int16(1) = PS3000A_UP 108 | # operation = 0 109 | # shots = 0 110 | # sweeps = 0 111 | # triggerType = ctypes.c_int16(0) = PS3000A_SIGGEN_RISING 112 | # triggerSource = ctypes.c_int16(0) = P3000A_SIGGEN_NONE 113 | # extInThreshold = 1 114 | wavetype = ctypes.c_int16(1) 115 | sweepType = ctypes.c_int32(2) 116 | triggertype = ctypes.c_int32(0) 117 | triggerSource = ctypes.c_int32(0) 118 | 119 | status["SetSigGenBuiltIn"] = ps.ps3000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 100000, 5000, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 120 | assert_pico_ok(status["SetSigGenBuiltIn"]) 121 | 122 | # Pauses the script to show signal 123 | time.sleep(36) 124 | 125 | # Closes the unit 126 | # Handle = chandle 127 | status["close"] = ps.ps3000aCloseUnit(chandle) 128 | assert_pico_ok(status["close"]) 129 | 130 | # Displays the status returns 131 | print(status) 132 | -------------------------------------------------------------------------------- /ps4000Examples/ps4000BlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS4000 BLOCK MODE EXAMPLE 5 | # This example opens a 4000 driver device, sets up two channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.ps4000 import ps4000 as ps 11 | import matplotlib.pyplot as plt 12 | from picosdk.functions import adc2mV, assert_pico_ok 13 | 14 | # Create chandle and status ready for use 15 | chandle = ctypes.c_int16() 16 | status = {} 17 | 18 | # Open 5000 series PicoScope 19 | # Returns handle to chandle for use in future API functions 20 | status["openunit"] = ps.ps4000OpenUnit(ctypes.byref(chandle)) 21 | assert_pico_ok(status["openunit"]) 22 | 23 | # Set up channel A 24 | # handle = chandle 25 | # channel = PS4000_CHANNEL_A = 0 26 | # enabled = 1 27 | # coupling type = PS4000_DC = 1 28 | # range = PS4000_2V = 7 29 | chARange = 7 30 | status["setChA"] = ps.ps4000SetChannel(chandle, 0, 1, 1, chARange) 31 | assert_pico_ok(status["setChA"]) 32 | 33 | # Set up channel B 34 | # handle = chandle 35 | # channel = PS4000_CHANNEL_B = 1 36 | # enabled = 1 37 | # coupling type = PS4000_DC = 1 38 | # range = PS4000_2V = 7 39 | chBRange = 7 40 | status["setChB"] = ps.ps4000SetChannel(chandle, 1, 1, 1, chBRange) 41 | assert_pico_ok(status["setChB"]) 42 | 43 | # setbandwidth filter A 44 | 45 | status["setBW"] = ps.ps4000SetBwFilter(chandle, 0, 1) 46 | 47 | # Set up single trigger 48 | # handle = chandle 49 | # enabled = 1 50 | # source = PS4000_CHANNEL_A = 0 51 | # threshold = 1024 ADC counts 52 | # direction = PS4000_RISING = 2 53 | # delay = 0 s 54 | # auto Trigger = 1000 ms 55 | status["trigger"] = ps.ps4000SetSimpleTrigger(chandle, 1, 0, 1024, 2, 0, 1000) 56 | assert_pico_ok(status["trigger"]) 57 | 58 | # Set number of pre and post trigger samples to be collected 59 | preTriggerSamples = 2500 60 | postTriggerSamples = 2500 61 | maxSamples = preTriggerSamples + postTriggerSamples 62 | 63 | # Get timebase information 64 | # Warning: When using this example it may not be possible to access all Timebases as all channels are enabled by default when opening the scope. 65 | # To access these Timebases, set any unused analogue channels to off. 66 | # handle = chandle 67 | # timebase = 8 = timebase 68 | # noSamples = maxSamples 69 | # pointer to timeIntervalNanoseconds = ctypes.byref(timeIntervalns) 70 | # pointer to maxSamples = ctypes.byref(returnedMaxSamples) 71 | # segment index = 0 72 | timebase = 8 73 | timeIntervalns = ctypes.c_float() 74 | returnedMaxSamples = ctypes.c_int32() 75 | oversample = ctypes.c_int16(1) 76 | status["getTimebase2"] = ps.ps4000GetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), oversample, ctypes.byref(returnedMaxSamples), 0) 77 | assert_pico_ok(status["getTimebase2"]) 78 | 79 | # Run block capture 80 | # handle = chandle 81 | # number of pre-trigger samples = preTriggerSamples 82 | # number of post-trigger samples = PostTriggerSamples 83 | # timebase = 8 = 80 ns = timebase (see Programmer's guide for mre information on timebases) 84 | # time indisposed ms = None (not needed in the example) 85 | # segment index = 0 86 | # lpReady = None (using ps4000IsReady rather than ps4000BlockReady) 87 | # pParameter = None 88 | status["runBlock"] = ps.ps4000RunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, oversample, None, 0, None, None) 89 | assert_pico_ok(status["runBlock"]) 90 | 91 | # Check for data collection to finish using ps4000IsReady 92 | ready = ctypes.c_int16(0) 93 | check = ctypes.c_int16(0) 94 | while ready.value == check.value: 95 | status["isReady"] = ps.ps4000IsReady(chandle, ctypes.byref(ready)) 96 | 97 | # Create buffers ready for assigning pointers for data collection 98 | bufferAMax = (ctypes.c_int16 * maxSamples)() 99 | bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example 100 | bufferBMax = (ctypes.c_int16 * maxSamples)() 101 | bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example 102 | 103 | # Set data buffer location for data collection from channel A 104 | # handle = chandle 105 | # source = PS4000_CHANNEL_A = 0 106 | # pointer to buffer max = ctypes.byref(bufferAMax) 107 | # pointer to buffer min = ctypes.byref(bufferAMin) 108 | # buffer length = maxSamples 109 | status["setDataBuffersA"] = ps.ps4000SetDataBuffers(chandle, 0, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples) 110 | assert_pico_ok(status["setDataBuffersA"]) 111 | 112 | # Set data buffer location for data collection from channel B 113 | # handle = chandle 114 | # source = PS4000_CHANNEL_B = 1 115 | # pointer to buffer max = ctypes.byref(bufferBMax) 116 | # pointer to buffer min = ctypes.byref(bufferBMin) 117 | # buffer length = maxSamples 118 | status["setDataBuffersB"] = ps.ps4000SetDataBuffers(chandle, 1, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples) 119 | assert_pico_ok(status["setDataBuffersB"]) 120 | 121 | # create overflow loaction 122 | overflow = ctypes.c_int16() 123 | # create converted type maxSamples 124 | cmaxSamples = ctypes.c_int32(maxSamples) 125 | 126 | # Retried data from scope to buffers assigned above 127 | # handle = chandle 128 | # start index = 0 129 | # pointer to number of samples = ctypes.byref(cmaxSamples) 130 | # downsample ratio = 0 131 | # downsample ratio mode = PS4000_RATIO_MODE_NONE 132 | # pointer to overflow = ctypes.byref(overflow)) 133 | status["getValues"] = ps.ps4000GetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow)) 134 | assert_pico_ok(status["getValues"]) 135 | 136 | 137 | # find maximum ADC count value 138 | # handle = chandle 139 | # pointer to value = ctypes.byref(maxADC) 140 | maxADC = ctypes.c_int16(32767) 141 | 142 | # convert ADC counts data to mV 143 | adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC) 144 | adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC) 145 | 146 | # Create time data 147 | time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value) 148 | 149 | # plot data from channel A and B 150 | plt.plot(time, adc2mVChAMax[:]) 151 | plt.plot(time, adc2mVChBMax[:]) 152 | plt.xlabel('Time (ns)') 153 | plt.ylabel('Voltage (mV)') 154 | plt.show() 155 | 156 | # Stop the scope 157 | # handle = chandle 158 | status["stop"] = ps.ps4000Stop(chandle) 159 | assert_pico_ok(status["stop"]) 160 | 161 | # Close unit Disconnect the scope 162 | # handle = chandle 163 | status["close"] = ps.ps4000CloseUnit(chandle) 164 | assert_pico_ok(status["close"]) 165 | 166 | # display status returns 167 | print(status) -------------------------------------------------------------------------------- /ps4000aExamples/ps4000aSigGen.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PicoScope 4000 (A API) Series Signal Generator Example 5 | # This example demonstrates how to use the PicoScope 4000 Series (ps4000a) driver API functions to set up the signal generator to do the following: 6 | # 7 | # 1. Output a sine wave 8 | # 2. Output a square wave 9 | # 3. Output a sweep of a square wave signal 10 | 11 | import ctypes 12 | from picosdk.ps4000a import ps4000a as ps 13 | import time 14 | from picosdk.functions import assert_pico_ok 15 | 16 | 17 | # Gives the device a handle 18 | status = {} 19 | chandle = ctypes.c_int16() 20 | 21 | # Opens the device/s 22 | status["openunit"] = ps.ps4000aOpenUnit(ctypes.byref(chandle), None) 23 | 24 | try: 25 | assert_pico_ok(status["openunit"]) 26 | except: 27 | # powerstate becomes the status number of openunit 28 | powerstate = status["openunit"] 29 | 30 | # If powerstate is the same as 282 then it will run this if statement 31 | if powerstate == 282: 32 | # Changes the power input to "PICO_POWER_SUPPLY_NOT_CONNECTED" 33 | status["ChangePowerSource"] = ps.ps4000aChangePowerSource(chandle, 282) 34 | # If the powerstate is the same as 286 then it will run this if statement 35 | elif powerstate == 286: 36 | # Changes the power input to "PICO_USB3_0_DEVICE_NON_USB3_0_PORT" 37 | status["ChangePowerSource"] = ps.ps4000aChangePowerSource(chandle, 286) 38 | else: 39 | raise 40 | 41 | assert_pico_ok(status["ChangePowerSource"]) 42 | 43 | # Output a sine wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 44 | # handle = chandle 45 | # offsetVoltage = 0 46 | # pkToPk = 2000000 47 | # waveType = ctypes.c_int16(0) = PS4000A_SINE 48 | # startFrequency = 10 kHz 49 | # stopFrequency = 10 kHz 50 | # increment = 0 51 | # dwellTime = 1 52 | # sweepType = ctypes.c_int32(0) = PS4000A_UP 53 | # operation = 0 54 | # shots = 0 55 | # sweeps = 0 56 | # triggerType = ctypes.c_int16(0) = PS4000A_SIGGEN_RISING 57 | # triggerSource = ctypes.c_int16(0) = PS4000A_SIGGEN_NONE 58 | # extInThreshold = 0 59 | wavetype = ps.PS4000A_WAVE_TYPE['PS4000A_SINE'] 60 | sweepType = ps.PS4000A_SWEEP_TYPE['PS4000A_UP'] 61 | triggertype = ps.PS4000A_SIGGEN_TRIG_TYPE['PS4000A_SIGGEN_RISING'] 62 | triggerSource = ps.PS4000A_SIGGEN_TRIG_SOURCE['PS4000A_SIGGEN_NONE'] 63 | extInThreshold = ctypes.c_int16(0) #extInThreshold - Not used 64 | 65 | status["SetSigGenBuiltIn"] = ps.ps4000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, extInThreshold) 66 | assert_pico_ok(status["SetSigGenBuiltIn"]) 67 | 68 | # Pauses the script to show signal 69 | time.sleep(10) 70 | 71 | # Output a square wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 72 | # handle = chandle 73 | # offsetVoltage = 0 74 | # pkToPk = 2000000 75 | # waveType = ctypes.c_int16(1) = PS4000A_SQUARE 76 | # startFrequency = 10 kHz 77 | # stopFrequency = 10 kHz 78 | # increment = 0 79 | # dwellTime = 1 80 | # sweepType = ctypes.c_int32(0) = PS4000A_UP 81 | # operation = 0 82 | # shots = 0 83 | # sweeps = 0 84 | # triggerType = ctypes.c_int16(0) = PS4000A_SIGGEN_RISING 85 | # triggerSource = ctypes.c_int16(0) = PS4000A_SIGGEN_NONE 86 | # extInThreshold = 0 87 | wavetype = ps.PS4000A_WAVE_TYPE['PS4000A_SQUARE'] 88 | sweepType = ps.PS4000A_SWEEP_TYPE['PS4000A_UP'] 89 | triggertype = ps.PS4000A_SIGGEN_TRIG_TYPE['PS4000A_SIGGEN_RISING'] 90 | triggerSource = ps.PS4000A_SIGGEN_TRIG_SOURCE['PS4000A_SIGGEN_NONE'] 91 | extInThreshold = ctypes.c_int16(0) #extInThreshold - Not used 92 | 93 | status["SetSigGenBuiltIn"] = ps.ps4000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, extInThreshold) 94 | assert_pico_ok(status["SetSigGenBuiltIn"]) 95 | 96 | # pauses the script to show signal 97 | time.sleep(10) 98 | 99 | # Output square wave with an up-down sweep, ranging from 10-100 kHz in 5 kHz increments every 1 second. 100 | # handle = chandle 101 | # offsetVoltage = 0 102 | # pkToPk = 2000000 103 | # waveType = ctypes.c_int16(1) = PS4000A_SQUARE 104 | # startFrequency = 10 kHz 105 | # stopFrequency = 100 kHz 106 | # increment = 5 kHz 107 | # dwellTime = 1 108 | # sweepType = ctypes.c_int32(2) = PS4000A_UPDOWN 109 | # operation = 0 110 | # shots = 0 111 | # sweeps = 0 112 | # triggerType = ctypes.c_int16(0) = PS4000A_SIGGEN_RISING 113 | # triggerSource = ctypes.c_int16(0) = PS4000A_SIGGEN_NONE 114 | # extInThreshold = 0 115 | wavetype = ps.PS4000A_WAVE_TYPE['PS4000A_SQUARE'] 116 | sweepType = ps.PS4000A_SWEEP_TYPE['PS4000A_UPDOWN'] 117 | triggertype = ps.PS4000A_SIGGEN_TRIG_TYPE['PS4000A_SIGGEN_RISING'] 118 | triggerSource = ps.PS4000A_SIGGEN_TRIG_SOURCE['PS4000A_SIGGEN_NONE'] 119 | extInThreshold = ctypes.c_int16(0) #extInThreshold - Not used 120 | 121 | status["SetSigGenBuiltIn"] = ps.ps4000aSetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 100000, 5000, 1, sweepType, 0, 0, 0, triggertype, triggerSource, extInThreshold) 122 | assert_pico_ok(status["SetSigGenBuiltIn"]) 123 | 124 | # Pauses the script to show signal 125 | time.sleep(36) 126 | 127 | # Closes the unit 128 | # Handle = chandle 129 | status["close"] = ps.ps4000aCloseUnit(chandle) 130 | assert_pico_ok(status["close"]) 131 | 132 | # Displays the status returns 133 | print(status) 134 | -------------------------------------------------------------------------------- /ps5000aExamples/ps5000aSigGen.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018-2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PicoScope 5000 (A API) Signal Generator Example 5 | # This example demonstrates how to use the PicoScope 5000 Series (ps5000a) driver API functions to set up the signal generator to do the following: 6 | # 7 | # 1. Output a sine wave 8 | # 2. Output a square wave 9 | # 3. Output a sweep of a square wave signal 10 | 11 | import ctypes 12 | from picosdk.ps5000a import ps5000a as ps 13 | import time 14 | from picosdk.functions import assert_pico_ok 15 | import numpy as np 16 | import math 17 | import matplotlib.pyplot as plt 18 | 19 | 20 | status = {} 21 | chandle = ctypes.c_int16() 22 | 23 | # Open the device 24 | status["openUnit"] = ps.ps5000aOpenUnit(ctypes.byref(chandle), None, 1) 25 | 26 | 27 | try: 28 | assert_pico_ok(status["openUnit"]) 29 | except: # PicoNotOkError: 30 | 31 | powerStatus = status["openUnit"] 32 | 33 | if powerStatus == 286: 34 | status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus) 35 | elif powerStatus == 282: 36 | status["changePowerSource"] = ps.ps5000aChangePowerSource(chandle, powerStatus) 37 | else: 38 | raise 39 | 40 | assert_pico_ok(status["changePowerSource"]) 41 | 42 | # Output a sine wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 43 | # handle = chandle 44 | # offsetVoltage = 0 45 | # pkToPk = 2000000 46 | # waveType = ctypes.c_int16(0) = PS5000A_SINE 47 | # startFrequency = 10 kHz 48 | # stopFrequency = 10 kHz 49 | # increment = 0 50 | # dwellTime = 1 51 | # sweepType = ctypes.c_int16(1) = PS5000A_UP 52 | # operation = 0 53 | # shots = 0 54 | # sweeps = 0 55 | # triggerType = ctypes.c_int16(0) = PS5000a_SIGGEN_RISING 56 | # triggerSource = ctypes.c_int16(0) = P5000a_SIGGEN_NONE 57 | # extInThreshold = 1 58 | wavetype = ctypes.c_int32(0) 59 | sweepType = ctypes.c_int32(0) 60 | triggertype = ctypes.c_int32(0) 61 | triggerSource = ctypes.c_int32(0) 62 | 63 | status["setSigGenBuiltInV2"] = ps.ps5000aSetSigGenBuiltInV2(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 0) 64 | assert_pico_ok(status["setSigGenBuiltInV2"]) 65 | 66 | 67 | # Pauses the script to show signal 68 | time.sleep(10) 69 | 70 | # Output a square wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 71 | # handle = chandle 72 | # offsetVoltage = -1000000 73 | # pkToPk = 1500000 74 | # waveType = ctypes.c_int16(1) = PS5000A_SQUARE 75 | # startFrequency = 10 kHz 76 | # stopFrequency = 10 kHz 77 | # increment = 0 78 | # dwellTime = 1 79 | # sweepType = ctypes.c_int16(1) = PS5000A_UP 80 | # operation = 0 81 | # shots = 0 82 | # sweeps = 0 83 | # triggerType = ctypes.c_int16(0) = PS5000A_SIGGEN_RISING 84 | # triggerSource = ctypes.c_int16(0) = PS5000A_SIGGEN_NONE 85 | # extInThreshold = 0 86 | wavetype = ctypes.c_int32(1) 87 | sweepType = ctypes.c_int32(0) 88 | triggertype = ctypes.c_int32(0) 89 | triggerSource = ctypes.c_int32(0) 90 | 91 | status["setSigGenBuiltInV2"] = ps.ps5000aSetSigGenBuiltInV2(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 0) 92 | assert_pico_ok(status["setSigGenBuiltInV2"]) 93 | 94 | # Pauses the script to show signal 95 | time.sleep(10) 96 | 97 | # Output a square wave with an up-down sweep, 10-100 kHz in 5 kHz increments every 1 second. 98 | # handle = chandle 99 | # offsetVoltage = -1000000 100 | # pkToPk = 1500000 101 | # waveType = ctypes.c_int16(1) = PS5000A_SQUARE 102 | # startFrequency = 10 kHz 103 | # stopFrequency = 100 kHz 104 | # increment = 5 kHz 105 | # dwellTime = 1 106 | # sweepType = ctypes.c_int16(1) = PS5000A_UP 107 | # operation = 0 108 | # shots = 0 109 | # sweeps = 0 110 | # triggerType = ctypes.c_int16(0) = PS5000A_SIGGEN_RISING 111 | # triggerSource = ctypes.c_int16(0) = PS5000A_SIGGEN_NONE 112 | # extInThreshold = 0 113 | wavetype = ctypes.c_int32(1) 114 | sweepType = ctypes.c_int32(2) 115 | triggertype = ctypes.c_int32(0) 116 | triggerSource = ctypes.c_int32(0) 117 | 118 | status["setSigGenBuiltInV2"] = ps.ps5000aSetSigGenBuiltInV2(chandle, 0, 2000000, wavetype, 10000, 100000, 5000, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 0) 119 | assert_pico_ok(status["setSigGenBuiltInV2"]) 120 | 121 | # Pauses the script to show signal 122 | time.sleep(6) 123 | 124 | # create a custom waveform 125 | minValue = ctypes.c_int16(0) 126 | maxValue = ctypes.c_int16(0) 127 | minSize = ctypes.c_int16(0) 128 | maxSize = ctypes.c_int16(0) 129 | status["sigGenArbMinMax"] = ps.ps5000aSigGenArbitraryMinMaxValues(chandle, ctypes.byref(minValue), ctypes.byref(maxValue),ctypes.byref(minSize),ctypes.byref(maxSize)) 130 | assert_pico_ok(status["sigGenArbMinMax"]) 131 | 132 | awgBuffer = (np.sin(np.linspace(0,2*math.pi,10000)))*maxValue.value 133 | awgBuffer = awgBuffer.astype(ctypes.c_int16) 134 | awgbufferPointer = awgBuffer.ctypes.data_as(ctypes.POINTER(ctypes.c_int16)) 135 | 136 | 137 | 138 | # convert 10 KHZ frequency to phase 139 | freq = 10000 140 | indexMode = 0 141 | bufferLength = len(awgBuffer) 142 | phase = ctypes.c_int16(0) 143 | status["freqToPhase"] = ps.ps5000aSigGenFrequencyToPhase(chandle, freq, indexMode, bufferLength, ctypes.byref(phase)) 144 | assert_pico_ok(status["freqToPhase"]) 145 | 146 | # output custom waveform with peak-to-peak of 2 V and frequency of 10 kHz 147 | # handle = chandle 148 | # offsetVoltage = 0 149 | # pkToPk = 2000000 150 | # startDeltaPhase = phase 151 | # stopDeltaPhase = phase 152 | # deltaPhaseIncrement = 0 153 | # dwellCount = 0 154 | # *arbitaryWaveform = awgbufferPointer 155 | # arbitaryWaveformSize = 1024 156 | # sweepType = ctypes.c_int32(0) 157 | # operation = 0 158 | # shots = 0 159 | # sweeps = 0 160 | # triggerType = ctypes.c_int16(0) = PS5000A_SIGGEN_RISING 161 | # triggerSource = ctypes.c_int16(0) = PS5000A_SIGGEN_NONE 162 | # extInThreshold = 0 163 | 164 | status["setSigGenArbitrary"] = ps.ps5000aSetSigGenArbitrary(chandle, 0, 3600000, phase.value, phase.value, 0, 0, awgbufferPointer, bufferLength, 0, 0, 0, 0, 0, 0, 0, 0) 165 | assert_pico_ok(status["setSigGenArbitrary"]) 166 | 167 | # Pauses the script to show signal 168 | time.sleep(10) 169 | 170 | # Closes the unit 171 | # Handle = chandle 172 | status["close"] = ps.ps5000aCloseUnit(chandle) 173 | assert_pico_ok(status["close"]) 174 | 175 | # Displays the status returns 176 | print(status) -------------------------------------------------------------------------------- /ps6000Examples/ps6000BlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018-2022 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS6000 BLOCK MODE EXAMPLE 5 | # This example opens a 6000 driver device, sets up two channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.ps6000 import ps6000 as ps 11 | import matplotlib.pyplot as plt 12 | from picosdk.functions import adc2mV, assert_pico_ok 13 | 14 | # Create chandle and status ready for use 15 | chandle = ctypes.c_int16() 16 | status = {} 17 | 18 | # Open 6000 series PicoScope 19 | # Returns handle to chandle for use in future API functions 20 | status["openunit"] = ps.ps6000OpenUnit(ctypes.byref(chandle), None) 21 | assert_pico_ok(status["openunit"]) 22 | 23 | # Set up channel A 24 | # handle = chandle 25 | # channel = PS6000_CHANNEL_A = 0 26 | # enabled = 1 27 | # coupling type = PS6000_DC = 1 28 | # range = PS6000_2V = 7 29 | # analogue offset = 0 V 30 | # bandwidth limiter = PS6000_BW_FULL = 0 31 | chARange = 7 32 | status["setChA"] = ps.ps6000SetChannel(chandle, 0, 1, 1, chARange, 0, 0) 33 | assert_pico_ok(status["setChA"]) 34 | 35 | # Set up channel B 36 | # handle = chandle 37 | # channel = PS6000_CHANNEL_B = 1 38 | # enabled = 1 39 | # coupling type = PS6000_DC = 1 40 | # range = PS6000_2V = 7 41 | # analogue offset = 0 V 42 | # bandwidth limiter = PS6000_BW_FULL = 0 43 | chBRange = 7 44 | status["setChB"] = ps.ps6000SetChannel(chandle, 1, 1, 1, chBRange, 0, 0) 45 | assert_pico_ok(status["setChB"]) 46 | 47 | # Set up single trigger 48 | # handle = chandle 49 | # enabled = 1 50 | # source = PS6000_CHANNEL_A = 0 51 | # threshold = 64 ADC counts 52 | # direction = PS6000_RISING = 2 53 | # delay = 0 s 54 | # auto Trigger = 1000 ms 55 | status["trigger"] = ps.ps6000SetSimpleTrigger(chandle, 1, 0, 64, 2, 0, 1000) 56 | assert_pico_ok(status["trigger"]) 57 | 58 | # Set number of pre and post trigger samples to be collected 59 | preTriggerSamples = 2500 60 | postTriggerSamples = 2500 61 | maxSamples = preTriggerSamples + postTriggerSamples 62 | 63 | # Get timebase information 64 | # Warning: When using this example it may not be possible to access all Timebases as all channels are enabled by default when opening the scope. 65 | # To access these Timebases, set any unused analogue channels to off. 66 | # handle = chandle 67 | # timebase = 8 = timebase 68 | # noSamples = maxSamples 69 | # pointer to timeIntervalNanoseconds = ctypes.byref(timeIntervalns) 70 | # oversample = 1 71 | # pointer to maxSamples = ctypes.byref(returnedMaxSamples) 72 | # segment index = 0 73 | timebase = 8 74 | timeIntervalns = ctypes.c_float() 75 | returnedMaxSamples = ctypes.c_int32() 76 | status["getTimebase2"] = ps.ps6000GetTimebase2(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), 1, ctypes.byref(returnedMaxSamples), 0) 77 | assert_pico_ok(status["getTimebase2"]) 78 | 79 | # Run block capture 80 | # handle = chandle 81 | # number of pre-trigger samples = preTriggerSamples 82 | # number of post-trigger samples = PostTriggerSamples 83 | # timebase = 8 = 80 ns (see Programmer's guide for mre information on timebases) 84 | # oversample = 0 85 | # time indisposed ms = None (not needed in the example) 86 | # segment index = 0 87 | # lpReady = None (using ps6000IsReady rather than ps6000BlockReady) 88 | # pParameter = None 89 | status["runBlock"] = ps.ps6000RunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, 0, None, 0, None, None) 90 | assert_pico_ok(status["runBlock"]) 91 | 92 | # Check for data collection to finish using ps6000IsReady 93 | ready = ctypes.c_int16(0) 94 | check = ctypes.c_int16(0) 95 | while ready.value == check.value: 96 | status["isReady"] = ps.ps6000IsReady(chandle, ctypes.byref(ready)) 97 | 98 | # Create buffers ready for assigning pointers for data collection 99 | bufferAMax = (ctypes.c_int16 * maxSamples)() 100 | bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example 101 | bufferBMax = (ctypes.c_int16 * maxSamples)() 102 | bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example 103 | 104 | # Set data buffer location for data collection from channel A 105 | # handle = chandle 106 | # source = PS6000_CHANNEL_A = 0 107 | # pointer to buffer max = ctypes.byref(bufferAMax) 108 | # pointer to buffer min = ctypes.byref(bufferAMin) 109 | # buffer length = maxSamples 110 | # ratio mode = PS6000_RATIO_MODE_NONE = 0 111 | status["setDataBuffersA"] = ps.ps6000SetDataBuffers(chandle, 0, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples, 0) 112 | assert_pico_ok(status["setDataBuffersA"]) 113 | 114 | # Set data buffer location for data collection from channel B 115 | # handle = chandle 116 | # source = PS6000_CHANNEL_B = 1 117 | # pointer to buffer max = ctypes.byref(bufferBMax) 118 | # pointer to buffer min = ctypes.byref(bufferBMin) 119 | # buffer length = maxSamples 120 | # ratio mode = PS6000_RATIO_MODE_NONE = 0 121 | status["setDataBuffersB"] = ps.ps6000SetDataBuffers(chandle, 1, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples, 0) 122 | assert_pico_ok(status["setDataBuffersB"]) 123 | 124 | # create overflow loaction 125 | overflow = ctypes.c_int16() 126 | # create converted type maxSamples 127 | cmaxSamples = ctypes.c_int32(maxSamples) 128 | 129 | # Retried data from scope to buffers assigned above 130 | # handle = chandle 131 | # start index = 0 132 | # pointer to number of samples = ctypes.byref(cmaxSamples) 133 | # downsample ratio = 1 134 | # downsample ratio mode = PS6000_RATIO_MODE_NONE 135 | # pointer to overflow = ctypes.byref(overflow)) 136 | status["getValues"] = ps.ps6000GetValues(chandle, 0, ctypes.byref(cmaxSamples), 1, 0, 0, ctypes.byref(overflow)) 137 | assert_pico_ok(status["getValues"]) 138 | 139 | # find maximum ADC count value 140 | maxADC = ctypes.c_int16(32512) 141 | 142 | # convert ADC counts data to mV 143 | adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC) 144 | adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC) 145 | 146 | # Create time data 147 | time = np.linspace(0, (cmaxSamples.value -1) * timeIntervalns.value, cmaxSamples.value) 148 | 149 | # plot data from channel A and B 150 | plt.plot(time, adc2mVChAMax[:]) 151 | plt.plot(time, adc2mVChBMax[:]) 152 | plt.xlabel('Time (ns)') 153 | plt.ylabel('Voltage (mV)') 154 | plt.show() 155 | 156 | status["stop"] = ps.ps6000Stop(chandle) 157 | assert_pico_ok(status["stop"]) 158 | 159 | # Close unitDisconnect the scope 160 | # handle = chandle 161 | ps.ps6000CloseUnit(chandle) 162 | 163 | # display status returns 164 | print(status) -------------------------------------------------------------------------------- /ps6000Examples/ps6000GetInfoExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS6000 GET INFO EXAMPLE 5 | # This example opens a 6000 driver device, gets the variant info and closes the scope. 6 | 7 | import ctypes 8 | import numpy as np 9 | from picosdk.ps6000 import ps6000 as ps 10 | import matplotlib.pyplot as plt 11 | from picosdk.functions import adc2mV, assert_pico_ok 12 | 13 | # Create chandle and status ready for use 14 | chandle = ctypes.c_int16() 15 | status = {} 16 | 17 | # Open 6000 series PicoScope 18 | # Returns handle to chandle for use in future API functions 19 | status["openunit"] = ps.ps6000OpenUnit(ctypes.byref(chandle), None) 20 | assert_pico_ok(status["openunit"]) 21 | 22 | # Get Info from scope 23 | string = (ctypes.c_char * 40)() 24 | stringLength = ctypes.c_int16(40) 25 | requiredSize = ctypes.c_int16(40) 26 | info = ps.PICO_INFO["PICO_VARIANT_INFO"] 27 | status["getInfo"] = ps.ps6000GetUnitInfo(chandle, ctypes.byref(string),stringLength, ctypes.byref(requiredSize), info) 28 | assert_pico_ok(status["getInfo"]) 29 | 30 | print(string.value) 31 | 32 | # Close unitDisconnect the scope 33 | # handle = chandle 34 | ps.ps6000CloseUnit(chandle) 35 | 36 | # display status returns 37 | print(status) -------------------------------------------------------------------------------- /ps6000Examples/ps6000SigGen.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PicoScope 6000 Series Signal Generator Example 5 | # This example demonstrates how to use the PicoScope 6000 Series (ps6000) driver API functions to to set up the signal generator to do the following: 6 | # 7 | # 1. Output a sine wave 8 | # 2. Output a square wave 9 | # 3. Output a sweep of a square wave signal 10 | 11 | import ctypes 12 | from picosdk.ps6000 import ps6000 as ps 13 | import time 14 | from picosdk.functions import assert_pico_ok 15 | 16 | 17 | # Gives the device a handle 18 | status = {} 19 | chandle = ctypes.c_int16() 20 | 21 | # Opens the device/s 22 | status["openunit"] = ps.ps6000OpenUnit(ctypes.byref(chandle), None) 23 | assert_pico_ok(status["openunit"]) 24 | 25 | # Output a sine wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 26 | # handle = chandle 27 | # offsetVoltage = 0 28 | # pkToPk = 2000000 29 | # waveType = ctypes.c_int16(0) = PS6000_SINE 30 | # startFrequency = 10 kHz 31 | # stopFrequency = 10 kHz 32 | # increment = 0 33 | # dwellTime = 1 34 | # sweepType = ctypes.c_int16(1) = PS6000_UP 35 | # operation = 0 36 | # shots = 0 37 | # sweeps = 0 38 | # triggerType = ctypes.c_int16(0) = PS6000_SIGGEN_RISING 39 | # triggerSource = ctypes.c_int16(0) = PS6000_SIGGEN_NONE 40 | # extInThreshold = 1 41 | wavetype = ctypes.c_int16(0) 42 | sweepType = ctypes.c_int32(0) 43 | triggertype = ctypes.c_int32(0) 44 | triggerSource = ctypes.c_int32(0) 45 | 46 | status["SetSigGenBuiltIn"] = ps.ps6000SetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 47 | assert_pico_ok(status["SetSigGenBuiltIn"]) 48 | 49 | # Pauses the script to show signal 50 | time.sleep(10) 51 | 52 | # Output a square wave with peak-to-peak voltage of 2 V and frequency of 10 kHz 53 | # handle = chandle 54 | # offsetVoltage = -1000000 55 | # pkToPk = 1500000 56 | # waveType = ctypes.c_int16(1) = PS6000_SQUARE 57 | # startFrequency = 10 kHz 58 | # stopFrequency = 10 kHz 59 | # increment = 0 60 | # dwellTime = 1 61 | # sweepType = ctypes.c_int16(1) = PS6000_UP 62 | # operation = 0 63 | # shots = 0 64 | # sweeps = 0 65 | # triggerType = ctypes.c_int16(0) = PS6000_SIGGEN_RISING 66 | # triggerSource = ctypes.c_int16(0) = PS6000_SIGGEN_NONE 67 | # extInThreshold = 1 68 | wavetype = ctypes.c_int16(1) 69 | sweepType = ctypes.c_int32(0) 70 | triggertype = ctypes.c_int32(0) 71 | triggerSource = ctypes.c_int32(0) 72 | 73 | status["SetSigGenBuiltIn"] = ps.ps6000SetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 10000, 0, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 74 | assert_pico_ok(status["SetSigGenBuiltIn"]) 75 | 76 | # Pauses the script to show signal 77 | time.sleep(10) 78 | 79 | # Output a square wave with an up-down sweep, 10-100 kHz in 5 kHz increments every 1 second. 80 | # handle = chandle 81 | # offsetVoltage = -1000000 82 | # pkToPk = 1500000 83 | # waveType = ctypes.c_int16(1) = PS6000_SQUARE 84 | # startFrequency = 10 kHz 85 | # stopFrequency = 100 kHz 86 | # increment = 5 kHz 87 | # dwellTime = 1 88 | # sweepType = ctypes.c_int16(1) = PS6000_UP 89 | # operation = 0 90 | # shots = 0 91 | # sweeps = 0 92 | # triggerType = ctypes.c_int16(0) = PS6000_SIGGEN_RISING 93 | # triggerSource = ctypes.c_int16(0) = PS6000_SIGGEN_NONE 94 | # extInThreshold = 1 95 | wavetype = ctypes.c_int16(1) 96 | sweepType = ctypes.c_int32(2) 97 | triggertype = ctypes.c_int32(0) 98 | triggerSource = ctypes.c_int32(0) 99 | 100 | status["SetSigGenBuiltIn"] = ps.ps6000SetSigGenBuiltIn(chandle, 0, 2000000, wavetype, 10000, 100000, 5000, 1, sweepType, 0, 0, 0, triggertype, triggerSource, 1) 101 | assert_pico_ok(status["SetSigGenBuiltIn"]) 102 | 103 | # Pauses the script to show signal 104 | time.sleep(36) 105 | 106 | # Closes the unit 107 | # Handle = chandle 108 | status["close"] = ps.ps6000CloseUnit(chandle) 109 | assert_pico_ok(status["close"]) 110 | 111 | # Displays the status returns 112 | print(status) -------------------------------------------------------------------------------- /ps6000aExamples/ps6000aBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020-2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS6000 A BLOCK MODE EXAMPLE 5 | # This example opens a 6000a driver device, sets up two channels and a trigger then collects a block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import numpy as np 10 | from picosdk.ps6000a import ps6000a as ps 11 | from picosdk.PicoDeviceEnums import picoEnum as enums 12 | import matplotlib.pyplot as plt 13 | from picosdk.functions import adc2mV, assert_pico_ok, mV2adc 14 | 15 | # Create chandle and status ready for use 16 | chandle = ctypes.c_int16() 17 | status = {} 18 | 19 | # Open 6000 A series PicoScope 20 | # returns handle to chandle for use in future API functions 21 | resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"] 22 | status["openunit"] = ps.ps6000aOpenUnit(ctypes.byref(chandle), None, resolution) 23 | assert_pico_ok(status["openunit"]) 24 | 25 | # Set channel A on 26 | # handle = chandle 27 | channelA = enums.PICO_CHANNEL["PICO_CHANNEL_A"] 28 | coupling = enums.PICO_COUPLING["PICO_DC_50OHM"] 29 | channelRange = 5 30 | # analogueOffset = 0 V 31 | bandwidth = enums.PICO_BANDWIDTH_LIMITER["PICO_BW_FULL"] 32 | status["setChannelA"] = ps.ps6000aSetChannelOn(chandle, channelA, coupling, channelRange, 0, bandwidth) 33 | assert_pico_ok(status["setChannelA"]) 34 | 35 | # set channel B-H off 36 | for x in range (1, 7, 1): 37 | channel = x 38 | status["setChannel",x] = ps.ps6000aSetChannelOff(chandle,channel) 39 | assert_pico_ok(status["setChannel",x]) 40 | 41 | # get max ADC value 42 | # handle = chandle 43 | minADC = ctypes.c_int16() 44 | maxADC = ctypes.c_int16() 45 | status["getAdcLimits"] = ps.ps6000aGetAdcLimits(chandle, resolution, ctypes.byref(minADC), ctypes.byref(maxADC)) 46 | assert_pico_ok(status["getAdcLimits"]) 47 | 48 | # Set simple trigger on channel A, 1 V rising with 1 s autotrigger 49 | # handle = chandle 50 | # enable = 1 51 | source = channelA 52 | # threshold = 100 mV 53 | direction = enums.PICO_THRESHOLD_DIRECTION["PICO_RISING"] 54 | # delay = 0 s 55 | # autoTriggerMicroSeconds = 1000000 us 56 | status["setSimpleTrigger"] = ps.ps6000aSetSimpleTrigger(chandle, 1, source, (mV2adc(100,channelRange,maxADC)), direction, 0, 1000000) 57 | assert_pico_ok(status["setSimpleTrigger"]) 58 | 59 | # Get fastest available timebase 60 | # handle = chandle 61 | enabledChannelFlags = enums.PICO_CHANNEL_FLAGS["PICO_CHANNEL_A_FLAGS"] 62 | timebase = ctypes.c_uint32(0) 63 | timeInterval = ctypes.c_double(0) 64 | # resolution = resolution 65 | status["getMinimumTimebaseStateless"] = ps.ps6000aGetMinimumTimebaseStateless(chandle, enabledChannelFlags, ctypes.byref(timebase), ctypes.byref(timeInterval), resolution) 66 | print("timebase = ", timebase.value) 67 | print("sample interval =", timeInterval.value, "s") 68 | 69 | # Set number of samples to be collected 70 | noOfPreTriggerSamples = 500000 71 | noOfPostTriggerSamples = 1000000 72 | nSamples = noOfPostTriggerSamples + noOfPreTriggerSamples 73 | 74 | # Create buffers 75 | bufferAMax = (ctypes.c_int16 * nSamples)() 76 | bufferAMin = (ctypes.c_int16 * nSamples)() # used for downsampling which isn't in the scope of this example 77 | 78 | # Set data buffers 79 | # handle = chandle 80 | # channel = channelA 81 | # bufferMax = bufferAMax 82 | # bufferMin = bufferAMin 83 | # nSamples = nSamples 84 | dataType = enums.PICO_DATA_TYPE["PICO_INT16_T"] 85 | waveform = 0 86 | downSampleMode = enums.PICO_RATIO_MODE["PICO_RATIO_MODE_RAW"] 87 | clear = enums.PICO_ACTION["PICO_CLEAR_ALL"] 88 | add = enums.PICO_ACTION["PICO_ADD"] 89 | action = clear|add # PICO_ACTION["PICO_CLEAR_WAVEFORM_CLEAR_ALL"] | PICO_ACTION["PICO_ADD"] 90 | status["setDataBuffers"] = ps.ps6000aSetDataBuffers(chandle, channelA, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), nSamples, dataType, waveform, downSampleMode, action) 91 | assert_pico_ok(status["setDataBuffers"]) 92 | 93 | # Run block capture 94 | # handle = chandle 95 | # timebase = timebase 96 | timeIndisposedMs = ctypes.c_double(0) 97 | # segmentIndex = 0 98 | # lpReady = None Using IsReady rather than a callback 99 | # pParameter = None 100 | status["runBlock"] = ps.ps6000aRunBlock(chandle, noOfPreTriggerSamples, noOfPostTriggerSamples, timebase, ctypes.byref(timeIndisposedMs), 0, None, None) 101 | assert_pico_ok(status["runBlock"]) 102 | 103 | # Check for data collection to finish using ps6000aIsReady 104 | ready = ctypes.c_int16(0) 105 | check = ctypes.c_int16(0) 106 | while ready.value == check.value: 107 | status["isReady"] = ps.ps6000aIsReady(chandle, ctypes.byref(ready)) 108 | 109 | # Get data from scope 110 | # handle = chandle 111 | # startIndex = 0 112 | noOfSamples = ctypes.c_uint64(nSamples) 113 | # downSampleRatio = 1 114 | # segmentIndex = 0 115 | overflow = ctypes.c_int16(0) 116 | status["getValues"] = ps.ps6000aGetValues(chandle, 0, ctypes.byref(noOfSamples), 1, downSampleMode, 0, ctypes.byref(overflow)) 117 | assert_pico_ok(status["getValues"]) 118 | 119 | 120 | 121 | # convert ADC counts data to mV 122 | adc2mVChAMax = adc2mV(bufferAMax, channelRange, maxADC) 123 | 124 | # Create time data 125 | time = np.linspace(0, (nSamples -1) * timeInterval.value * 1000000000, nSamples) 126 | 127 | # plot data from channel A and B 128 | plt.plot(time, adc2mVChAMax[:]) 129 | plt.xlabel('Time (ns)') 130 | plt.ylabel('Voltage (mV)') 131 | plt.show() 132 | 133 | # Close the scope 134 | status["closeunit"] = ps.ps6000aCloseUnit(chandle) 135 | assert_pico_ok(status["closeunit"]) 136 | 137 | print(status) -------------------------------------------------------------------------------- /ps6000aExamples/ps6000aGetUnitInfo.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2024 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS6000 A GET UNIT INFO EXAMPLE 5 | # This example opens a 6000a driver device, collects the model and serial nubmber from the device and closes the device. 6 | 7 | import ctypes 8 | import numpy as np 9 | from picosdk.ps6000a import ps6000a as ps 10 | from picosdk.PicoDeviceEnums import picoEnum as enums 11 | from picosdk.functions import assert_pico_ok 12 | 13 | # Create chandle and status ready for use 14 | chandle = ctypes.c_int16() 15 | status = {} 16 | 17 | # Open 6000 A series PicoScope 18 | # returns handle to chandle for use in future API functions 19 | resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"] 20 | status["openunit"] = ps.ps6000aOpenUnit(ctypes.byref(chandle), None, resolution) 21 | assert_pico_ok(status["openunit"]) 22 | 23 | # Get unit info 24 | modelNum = ctypes.create_string_buffer(6) 25 | modelNumString = ctypes.cast(modelNum,ctypes.c_char_p) 26 | stringLength = len(modelNum) 27 | requiredSize = ctypes.c_int16(stringLength) 28 | infoModel= 0x03 29 | status["getUnitInfo_Model"] = ps.ps6000aGetUnitInfo(chandle, modelNumString,stringLength,ctypes.byref(requiredSize),infoModel) 30 | assert_pico_ok(status["getUnitInfo_Model"]) 31 | print(modelNum.value) 32 | 33 | SN = ctypes.create_string_buffer(b"AA000/0000") 34 | SNString = ctypes.cast(SN,ctypes.c_char_p) 35 | stringLength = len(SN) 36 | requiredSize = ctypes.c_int16(stringLength) 37 | infoSN = 0x04 38 | status["getUnitInfo_SN"] = ps.ps6000aGetUnitInfo(chandle, SNString,stringLength,ctypes.byref(requiredSize),infoSN) 39 | assert_pico_ok(status["getUnitInfo_SN"]) 40 | print(SN.value) 41 | 42 | # Close the scope 43 | status["closeunit"] = ps.ps6000aCloseUnit(chandle) 44 | assert_pico_ok(status["closeunit"]) 45 | 46 | 47 | print(status) -------------------------------------------------------------------------------- /ps6000aExamples/ps6000aSigGenExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PS6000 A SIGNAL GENERATOR EXAMPLE 5 | # This example opens a 6000a driver device, sets up the signal generator to do the following: 6 | # 7 | # 1. Output a sine wave 8 | # 2. Output a square wave 9 | # 3. Output a sweep of a square wave signal 10 | 11 | import ctypes 12 | import numpy as np 13 | from picosdk.ps6000a import ps6000a as ps 14 | from picosdk.PicoDeviceEnums import picoEnum as enums 15 | from picosdk.functions import adc2mV, assert_pico_ok 16 | import time 17 | 18 | # Create chandle and status ready for use 19 | chandle = ctypes.c_int16() 20 | status = {} 21 | 22 | # Open 6000 A series PicoScope 23 | # returns handle to chandle for use in future API functions 24 | resolution = enums.PICO_DEVICE_RESOLUTION["PICO_DR_8BIT"] 25 | status["openunit"] = ps.ps6000aOpenUnit(ctypes.byref(chandle), None, resolution) 26 | assert_pico_ok(status["openunit"]) 27 | 28 | # Set signal generator waveform 29 | # handle = chandle 30 | wavetype = enums.PICO_WAVE_TYPE["PICO_SINE"] 31 | bufferlength = 1000 32 | buffer = (ctypes.c_int16 * bufferlength)() 33 | status["sigGenWaveform"] = ps.ps6000aSigGenWaveform(chandle, wavetype, ctypes.byref(buffer), bufferlength) 34 | assert_pico_ok(status["sigGenWaveform"]) 35 | 36 | # Set signal generator range 37 | # handle = chandle 38 | peakToPeakVolts = 2 39 | offsetVolts = 0 40 | status["sigGenRange"] = ps.ps6000aSigGenRange(chandle, peakToPeakVolts, offsetVolts) 41 | assert_pico_ok(status["sigGenRange"]) 42 | 43 | # Set signal generator duty cycle 44 | # handle = chandle 45 | dutyCyclePercent = 50 46 | status["sigGenDutyCycle"] = ps.ps6000aSigGenWaveformDutyCycle(chandle, dutyCyclePercent) 47 | assert_pico_ok(status["sigGenDutyCycle"]) 48 | 49 | # Set signal generator frequency 50 | # handle = chandle 51 | frequencyHz = 1000 52 | status["sigGenFreq"] = ps.ps6000aSigGenFrequency(chandle, frequencyHz) 53 | assert_pico_ok(status["sigGenFreq"]) 54 | 55 | # Apply signal generator settings 56 | # handle = chandle 57 | sigGenEnabled = 1 58 | sweepEnabled = 0 59 | triggerEnabled = 0 60 | automaticClockOptimisationEnabled = 0 61 | overrideAutomaticClockAndPrescale = 0 62 | frequency = ctypes.c_int16(frequencyHz) 63 | #stopFrequency = None 64 | #frequencyIncrement = None 65 | #dwellTime = None 66 | status["sigGenApply"] = ps.ps6000aSigGenApply(chandle, 67 | sigGenEnabled, 68 | sweepEnabled, 69 | triggerEnabled, 70 | automaticClockOptimisationEnabled, 71 | overrideAutomaticClockAndPrescale, 72 | ctypes.byref(frequency), 73 | None, 74 | None, 75 | None 76 | ) 77 | assert_pico_ok(status["sigGenApply"]) 78 | 79 | time.sleep(5) 80 | 81 | # Pause signal generator 82 | # handle = chandle 83 | status["sigGenPause"] = ps.ps6000aSigGenPause(chandle) 84 | assert_pico_ok(status["sigGenPause"]) 85 | 86 | time.sleep(5) 87 | 88 | # Resume signal generator 89 | # handle = chandle 90 | status["sigGenRestart"] = ps.ps6000aSigGenRestart(chandle) 91 | assert_pico_ok(status["sigGenRestart"]) 92 | 93 | time.sleep(5) 94 | 95 | # Pause signal generator 96 | # handle = chandle 97 | status["sigGenPause"] = ps.ps6000aSigGenPause(chandle) 98 | assert_pico_ok(status["sigGenPause"]) 99 | 100 | # Close the scope 101 | status["closeunit"] = ps.ps6000aCloseUnit(chandle) 102 | assert_pico_ok(status["closeunit"]) 103 | 104 | print(status) -------------------------------------------------------------------------------- /pt104Examples/pt104EnumerateTestsExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PT104 Example 5 | # This example opens a pt104, sets up a single channel and collects data before closing the pt104 6 | 7 | import ctypes 8 | from picosdk.usbPT104 import usbPt104 as pt104 9 | import numpy as np 10 | from picosdk.functions import assert_pico_ok 11 | from time import sleep 12 | import matplotlib.pyplot as plt 13 | 14 | # Create status ready for use 15 | status = {} 16 | 17 | # Setup Enumerating function data types 18 | Enumerate_string = ctypes.create_string_buffer(b"------------------------------------------------------------------") 19 | EnumUnitString = ctypes.cast(Enumerate_string,ctypes.c_char_p) 20 | stringLength = len(Enumerate_string) 21 | requiredSize = ctypes.c_uint32(stringLength) 22 | 23 | unit_connection_method = pt104.COMMUNICATION_TYPE["CT_USB"] 24 | 25 | print("Enumerating Unit(s)...") 26 | status["EnumerateUnit"] = pt104.UsbPt104Enumerate(EnumUnitString, ctypes.byref(requiredSize) , unit_connection_method ) 27 | assert_pico_ok(status["EnumerateUnit"]) 28 | print("serial number(s) are-") 29 | print(EnumUnitString.value) 30 | 31 | # Create variables for unit handles 32 | chandle = ctypes.c_int16() 33 | chandle2 = ctypes.c_int16() 34 | 35 | # Open the device 36 | print("Opening device...") 37 | status["openUnit"] = pt104.UsbPt104OpenUnit(ctypes.byref(chandle),0) 38 | assert_pico_ok(status["openUnit"]) 39 | print("handle is: ", chandle) 40 | 41 | SN = ctypes.create_string_buffer(b"AA000/0000") 42 | SNString = ctypes.cast(SN,ctypes.c_char_p) 43 | stringLength = len(SN) 44 | requiredSize = ctypes.c_int16(stringLength) 45 | infoSN = 0x04 46 | 47 | status["getUnitInfo_SN"] = pt104.UsbPt104GetUnitInfo(chandle, SNString,stringLength,ctypes.byref(requiredSize),infoSN) 48 | assert_pico_ok(status["getUnitInfo_SN"]) 49 | print("Serial number is...") 50 | print(SN.value) 51 | 52 | # Open the 2nd device 53 | print("Opening the 2nd device...") 54 | status["openUnit"] = pt104.UsbPt104OpenUnit(ctypes.byref(chandle2),0) 55 | assert_pico_ok(status["openUnit"]) 56 | print("handle is: ", chandle2) 57 | 58 | status["getUnitInfo_SN"] = pt104.UsbPt104GetUnitInfo(chandle2, SNString,stringLength,ctypes.byref(requiredSize),infoSN) 59 | assert_pico_ok(status["getUnitInfo_SN"]) 60 | print("Serial number is...") 61 | print(SN.value) 62 | 63 | # Close the unit(s) 64 | print("Closing Unit(s)...") 65 | status["closeUnit"] = pt104.UsbPt104CloseUnit(chandle) 66 | assert_pico_ok(status["closeUnit"]) 67 | status["closeUnit"] = pt104.UsbPt104CloseUnit(chandle2) 68 | assert_pico_ok(status["closeUnit"]) 69 | 70 | print(status) 71 | -------------------------------------------------------------------------------- /pt104Examples/pt104Example.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # PT104 Example 5 | # This example opens a pt104, sets up a single channel and collects data before closing the pt104 6 | 7 | import ctypes 8 | from picosdk.usbPT104 import usbPt104 as pt104 9 | import numpy as np 10 | from picosdk.functions import assert_pico_ok 11 | from time import sleep 12 | import matplotlib.pyplot as plt 13 | 14 | # Create chandle and status ready for use 15 | status = {} 16 | chandle = ctypes.c_int16() 17 | 18 | # Open the device 19 | status["openUnit"] = pt104.UsbPt104OpenUnit(ctypes.byref(chandle),0) 20 | assert_pico_ok(status["openUnit"]) 21 | 22 | # Set mains noise filtering 23 | sixty_hertz = 0 #50 Hz 24 | status["setMains"] = pt104.UsbPt104SetMains(chandle, sixty_hertz) 25 | assert_pico_ok(status["setMains"]) 26 | 27 | # Setup channel 1 28 | channel = pt104.PT104_CHANNELS["USBPT104_CHANNEL_1"] #channel 1 29 | datatype = pt104.PT104_DATA_TYPE["USBPT104_PT100"] #pt100 30 | noOfWires = 4 #wires 31 | 32 | status["setChannel1"] = pt104.UsbPt104SetChannel(chandle, channel, datatype, noOfWires) 33 | assert_pico_ok(status["setChannel1"]) 34 | 35 | #collect data 36 | print("collecting data") 37 | numSamples = 20 38 | 39 | data = (ctypes.c_int32 * numSamples)() 40 | 41 | for i in range(numSamples): 42 | 43 | #pause 44 | sleep(2) 45 | 46 | # Get values 47 | measurement = ctypes.c_int32() 48 | filtered = 1 # true 49 | status["getValue"] = pt104.UsbPt104GetValue(chandle, channel, ctypes.byref(measurement), filtered) 50 | assert_pico_ok(status["getValue"]) 51 | 52 | data[i] = measurement.value 53 | 54 | samples = np.linspace(0, numSamples*2, numSamples) 55 | dataTemp = [x /1000 for x in data] 56 | 57 | plt.plot(samples, dataTemp) 58 | plt.xlabel('Time (s)') 59 | plt.ylabel('Temperature ($^o$C)') 60 | plt.show() 61 | 62 | # Close the device 63 | status["closeUnit"] = pt104.UsbPt104CloseUnit(chandle) 64 | assert_pico_ok(status["closeUnit"]) 65 | 66 | print(status) -------------------------------------------------------------------------------- /requirements-for-examples.txt: -------------------------------------------------------------------------------- 1 | matplotlib>=1.5.3 2 | toml>=0.10.2 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.12.1 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017-2018 Pico Technology Ltd. 3 | # 4 | from __future__ import print_function 5 | from setuptools import setup 6 | 7 | import ctypes 8 | from ctypes import * 9 | from ctypes.util import find_library 10 | import sys 11 | import os.path 12 | 13 | 14 | signalfile = ".sdkwarning" 15 | if not os.path.exists(signalfile): 16 | name = 'ps2000' 17 | try: 18 | if sys.platform == 'win32': 19 | result = ctypes.WinDLL(find_library(name)) 20 | else: 21 | result = cdll.LoadLibrary(find_library(name)) 22 | except OSError: 23 | print("Please install the PicoSDK in order to use this wrapper." 24 | "Visit https://www.picotech.com/downloads") 25 | exit(1) 26 | open(signalfile, 'a').close() 27 | 28 | with open("README.md") as f: 29 | readme = f.read() 30 | 31 | setup( 32 | name='picosdk', 33 | packages=['picosdk'], 34 | install_requires=["numpy>=1.12.1"], 35 | version='1.0', 36 | description='PicoSDK Python wrapper', 37 | long_description=readme, 38 | author='Pico Technology Ltd', 39 | author_email='support@picotech.com', 40 | license="ISC", 41 | url='https://www.picotech.com', 42 | classifiers=[ 43 | "Development Status :: 5 - Production/Stable", 44 | "Intended Audience :: Science/Research", 45 | "License :: OSI Approved :: ISC License (ISCL)", 46 | "Natural Language :: English", 47 | "Programming Language :: Python :: 2.7", 48 | "Programming Language :: Python :: 3", 49 | "Programming Language :: Python :: 3.6", 50 | "Programming Language :: Python :: 3.7", 51 | "Programming Language :: Python :: 3.8", 52 | "Programming Language :: Python :: 3.9", 53 | "Topic :: Scientific/Engineering", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /setupPicosynth.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017-2018 Pico Technology Ltd. 3 | # 4 | from __future__ import print_function 5 | from distutils.core import setup 6 | 7 | import ctypes 8 | from ctypes import * 9 | from ctypes.util import find_library 10 | import sys 11 | import os.path 12 | 13 | 14 | signalfile = ".sdkwarning" 15 | if not os.path.exists(signalfile): 16 | name = 'picosynth' 17 | try: 18 | if sys.platform == 'win32': 19 | result = ctypes.WinDLL(find_library(name)) 20 | print(result) 21 | else: 22 | result = cdll.LoadLibrary(find_library(name)) 23 | except OSError: 24 | print("Please install PicoSynth software in order to use this wrapper." 25 | "Visit https://www.picotech.com/downloads") 26 | exit(1) 27 | open(signalfile, 'a').close() 28 | 29 | 30 | setup(name='PicoSDK', 31 | version='1.0', 32 | description='PicoSDK Python wrapper', 33 | author='Pico Technology Ltd', 34 | author_email='support@picotech.com', 35 | url='https://www.picotech.com', 36 | packages=['picosdk']) 37 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | -------------------------------------------------------------------------------- /test/run_examples.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cd "${BASH_SOURCE%/*}" || exit 4 | 5 | FILE_ERRORS="" 6 | NEWLINE=$'\n' 7 | 8 | for file in ../ps*Examples/* 9 | do 10 | if [[ -f $file ]]; then 11 | echo $file 12 | PYTHONPATH=`pwd`/.. python $file 13 | if [ $? -ne 0 ]; then 14 | FILE_ERRORS="$FILE_ERRORS$file$NEWLINE" 15 | fi 16 | fi 17 | done 18 | 19 | echo $FILE_ERRORS 20 | 21 | if [ -z "$FILE_ERRORS" ]; then 22 | exit 0 23 | fi 24 | exit 1 25 | -------------------------------------------------------------------------------- /test/test_discover.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | Unit tests for the wrapper functions for discovering devices 6 | """ 7 | 8 | from __future__ import print_function 9 | 10 | from test.test_helpers import DriverTest, drivers_with_device_connected 11 | from picosdk.device import Device 12 | from picosdk.errors import DeviceNotFoundError 13 | import picosdk.discover as dut 14 | 15 | 16 | class OpenCloseTest(DriverTest): 17 | def test_find_unit_success(self): 18 | """test_find_unit_success 19 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 20 | if not drivers_with_device_connected: 21 | return 22 | 23 | device = dut.find_unit() 24 | try: 25 | self.assertIsInstance(device, Device) 26 | self.assertIn(device.driver.name, drivers_with_device_connected) 27 | finally: 28 | device.close() 29 | 30 | def test_find_all_units_success(self): 31 | """test_find_all_units_success 32 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 33 | if not drivers_with_device_connected: 34 | return 35 | 36 | devices = dut.find_all_units() 37 | 38 | try: 39 | for device in devices: 40 | self.assertIsInstance(device, Device) 41 | self.assertIn(device.driver.name, drivers_with_device_connected) 42 | self.assertEqual(set(device.driver.name for device in devices), set(drivers_with_device_connected)) 43 | finally: 44 | for device in devices: 45 | device.close() 46 | 47 | def test_find_unit_failure(self): 48 | devices = [] 49 | threw = False 50 | try: 51 | while len(devices) <= len(drivers_with_device_connected): 52 | devices.append(dut.find_unit()) 53 | except DeviceNotFoundError: 54 | threw = True 55 | finally: 56 | for device in devices: 57 | device.close() 58 | self.assertEqual(len(drivers_with_device_connected), len(devices)) 59 | self.assertTrue(threw) 60 | 61 | def test_find_all_units_failure(self): 62 | devices = [] 63 | threw = False 64 | try: 65 | devices = dut.find_all_units() 66 | dut.find_all_units() 67 | except DeviceNotFoundError: 68 | threw = True 69 | finally: 70 | for device in devices: 71 | device.close() 72 | self.assertTrue(threw) 73 | -------------------------------------------------------------------------------- /test/test_get_unit_info.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | Unit tests for the wrapper function for retrieving device information. 6 | """ 7 | 8 | from __future__ import print_function 9 | 10 | from test.test_helpers import DriverTest, drivers_with_device_connected 11 | from picosdk.errors import DeviceNotFoundError, ArgumentOutOfRangeError 12 | 13 | try: 14 | STRING_TYPES = (str, unicode) 15 | except: 16 | STRING_TYPES = (bytes, str) 17 | 18 | 19 | class GetInfoTest(DriverTest): 20 | def test_get_info_success(self): 21 | """test_get_info_success 22 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 23 | if not drivers_with_device_connected: 24 | return 25 | drivers_to_use = drivers_with_device_connected 26 | 27 | def test(driver): 28 | devices = [] 29 | try: 30 | devices.append(driver.open_unit()) 31 | except DeviceNotFoundError: 32 | return "no device found." 33 | 34 | device = devices.pop() 35 | info = driver.get_unit_info(device) 36 | device.close() 37 | 38 | self.assertEqual(info.driver, driver) 39 | self.assertIsInstance(info.variant, STRING_TYPES) 40 | self.assertIsInstance(info.serial, STRING_TYPES) 41 | 42 | self.run_snippet_and_count_problems(drivers_to_use, test) 43 | 44 | def test_get_info_advanced_success(self): 45 | """test_get_info_advanced_success 46 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 47 | if not drivers_with_device_connected: 48 | return 49 | drivers_to_use = drivers_with_device_connected 50 | 51 | def test(driver): 52 | devices = [] 53 | try: 54 | devices.append(driver.open_unit()) 55 | except DeviceNotFoundError: 56 | return "no device found." 57 | 58 | device = devices.pop() 59 | # three keys present on ALL devices. 60 | info = driver.get_unit_info(device, 61 | "PICO_DRIVER_VERSION", 62 | "PICO_USB_VERSION", 63 | "PICO_HARDWARE_VERSION") 64 | device.close() 65 | 66 | self.assertEqual(len(info), 3) 67 | self.assertIsInstance(info.PICO_DRIVER_VERSION, STRING_TYPES) 68 | self.assertIsInstance(info.PICO_USB_VERSION, STRING_TYPES) 69 | self.assertIsInstance(info.PICO_HARDWARE_VERSION, STRING_TYPES) 70 | 71 | self.run_snippet_and_count_problems(drivers_to_use, test) 72 | 73 | def test_get_info_with_invalid_key_fails(self): 74 | """test_get_info_advanced_success 75 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 76 | if not drivers_with_device_connected: 77 | return 78 | drivers_to_use = drivers_with_device_connected 79 | 80 | def test(driver): 81 | devices = [] 82 | try: 83 | devices.append(driver.open_unit()) 84 | except DeviceNotFoundError: 85 | return "no device found." 86 | 87 | device = devices.pop() 88 | threw = False 89 | try: 90 | # some valid and some invalid keys. People may pass PICO_CAL_DATE to ps2000 etc. 91 | info = driver.get_unit_info(device, 92 | "PICO_DRIVER_VERSION", 93 | "aillk_jasgKLASDFG_Jlasdkgfj", 94 | "PICO_HARDWARE_VERSION") 95 | except ArgumentOutOfRangeError: 96 | threw = True 97 | finally: 98 | device.close() 99 | 100 | if not threw: 101 | return "get_unit_info didn't throw exception on bad key." 102 | 103 | self.run_snippet_and_count_problems(drivers_to_use, test) 104 | -------------------------------------------------------------------------------- /test/test_helpers.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | Helper methods for tests, and test configuration information. 6 | """ 7 | 8 | import importlib as _importlib 9 | import unittest as _unittest 10 | 11 | drivers_to_load = [ 12 | 'ps2000', 13 | 'ps2000a', 14 | 'ps3000', 15 | 'ps3000a', 16 | 'ps4000', 17 | 'ps4000a', 18 | 'ps5000a', 19 | 'ps6000', 20 | ] 21 | 22 | modules = {} 23 | 24 | for _d in drivers_to_load: 25 | modules[_d] = _importlib.import_module("picosdk.%s" % _d) 26 | 27 | # PLEASE MODIFY this list before running, to indicate which drivers should 28 | # expect to find a device. 29 | drivers_with_device_connected = [ 30 | # 'ps2000', 31 | # 'ps2000a', 32 | # 'ps3000', 33 | # 'ps3000a', 34 | # 'ps4000', 35 | # 'ps4000a', 36 | # 'ps5000a', 37 | # 'ps6000', 38 | ] 39 | 40 | 41 | class TestFailAndError(Exception): 42 | pass 43 | 44 | 45 | class TestError(Exception): 46 | pass 47 | 48 | 49 | class DriverTest(_unittest.TestCase): 50 | @staticmethod 51 | def _find_driver(name): 52 | # e.g. ps2000.ps2000 53 | m = modules[name] 54 | return getattr(m, name) 55 | 56 | def run_snippet_and_count_problems(self, drivers_to_use, fn): 57 | errors = [] 58 | failures = [] 59 | for d in drivers_to_use: 60 | driver = self._find_driver(d) 61 | try: 62 | result = fn(driver) 63 | if result is not None: 64 | failures.append((d, result)) 65 | except Exception as e: 66 | errors.append((d, e)) 67 | # format the errors and failure messages for printing: 68 | errors = ", ".join(["%s (%r)" % e for e in errors]) 69 | failures = ", ".join(["%s (%s)" % f for f in failures]) 70 | if failures and errors: 71 | raise TestFailAndError("drivers error'd: %s\nand drivers failed: %s" % (errors, failures)) 72 | elif errors: 73 | raise TestError("drivers error'd: %s" % errors) 74 | else: 75 | self.assertEqual(len(failures), 0, "Drivers failed: %s" % failures) 76 | -------------------------------------------------------------------------------- /test/test_open_close_unit.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | Unit tests for the wrapper functions for opening and closing devices. 6 | """ 7 | 8 | from __future__ import print_function 9 | 10 | from test.test_helpers import DriverTest, drivers_to_load, drivers_with_device_connected 11 | from picosdk.errors import DeviceNotFoundError 12 | 13 | 14 | class OpenCloseTest(DriverTest): 15 | def test_open_unit_failure(self): 16 | """test_open_unit_failure 17 | note: test assumes that at maximum one device is attached for each driver.""" 18 | drivers_to_use = drivers_to_load 19 | 20 | def test(driver): 21 | threw = False 22 | devices = [] 23 | try: 24 | devices.append(driver.open_unit()) 25 | devices.append(driver.open_unit()) 26 | except DeviceNotFoundError: 27 | threw = True 28 | finally: 29 | for device in devices: 30 | device.close() 31 | if not threw: 32 | return "didn't throw a DeviceNotFoundError." 33 | self.run_snippet_and_count_problems(drivers_to_use, test) 34 | 35 | def test_open_unit_success(self): 36 | """test_open_unit_success 37 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 38 | if not drivers_with_device_connected: 39 | return 40 | drivers_to_use = drivers_with_device_connected[:] 41 | 42 | def test(driver): 43 | threw = False 44 | devices = [] 45 | try: 46 | devices.append(driver.open_unit()) 47 | except DeviceNotFoundError as e: 48 | threw = e 49 | finally: 50 | for device in devices: 51 | print("closing device %s" % device.handle) 52 | device.close() 53 | if threw is not False: 54 | return "no device found (%s)." % threw 55 | self.run_snippet_and_count_problems(drivers_to_use, test) 56 | 57 | def test_close_unit_success(self): 58 | """test_close_unit_success 59 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 60 | if not drivers_with_device_connected: 61 | return 62 | drivers_to_use = drivers_with_device_connected 63 | 64 | def test(driver): 65 | devices = [] 66 | try: 67 | devices.append(driver.open_unit()) 68 | except DeviceNotFoundError as e: 69 | return "no device found (%s)." % e 70 | 71 | device = devices.pop() 72 | info = device.info 73 | device.close() 74 | # To test the success of close(), we try to re-open the device. 75 | # If we fail, then we have not closed it correctly. 76 | try: 77 | devices.append(driver.open_unit(serial=info.serial)) 78 | except DeviceNotFoundError as e: 79 | return "Could not close and then re-open the device (%s)." % e 80 | finally: 81 | for device in devices: 82 | device.close() 83 | self.run_snippet_and_count_problems(drivers_to_use, test) 84 | 85 | def test_with_statement_open_close(self): 86 | """test_with_statement_open_close 87 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 88 | if not drivers_with_device_connected: 89 | return 90 | drivers_to_use = drivers_with_device_connected[:] 91 | 92 | def test(driver): 93 | threw = False 94 | was_open = False 95 | was_closed = False 96 | outer_scope_device = None 97 | try: 98 | with driver.open_unit() as device: 99 | was_open = device.is_open 100 | outer_scope_device = device 101 | was_closed = not outer_scope_device.is_open 102 | except DeviceNotFoundError as e: 103 | threw = e 104 | finally: 105 | if outer_scope_device is not None and not was_closed: 106 | outer_scope_device.close() 107 | if threw is not False: 108 | return "no device found (%s)." % threw 109 | elif not was_open: 110 | return "device was not opened correctly" 111 | elif not was_closed: 112 | return "device was not closed after exiting the scope" 113 | 114 | self.run_snippet_and_count_problems(drivers_to_use, test) 115 | -------------------------------------------------------------------------------- /test/test_set_channel.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | """ 5 | Unit tests for the wrapper functions for configuring channels 6 | """ 7 | 8 | from __future__ import print_function 9 | 10 | from test.test_helpers import DriverTest, drivers_with_device_connected 11 | from picosdk.errors import ArgumentOutOfRangeError 12 | from picosdk.device import ChannelConfig 13 | 14 | 15 | class SetChannelTest(DriverTest): 16 | # Both 3000a and 5000a define a 50V enum member, but neither actually has a device which 17 | # supports that range. 18 | max_volts_by_driver = { 19 | "ps2000": 20, 20 | "ps2000a": 20, 21 | "ps3000": 400, 22 | "ps3000a": 20, 23 | "ps4000": 100, 24 | "ps4000a": 50, 25 | "ps5000a": 20, 26 | } 27 | 28 | def test_set_channel_success(self): 29 | """test_set_channel_success 30 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 31 | if not drivers_with_device_connected: 32 | return 33 | drivers_to_use = drivers_with_device_connected 34 | 35 | def test(driver): 36 | expected_max_volts = self.max_volts_by_driver[driver.name] 37 | with driver.open_unit() as device: 38 | config = ChannelConfig(name='A', enabled=True, coupling='DC', range_peak=expected_max_volts) 39 | actual_max_voltage = device.set_channel(config) 40 | 41 | self.assertEqual(expected_max_volts, actual_max_voltage) 42 | 43 | self.run_snippet_and_count_problems(drivers_to_use, test) 44 | 45 | def test_set_channel_very_small_peak(self): 46 | if not drivers_with_device_connected: 47 | return 48 | drivers_to_use = drivers_with_device_connected 49 | 50 | # Some drivers specify more ranges than some of their devices actually support. Check that we handle this error 51 | # at the lowest voltages (at the upper range, see the relevant test below, there's nothing we can do but raise.) 52 | def test(driver): 53 | five_millivolts = 0.005 54 | 55 | with driver.open_unit() as device: 56 | config = ChannelConfig(name='A', enabled=True, coupling='DC', range_peak=five_millivolts) 57 | actual_max_voltage = device.set_channel(config) 58 | 59 | self.assertGreaterEqual(actual_max_voltage, five_millivolts) 60 | 61 | self.run_snippet_and_count_problems(drivers_to_use, test) 62 | 63 | def test_set_channel_range_too_large(self): 64 | """test_set_channel_range_too_large 65 | note: test assumes you have set test_helpers.drivers_with_device_connected""" 66 | if not drivers_with_device_connected: 67 | return 68 | drivers_to_use = drivers_with_device_connected 69 | 70 | def test(driver): 71 | with driver.open_unit() as device: 72 | threw = False 73 | try: 74 | driver.set_channel(device, range_peak=float('inf')) 75 | except ArgumentOutOfRangeError: 76 | threw = True 77 | if not threw: 78 | return "didn't throw an ArgumentOutOfRangeError." 79 | 80 | self.run_snippet_and_count_problems(drivers_to_use, test) 81 | -------------------------------------------------------------------------------- /usbdrdaqExamples/usbdrdaqPhBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # USBDRDAQ SCOPE BLOCK MODE EXAMPLE 5 | # This example opens a UsbDrDaq driver device, sets up the scope channel and a trigger then collects a single block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import time 10 | from picosdk.usbDrDaq import usbDrDaq as drDaq 11 | import numpy as np 12 | import matplotlib.pyplot as plt 13 | from picosdk.functions import adc2mV, assert_pico_ok 14 | 15 | # Create chandle and status ready for use 16 | status = {} 17 | chandle = ctypes.c_int16() 18 | 19 | # Opens the device 20 | status["openunit"] = drDaq.UsbDrDaqOpenUnit(ctypes.byref(chandle)) 21 | assert_pico_ok(status["openunit"]) 22 | 23 | # Set sample interval 24 | us_for_block = ctypes.c_int32(1000) 25 | ideal_no_of_samples = 1000 26 | channels = ctypes.c_int32(drDaq.USB_DRDAQ_INPUTS["USB_DRDAQ_CHANNEL_PH"]) 27 | no_of_channels = 1 28 | status["setInterval"] = drDaq.UsbDrDaqSetInterval(chandle, ctypes.byref(us_for_block), ideal_no_of_samples, ctypes.byref(channels), no_of_channels) 29 | assert_pico_ok(status["setInterval"]) 30 | 31 | # Find scaling information 32 | channel = drDaq.USB_DRDAQ_INPUTS["USB_DRDAQ_CHANNEL_PH"] 33 | nScales = ctypes.c_int16(0) 34 | currentScale = ctypes.c_int16(0) 35 | names = (ctypes.c_char*256)() 36 | namesSize = 256 37 | status["getscalings"] = drDaq.UsbDrDaqGetScalings(chandle, channel, ctypes.byref(nScales), ctypes.byref(currentScale), ctypes.byref(names), namesSize) 38 | assert_pico_ok(status["getscalings"]) 39 | 40 | print(nScales.value) 41 | print(currentScale.value) 42 | print(names.value) 43 | 44 | # Set channel scaling 45 | scalingNumber = 0 # pH scaling 46 | status["setscaling"] = drDaq.UsbDrDaqSetScalings(chandle, channel, scalingNumber) 47 | assert_pico_ok(status["setscaling"]) 48 | 49 | # Set temperature compenstation 50 | enabled = 1 51 | status["phTemperatureCompensation"] = drDaq.UsbDrDaqPhTemperatureCompensation(chandle, enabled) 52 | assert_pico_ok(status["phTemperatureCompensation"]) 53 | 54 | # Run block capture 55 | method = drDaq.USB_DRDAQ_BLOCK_METHOD["BM_SINGLE"] 56 | status["run"] = drDaq.UsbDrDaqRun(chandle, ideal_no_of_samples, method) 57 | assert_pico_ok(status["run"]) 58 | 59 | ready = ctypes.c_int16(0) 60 | 61 | while ready.value == 0: 62 | status["ready"] = drDaq.UsbDrDaqReady(chandle, ctypes.byref(ready)) 63 | print(ready.value) 64 | time.sleep(0.1) 65 | 66 | # Retrieve data from device 67 | values = (ctypes.c_float * ideal_no_of_samples)() 68 | noOfValues = ctypes.c_uint32(ideal_no_of_samples) 69 | overflow = ctypes.c_uint16(0) 70 | triggerIndex = ctypes.c_uint32(0) 71 | status["getvaluesF"] = drDaq.UsbDrDaqGetValuesF(chandle, ctypes.byref(values), ctypes.byref(noOfValues), ctypes.byref(overflow), ctypes.byref(triggerIndex)) 72 | assert_pico_ok(status["getvaluesF"]) 73 | 74 | # generate time data 75 | time = np.linspace(0, us_for_block, ideal_no_of_samples) 76 | 77 | # plot the data 78 | plt.plot(time, values[:]) 79 | plt.xlabel('Time (ns)') 80 | plt.ylabel('pH') 81 | plt.show() 82 | 83 | 84 | # Disconnect the scope 85 | # handle = chandle 86 | status["close"] = drDaq.UsbDrDaqCloseUnit(chandle) 87 | assert_pico_ok(status["close"]) 88 | 89 | # Display status returns 90 | print(status) 91 | -------------------------------------------------------------------------------- /usbdrdaqExamples/usbdrdaqScopeBlockExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2020 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # USBDRDAQ SCOPE BLOCK MODE EXAMPLE 5 | # This example opens a UsbDrDaq driver device, sets up the scope channel and a trigger then collects a single block of data. 6 | # This data is then plotted as mV against time in ns. 7 | 8 | import ctypes 9 | import time 10 | from picosdk.usbDrDaq import usbDrDaq as drDaq 11 | import numpy as np 12 | import matplotlib.pyplot as plt 13 | from picosdk.functions import adc2mV, assert_pico_ok 14 | 15 | # Create chandle and status ready for use 16 | status = {} 17 | chandle = ctypes.c_int16() 18 | 19 | # Opens the device 20 | status["openunit"] = drDaq.UsbDrDaqOpenUnit(ctypes.byref(chandle)) 21 | assert_pico_ok(status["openunit"]) 22 | 23 | # Set sample interval 24 | us_for_block = ctypes.c_int32(1000) 25 | ideal_no_of_samples = 1000 26 | channels = ctypes.c_int32(drDaq.USB_DRDAQ_INPUTS["USB_DRDAQ_CHANNEL_SCOPE"]) 27 | no_of_channels = 1 28 | status["setInterval"] = drDaq.UsbDrDaqSetInterval(chandle, ctypes.byref(us_for_block), ideal_no_of_samples, ctypes.byref(channels), no_of_channels) 29 | assert_pico_ok(status["setInterval"]) 30 | 31 | # Find scaling information 32 | channel = drDaq.USB_DRDAQ_INPUTS["USB_DRDAQ_CHANNEL_SCOPE"] 33 | nScales = ctypes.c_int16(0) 34 | currentScale = ctypes.c_int16(0) 35 | names = (ctypes.c_char*256)() 36 | namesSize = 256 37 | status["getscalings"] = drDaq.UsbDrDaqGetScalings(chandle, channel, ctypes.byref(nScales), ctypes.byref(currentScale), ctypes.byref(names), namesSize) 38 | assert_pico_ok(status["getscalings"]) 39 | 40 | print(nScales.value) 41 | print(currentScale.value) 42 | print(names.value) 43 | 44 | # Set channel scaling 45 | scalingNumber = drDaq.USB_DRDAQ_SCOPE_RANGE["USB_DRDAQ_2V5"] 46 | status["setscaling"] = drDaq.UsbDrDaqSetScalings(chandle, channel, scalingNumber) 47 | assert_pico_ok(status["setscaling"]) 48 | 49 | # Set trigger 50 | enabled = 1 51 | auto_trigger = 1 52 | auto_ms = 1000 # in ms 53 | dir = 0 # rising edge 54 | threshold = 1000 # in mV 55 | hysteresis = 50 # in ADC counts 56 | delay = -50 # trigger in centre of block 57 | status["settrigger"] = drDaq.UsbDrDaqSetTrigger(chandle, enabled, auto_trigger, auto_ms, channel, dir, threshold, hysteresis, delay) 58 | assert_pico_ok(status["settrigger"]) 59 | 60 | # Run block capture 61 | method = drDaq.USB_DRDAQ_BLOCK_METHOD["BM_SINGLE"] 62 | status["run"] = drDaq.UsbDrDaqRun(chandle, ideal_no_of_samples, method) 63 | assert_pico_ok(status["run"]) 64 | 65 | ready = ctypes.c_int16(0) 66 | 67 | while ready.value == 0: 68 | status["ready"] = drDaq.UsbDrDaqReady(chandle, ctypes.byref(ready)) 69 | print(ready.value) 70 | time.sleep(0.1) 71 | 72 | # Retrieve data from device 73 | values = (ctypes.c_float * ideal_no_of_samples)() 74 | noOfValues = ctypes.c_uint32(ideal_no_of_samples) 75 | overflow = ctypes.c_uint16(0) 76 | triggerIndex = ctypes.c_uint32(0) 77 | status["getvaluesF"] = drDaq.UsbDrDaqGetValuesF(chandle, ctypes.byref(values), ctypes.byref(noOfValues), ctypes.byref(overflow), ctypes.byref(triggerIndex)) 78 | assert_pico_ok(status["getvaluesF"]) 79 | 80 | # generate time data 81 | time = np.linspace(0, us_for_block, ideal_no_of_samples) 82 | 83 | # plot the data 84 | plt.plot(time, values[:]) 85 | plt.xlabel('Time (ns)') 86 | plt.ylabel('Voltage (mV)') 87 | plt.show() 88 | 89 | 90 | # Disconnect the scope 91 | # handle = chandle 92 | status["close"] = drDaq.UsbDrDaqCloseUnit(chandle) 93 | assert_pico_ok(status["close"]) 94 | 95 | # Display status returns 96 | print(status) 97 | -------------------------------------------------------------------------------- /usbtc08Examples/tc08SingleModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # TC-08 SINGLE MODE EXAMPLE 5 | 6 | 7 | import ctypes 8 | import numpy as np 9 | from picosdk.usbtc08 import usbtc08 as tc08 10 | from picosdk.functions import assert_pico2000_ok 11 | 12 | # Create chandle and status ready for use 13 | chandle = ctypes.c_int16() 14 | status = {} 15 | 16 | # open unit 17 | status["open_unit"] = tc08.usb_tc08_open_unit() 18 | assert_pico2000_ok(status["open_unit"]) 19 | chandle = status["open_unit"] 20 | 21 | # set mains rejection to 50 Hz 22 | status["set_mains"] = tc08.usb_tc08_set_mains(chandle,0) 23 | assert_pico2000_ok(status["set_mains"]) 24 | 25 | # set up channel 26 | # therocouples types and int8 equivalent 27 | # B=66 , E=69 , J=74 , K=75 , N=78 , R=82 , S=83 , T=84 , ' '=32 , X=88 28 | typeK = ctypes.c_int8(75) 29 | status["set_channel"] = tc08.usb_tc08_set_channel(chandle, 1, typeK) 30 | assert_pico2000_ok(status["set_channel"]) 31 | 32 | # get minimum sampling interval in ms 33 | status["get_minimum_interval_ms"] = tc08.usb_tc08_get_minimum_interval_ms(chandle) 34 | assert_pico2000_ok(status["get_minimum_interval_ms"]) 35 | 36 | # get single temperature reading 37 | temp = (ctypes.c_float * 9)() 38 | overflow = ctypes.c_int16(0) 39 | units = tc08.USBTC08_UNITS["USBTC08_UNITS_CENTIGRADE"] 40 | status["get_single"] = tc08.usb_tc08_get_single(chandle,ctypes.byref(temp), ctypes.byref(overflow), units) 41 | assert_pico2000_ok(status["get_single"]) 42 | 43 | # print data 44 | print("Cold Junction ", temp[0]," Channel 1 ", temp[1]) 45 | 46 | 47 | # close unit 48 | status["close_unit"] = tc08.usb_tc08_close_unit(chandle) 49 | assert_pico2000_ok(status["close_unit"]) 50 | 51 | # display status returns 52 | print(status) -------------------------------------------------------------------------------- /usbtc08Examples/tc08StreamingModeExample.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Pico Technology Ltd. See LICENSE file for terms. 3 | # 4 | # TC-08 STREAMING MODE EXAMPLE 5 | 6 | 7 | import ctypes 8 | import numpy as np 9 | import time 10 | from picosdk.usbtc08 import usbtc08 as tc08 11 | from picosdk.functions import assert_pico2000_ok 12 | import matplotlib.pyplot as plt 13 | 14 | # Create chandle and status ready for use 15 | chandle = ctypes.c_int16() 16 | status = {} 17 | 18 | # open unit 19 | status["open_unit"] = tc08.usb_tc08_open_unit() 20 | assert_pico2000_ok(status["open_unit"]) 21 | chandle = status["open_unit"] 22 | 23 | # set mains rejection to 50 Hz 24 | status["set_mains"] = tc08.usb_tc08_set_mains(chandle,0) 25 | assert_pico2000_ok(status["set_mains"]) 26 | 27 | # set up channel 28 | # therocouples types and int8 equivalent 29 | # B=66 , E=69 , J=74 , K=75 , N=78 , R=82 , S=83 , T=84 , ' '=32 , X=88 30 | typeK = ctypes.c_int8(75) 31 | status["set_channel"] = tc08.usb_tc08_set_channel(chandle, 1, typeK) 32 | assert_pico2000_ok(status["set_channel"]) 33 | 34 | # get minimum sampling interval in ms 35 | status["get_minimum_interval_ms"] = tc08.usb_tc08_get_minimum_interval_ms(chandle) 36 | assert_pico2000_ok(status["get_minimum_interval_ms"]) 37 | 38 | # set tc-08 running 39 | status["run"] = tc08.usb_tc08_run(chandle, status["get_minimum_interval_ms"]) 40 | assert_pico2000_ok(status["run"]) 41 | 42 | time.sleep(21) 43 | 44 | # collect data 45 | temp_buffer = (ctypes.c_float * 2 * 100)() 46 | times_ms_buffer = (ctypes.c_int32 * 100)() 47 | overflow = ctypes.c_int16() 48 | status["get_temp"] = tc08.usb_tc08_get_temp(chandle, ctypes.byref(temp_buffer), ctypes.byref(times_ms_buffer), 100, ctypes.byref(overflow), 1, 0, 1) 49 | assert_pico2000_ok(status["get_temp"]) 50 | 51 | # stop unit 52 | status["stop"] = tc08.usb_tc08_stop(chandle) 53 | assert_pico2000_ok(status["stop"]) 54 | 55 | # close unit 56 | status["close_unit"] = tc08.usb_tc08_close_unit(chandle) 57 | assert_pico2000_ok(status["close_unit"]) 58 | 59 | # plot data 60 | plt.plot(temp_buffer[0:status["get_temp"]]) 61 | plt.xlabel('Time (ns)') 62 | plt.ylabel('Temperature (oC)') 63 | plt.show() 64 | 65 | # display status returns 66 | print(status) --------------------------------------------------------------------------------