PicoSDK for Mac with arm64 architecture

Post general discussions on using our drivers to write your own software here
Post Reply
ankur.ag12@gmail.com
Newbie
Posts: 0
Joined: Sat Jan 13, 2024 1:40 am

PicoSDK for Mac with arm64 architecture

Post by ankur.ag12@gmail.com »

Currently provided PicoSDK doesn't work with arm64 Macs. For example here is the error on M1:

Code: Select all

picosdk.errors.CannotOpenPicoSDKError: PicoSDK (ps2000) not compatible (check 32 vs 64-bit): dlopen(/Applications/PicoLog.app/Contents/Resources/libps2000.dylib, 0x0006): tried: '/Applications/PicoLog.app/Contents/Resources/libps2000.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/Applications/PicoLog.app/Contents/Resources/libps2000.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Applications/PicoLog.app/Contents/Resources/libps2000.dylib' (no such file), '/Applications/PicoLog.app/Contents/Resources/libps2000.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
Could you recompile the SDK for arm64 Mac?
Thanks!

Anna
User
User
Posts: 2
Joined: Fri Sep 16, 2016 8:44 am

Re: PicoSDK for Mac with arm64 architecture

Post by Anna »

Hi Picotech Team,
I second this! Mac's new architecture is out for some time now. I was very negatively surprised that I cannot use the SDK.

acamargofb
Newbie
Posts: 1
Joined: Wed Feb 07, 2024 6:49 pm

Re: PicoSDK for Mac with arm64 architecture

Post by acamargofb »

Hi there,
I have a Mac Pro with M1 processor. I was able to install the SDK, and the C libraries. But when I tried to run an example for Python code, I can't run it, I am getting this error:
CannotFindPicoSDKError: PicoSDK (ps5000) not found, check LD_LIBRARY_PATH

The code that I am testing is the following:

======

# Copyright (C) 2018-2022 Pico Technology Ltd. See LICENSE file for terms.
#
# PS5000 BLOCK MODE EXAMPLE
# This example opens a 5000a driver device, sets up two channels and a trigger then collects a block of data.
# This data is then plotted as mV against time in ns.

import ctypes
import numpy as np
from picosdk.ps5000 import ps5000 as ps

import matplotlib.pyplot as plt
from picosdk.functions import adc2mV, assert_pico_ok, mV2adc

# Create chandle and status ready for use
chandle = ctypes.c_int16()
status = {}

# Open 5000 series PicoScope
# Returns handle to chandle for use in future API functions
status["openunit"] = ps.ps5000OpenUnit(ctypes.byref(chandle))
assert_pico_ok(status["openunit"])


# Set up channel A
# handle = chandle
channel = ps.PS5000_CHANNEL["PS5000_CHANNEL_A"]
# enabled = 1
coupling_type = 1 # DC
chARange = ps.PS5000_RANGE["PS5000_20V"]
# analogue offset = 0 V
status["setChA"] = ps.ps5000SetChannel(chandle, channel, 1, coupling_type, chARange)
assert_pico_ok(status["setChA"])

# Set up channel B
# handle = chandle
channel = ps.PS5000_CHANNEL["PS5000_CHANNEL_B"]
# enabled = 1
# coupling_type = ps.PS5000_COUPLING["PS5000_DC"]
chBRange = ps.PS5000_RANGE["PS5000_2V"]
# analogue offset = 0 V
status["setChB"] = ps.ps5000SetChannel(chandle, channel, 1, coupling_type, chBRange)
assert_pico_ok(status["setChB"])

# find maximum ADC count value
# handle = chandle
# pointer to value = ctypes.byref(maxADC)
maxADC = ctypes.c_int16(32512)

# Set up single trigger
# handle = chandle
# enabled = 1
source = ps.PS5000_CHANNEL["PS5000_CHANNEL_A"]
threshold = int(mV2adc(500,chARange, maxADC))
# direction = PS5000_RISING = 2
# delay = 0 s
# auto Trigger = 1000 ms
status["trigger"] = ps.ps5000SetSimpleTrigger(chandle, 1, source, threshold, 2, 0, 1000)
assert_pico_ok(status["trigger"])

# Set number of pre and post trigger samples to be collected
preTriggerSamples = 2500
postTriggerSamples = 2500
maxSamples = preTriggerSamples + postTriggerSamples

# Get timebase information
# 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.
# To access these Timebases, set any unused analogue channels to off.
# handle = chandle
timebase = 8
# noSamples = maxSamples
# pointer to timeIntervalNanoseconds = ctypes.byref(timeIntervalns)
oversample = 1
# pointer to maxSamples = ctypes.byref(returnedMaxSamples)
# segment index = 0
timeIntervalns = ctypes.c_float()
returnedMaxSamples = ctypes.c_int32()
status["getTimebase"] = ps.ps5000GetTimebase(chandle, timebase, maxSamples, ctypes.byref(timeIntervalns), oversample, ctypes.byref(returnedMaxSamples), 0)
assert_pico_ok(status["getTimebase2"])

# Run block capture
# handle = chandle
# number of pre-trigger samples = preTriggerSamples
# number of post-trigger samples = PostTriggerSamples
# timebase = 8 = 80 ns (see Programmer's guide for mre information on timebases)
# oversample = 1
# time indisposed ms = None (not needed in the example)
# segment index = 0
# lpReady = None (using ps5000IsReady rather than ps5000BlockReady)
# pParameter = None
status["runBlock"] = ps.ps5000RunBlock(chandle, preTriggerSamples, postTriggerSamples, timebase, oversample, None, 0, None, None)
assert_pico_ok(status["runBlock"])

# Check for data collection to finish using ps5000IsReady
ready = ctypes.c_int16(0)
check = ctypes.c_int16(0)
while ready.value == check.value:
status["isReady"] = ps.ps5000IsReady(chandle, ctypes.byref(ready))


# Create buffers ready for assigning pointers for data collection
bufferAMax = (ctypes.c_int16 * maxSamples)()
bufferAMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example
bufferBMax = (ctypes.c_int16 * maxSamples)()
bufferBMin = (ctypes.c_int16 * maxSamples)() # used for downsampling which isn't in the scope of this example

# Set data buffer location for data collection from channel A
# handle = chandle
source = ps.PS5000_CHANNEL["PS5000_CHANNEL_A"]
# pointer to buffer max = ctypes.byref(bufferAMax)
# pointer to buffer min = ctypes.byref(bufferAMin)
# buffer length = maxSamples
status["setDataBuffersA"] = ps.ps5000SetDataBuffers(chandle, source, ctypes.byref(bufferAMax), ctypes.byref(bufferAMin), maxSamples)
assert_pico_ok(status["setDataBuffersA"])

# Set data buffer location for data collection from channel B
# handle = chandle
source = ps.PS5000_CHANNEL["PS5000_CHANNEL_B"]
# pointer to buffer max = ctypes.byref(bufferBMax)
# pointer to buffer min = ctypes.byref(bufferBMin)
# buffer length = maxSamples
# segment index = 0
# ratio mode = PS5000_RATIO_MODE_NONE = 0
status["setDataBuffersB"] = ps.ps5000SetDataBuffers(chandle, source, ctypes.byref(bufferBMax), ctypes.byref(bufferBMin), maxSamples)
assert_pico_ok(status["setDataBuffersB"])

# create overflow loaction
overflow = ctypes.c_int16()
# create converted type maxSamples
cmaxSamples = ctypes.c_int32(maxSamples)

# Retried data from scope to buffers assigned above
# handle = chandle
# start index = 0
# pointer to number of samples = ctypes.byref(cmaxSamples)
# downsample ratio = 0
# downsample ratio mode = PS5000_RATIO_MODE_NONE
# pointer to overflow = ctypes.byref(overflow))
status["getValues"] = ps.ps5000GetValues(chandle, 0, ctypes.byref(cmaxSamples), 0, 0, 0, ctypes.byref(overflow))
assert_pico_ok(status["getValues"])


# convert ADC counts data to mV
adc2mVChAMax = adc2mV(bufferAMax, chARange, maxADC)
adc2mVChBMax = adc2mV(bufferBMax, chBRange, maxADC)

# Create time data
time = np.linspace(0, (cmaxSamples.value - 1) * timeIntervalns.value, cmaxSamples.value)

# plot data from channel A and B
plt.plot(time, adc2mVChAMax[:])
plt.plot(time, adc2mVChBMax[:])
plt.xlabel('Time (ns)')
plt.ylabel('Voltage (mV)')
plt.show()

# Stop the scope
# handle = chandle
status["stop"] = ps.ps5000Stop(chandle)
assert_pico_ok(status["stop"])

# Close unit Disconnect the scope
# handle = chandle
status["close"]=ps.ps5000CloseUnit(chandle)
assert_pico_ok(status["close"])

# display status returns
print(status)
=======

Post Reply