GithubHelp home page GithubHelp logo

analogdevicesinc / libm2k Goto Github PK

View Code? Open in Web Editor NEW
34.0 31.0 32.0 22.77 MB

A C++ library (bindings for Python and C#) for interfacing with the ADALM2000

Home Page: http://analogdevicesinc.github.io/libm2k

License: GNU Lesser General Public License v2.1

CMake 2.07% Python 8.99% C++ 35.23% Shell 0.84% C# 1.42% C 1.28% SWIG 0.41% Batchfile 0.10% MATLAB 48.94% M 0.01% PowerShell 0.72%
m2k adalm-2000 hacktoberfest

libm2k's Introduction

libm2k's People

Contributors

adisuciu avatar adrian-stanea avatar alexandratrifan avatar andreeaipop avatar bindea-cristian avatar ccraluca avatar commodo avatar cristina-suteu avatar danielguramulta avatar demon000 avatar ionutmuthi avatar maitbot avatar mihaiolteanu avatar rgetz avatar tagoylo avatar tfcollins avatar

Stargazers

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

Watchers

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

libm2k's Issues

Analog output has issues for small buffer push()

If I use push([array1,array2]) the two outputs start at the same time, and can remain sync'd. However, if the length of either array1 or array2 gets small, down to 100 or below on my system, I start to see all kinds of jitter and they lose their relative phase.

Here is a minimal script to reproduce it:

import libm2k
import pylab
import numpy

# Get the first m2k name
name = libm2k.getAllContexts()[0]

# Get the m2k
m2k = libm2k.m2kOpen(name).toM2k()

# Run the calibration
m2k.calibrate()

# Enable the first output, enable it, and send it some data.
ao = m2k.getAnalogOut()
ao.enableChannel(0, True)
ao.enableChannel(1, True)
ao.setSampleRate(0, 75000000)
ao.setSampleRate(1, 75000000)

# Waveforms: sinusoid and square pulse
N  = 200                        # Number of samples to stream
ns = numpy.linspace(0,N-1,N)    # List of integers
v1 = numpy.sin(2*numpy.pi*ns/N) # Single cycle in N points
v2 = numpy.linspace(1,0,N)      # Trigger edge
v2[0] = 0.5                     # But a little smoother...

# Send both waveforms at once
ao.push([v1,v2]) # Default is cyclic, pulse on the first output

# Enable the first input channel, enable it, and take data
ai = m2k.getAnalogIn()
ai.enableChannel(0, True)
ai.enableChannel(1, True)
ai.setSampleRate(100000000)
ai.setRange(0, libm2k.HIGH_GAIN)
ai.setRange(1, libm2k.HIGH_GAIN)

# Now try triggering
trig = ai.getTrigger()
trig.setAnalogMode(1,1)         # ch2, analog condition
trig.setAnalogSource(1)         # ch2
trig.setAnalogCondition(1,0)    # ch2, rising edge
trig.setAnalogLevel(0,0.5)      # ch2, 0.5V

# Set the timeout (5 sec) to be safe if it doesn't trigger
m2k.setTimeout(3000)

# Go for it 10 times
for n in range(10):
    y1, y2 = ai.getSamples(N*3)
    pylab.plot(y1)
    pylab.plot(y2)

Notice the N=200 line. As is, this produces perfect synchronization:
image

If I set N=100:
image

You can see the jitters more clearly as I toggle the number of samples to each analog out individually:
image

Notice especially what the later square pulses do. There are glitches and variable delays.

This feels like a buffering issue? I would think for pushed data sets that fit within the analog output's internal buffer, libm2k should just dump the data into there and let the FPGA do the looping internally? This might be a firmware issue.

I am on Linux Mint 19.3 with libm2k v0.2.1 and libiio v0.21.

Keep up the good work! <-- 100% not sarcastic. This library is REALLY moving us forward.

Cheers,
Jack

Suggested Trigger enhancement

Hi:
Here is a suggested enhancement to the analog trigger source options. Having the option to trigger / sync the analog input capture to the AWG output waveform. This could be done (might need addition to firmware) based on the AWG waveform buffer pointer. Easy obvious one is to trigger / syn off start of AWG buffer each time it repeats. Additionally you could provide an option to supply a time offset from the start of the buffer in AWG samples for example.

Why would this be useful? A common setup would have one of the scope channels connected to one of the AWG outputs to monitor the signal. You would then probably use that scope channel as the trigger source. The second scope channel might be then used to measure some other (output) node in the circuit. Given that m2k only has the two scope channels it might be desirable to not need to use one channel to trigger off the AWG output. With a way to syn directly off AWG waveform then both scope channels are free to use elsewhere in the circuit being investigated.

Also if you know where (how) in the AWG buffer the captured scope data aligns then you can plot the AWG waveform data along with the captured scope data i.e possible to plot a representation of the AWG outputs at the same time as the scope inputs without needing to physically connecting them together. Like having a "4" channel scope in some cases.

Any way just a suggestion. Maybe there is already a way to do this and it is just not documented yet.

Doug

Example binaries fail with "segmentation fault"

screenshot1570186014

Same for the analog and digital binaries.
Might be related to #33, as this, taken directly from the examples/analog/getSamples.cpp file, also fails with "segmentation fault",

int main(int argc, char* argv[]) {
    M2k *ctx = m2kOpen();
    ctx->calibrateADC();
    ctx->calibrateDAC();
}

Pattern generator trigger

Add the functionality of configuring the DigitalOut interface so that the signal generation starts when an event on a different interface occurs.
The possible interfaces that can notify the DigitalOut are: AnalogIn, DigitalIn, TI and TO pins.

ERR: Invalid argument - No such context attributehw_serial

Open a Lidar context,

Context *context = ContextBuilder::contextOpen("ip:10.48.65.139");

And call the context interface getSerialNumber,

cout << context->getSerialNumber();

Result:

terminate called after throwing an instance of 'std::invalid_argument'
  what():  ERR: Invalid argument - No such context attributehw_serial

Compilation aborted (core dumped) at Mon Nov 11 18:38:33

Question anout analog input buffer

Hi:

In my testing so far it seems that the analog input buffer still contains some old data after I change the sample rate and maybe when I change the number of samples, SHOWsamples, in a call like this:
ain.getSamples(SHOWsamples)

Is there a way to flush out old samples after a change other than doing one or more extra ain.getSamples as dummy reads?

Thanks

Doug

Extracting values from SwigPyObject?

Hi:
Many of the libm2k functions return a SwigPyObject like
ain.getRangeLimits(0) returns:
<Swig Object of type 'std::pair< double,double > *' at 0x06A0E8A8>
ain.getAvailableRanges() returns
<Swig Object of type 'std::vector< libm2k::analog::M2K_RANGE,std::allocator< libm2k::analog::M2K_RANGE > > *' at 0x065DF0C8>

How do I convert or extract these Swig objects to normal python variables?

Thanks

Doug

Multiple errors while using generic devices from a context

  1. Open a Lidar context,
Context *context = ContextBuilder::contextOpen("ip:10.48.65.139");
  1. Get all the analogIn devices,
auto all_analog_in = context->scanAllAnalogIn();

for (auto i = all_analog_in.begin(); i != all_analog_in.end(); ++i) {
    cout << *i << "\n";
}

Result (the devices are recognized, all good):

axi-ad9094-hpc
ad7091
  1. Try to get an analogIn device and print it's name (same as above, only each device individually):
libm2k::analog::GenericAnalogIn* dev_in = context->getAnalogIn("ad7091");
cout << dev_in->getDeviceName();

Result:

Compilation segmentation fault (core dumped)
  1. Try the same but with index instead of a string,
libm2k::analog::GenericAnalogIn* dev_in = context->getAnalogIn(0);
cout << dev_in->getDeviceName();

Result: "" (empty string)

  1. Ignore the above and try to get some samples,
dev_in->getSamples(100);

Result:

terminate called after throwing an instance of 'std::invalid_argument'
  what():  ERR: Invalid argument - Buffer: No channel enabled for RX buffer

Compilation aborted (core dumped)

How are these generic classes to be used? Should they not be used directly like that? Should one derive from these classes and implement additional functionality for them to work? At the moment it doesn't seem like I can do much with them, except reading their string representation.

Edit: Last error seems to be "no channel enabled". That seems obvious. I'll try to redo that last example.

Edit2:
6. enable at least a channel before trying to refill the buffer

dev_in->enableChannel(1, true);
dev_in->getSamples(100);

Result

terminate called after throwing an instance of 'std::invalid_argument'
  what():  ERR: Invalid argument - Buffer: Cannot refill RX buffer

I've tried with both devices, index 0 and index 1 since I'm not sure which is which and tried to enable different channels. Same result.

DAC seems to be worked wrong in lower sampling frequency

Hello

I noticed a problem when I tried to get 1KHz of analog sin wave using function generater with Python program. The problem is that the frequency of the output sin wave is differ depending on the setting for sampling frequency of DAC. The code is as follows:

import libm2k
import matplotlib.pyplot as plt
import numpy as np

ctx=libm2k.m2kOpen()
if ctx is None:
	print("Connection Error: No ADALM2000 device available/connected to your PC.")
	exit(1)

INFS = 100000    # 100KHz -> 1/1000 decimation

#OUTFS = 75000000 # 75MHz  -> no interpolation
OUTFS = 7500000  # 7.5MHz -> 10x interpolation
#OUTFS = 750000   # 750KHz -> 100x interpolation
#OUTFS = 75000     # 75KHz -> 1000x interpolation

TESTFREQ = 1000
TESTLEN = 50000

ctx.calibrateADC()
ctx.calibrateDAC()

ain=ctx.getAnalogIn()
aout=ctx.getAnalogOut()

ain.enableChannel(0,True)
ain.setSampleRate(INFS)
ain.setRange(0,-10,10)

aout.setSampleRate(0, OUTFS)
aout.enableChannel(0, True)

period_out = OUTFS/TESTFREQ
x = np.linspace(0,2*np.pi,period_out,endpoint=False)
sig = np.sin(x)
buf = [sig]

aout.setCyclic(True)
aout.push(buf)

period_in = int(INFS/TESTFREQ)
data = ain.getSamples(TESTLEN)
plt.plot(data[0][0::period_in])
plt.ylim(-1.5,1.5)
plt.show()

libm2k.contextClose(ctx)

I wired W1->1+ and GND->1-. Then I ran this program with setting OUTFS to 75MHz or 7.5MHz I got DC on graph. Otherwise, sine wave appears in the graph. As the ADC sampling frequency is fixed, this means the frequency of sin wave changed when lower sampling frequency for DAC. Also can be observed this by using FFT.

Is there any solution about above things?

7 5MHz
750KHz

Link to 'nightly' build

Hi:
I know you are not yet ready apparently to put out an official release, but can you for right now add a link to the 'nightly' build on AppVeyor on the Read Me page?

Thanks

Doug

DeviceGeneric assumes all output channels are called "voltageX"

DeviceGeneric searches for all the device's channels at init. But it assumes all the output channels are of the form "voltageX" where X is from 0 to nb_channels.

In devicegeneric_impl.cpp

std::string name = "voltage" + std::to_string(i);
chn = new Channel(m_dev, name.c_str(), true);

But the 7c700000.axi-pulse-capture device has an output channel named altvoltage0, for example.

As a result, m_channel_list remains empty after init, as no valid channels are discovered during the generic device initialization.

What's going wrong here?

Hi:
As you will see in error captured from the Python shell, I'm running 3.7.3 on a 64 bit Windows 7 computer. I installed libm2k for windows using libm2k-system-setup.exe from this Appveyor build:

https://ci.appveyor.com/project/analogdevicesinc/libm2k/builds/26172407/artifacts

I downloaded the simplest example powersupply.py and tried to run it but it failed???

Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

==================== RESTART: C:\ALICEm2k\powersupply.py ====================
Traceback (most recent call last):
File "C:\ALICEm2k\powersupply.py", line 1, in
import libm2k
File "C:\Python37\lib\site-packages\libm2k.py", line 15, in
import _libm2k
ImportError: DLL load failed: %1 is not a valid Win32 application.

So my question. What's going wrong here? What's missing in this installation?

Thanks

Doug

CMake requirements incorrect

To use the cmake command SWIG_ADD_LIBRARY requires CMake 3.8, need to bump the required version or tweak the python bindings cmake file. Might want to check how easy 3.8 is to get on Ubuntu.

Missing _libm2k.pyd building on mac

Hi,

I'm trying to use libm2k Python binding on Mac.
Followed "Building on OSX" section at
https://wiki.analog.com/libm2k
then ran

python setup.py install

It looks the compilation and installation succeed. But importing libm2k fails.

import libm2k
Traceback (most recent call last):
File "", line 1, in
File "/Users/ssato/anaconda3/envs/iio/lib/python3.6/site-packages/libm2k-0.1.0-py3.6.egg/libm2k.py", line 15, in
ModuleNotFoundError: No module named '_libm2k'

Checking inside egg (and also build directory), there are

  • _libm2k.so
  • libm2k.py

files but there is no _libm2k.pyd file.

Attached is the log during build.
build_log.txt

I'd appreciate any advice what to try to make it work.

Potential bug with libm2k windows installer?

Dear Developers,

This might not be an urgent issue but as we were formalizing the libm2k & libiio installation instructions for students we noticed one thing about the libm2k windows installer:

The Python version we used is 3.7.4.
The libm2k installer (system-setup.exe) is downloaded from this link (master 570):
https://ci.appveyor.com/project/analogdevicesinc/libm2k/builds/29924208/artifacts
The libiio installer is downloaded from:
https://github.com/analogdevicesinc/libiio
by selecting the "Primary Installer Package" for Windows.

Previously, we have always run the libiio installer first and then run the libm2k installer, after which we could run our Python programs without issues.

But today we noticed that, if the libiio is not already installed and we run libm2k installer, it will return 3 checkboxes:
1)Install libm2k Python 3.7 bindings
2)Install libiio
3)Install libm2k tools

However, after the installation is finished, if we ran the Python programs we will get the following error message:
import _libm2k
ImportError: DLL load failed: The specified module could not be found.

Running the libiio installer and finish the installation will fix the error.

Now, in the second test, we first ran the libiio installer to install libiio, and then run the libm2k installer. In this case, the installer is able to detect the already installed libiio and return the following 3 checkboxes:

1)Install libm2k Python 3.7 bindings
2)Overwrite libiio
3)Install libm2k tools

Finish the installation and we can run programs without any errors.

What might be an issue is that the libm2k installer does not actually install the libiio even if the checkbox option "install libiio" is selected. If we look at the installed programs by going to control panel->Uninstall or change a program. Four components need to be there in order for the programs to run without errors: libm2k, libiio, libm2k Python bindings, libiio Python bindings. Running the libm2k installer alone with "install libiio" checkbox selected will still only install libm2k & libm2k Python bindings.

Thanks!
Steven

calibrateDAC causes the waveform generation to fail.

Running with ADALM2000, on Windows 10 64-bit, either with Python analog.py example or C analog.exe, analog output doesn't work at all, the waveform never appears on the relevant pins.
For reference, signal generation works fine with Scopy and Alice M2K, just not libm2k.
Also, after running either analog.exe or analog.py first, analog output stops working completely, either through Scopy or Alice M2K. It appears that libm2k crashes something inside the ADALM2000 itself, and it needs to be power cycled to start working in Scopy again.

Commenting out line that calls calibrateDAC() fixes the problem completely.

Save/Load calibration in Context

Create Calibration class which contains all calibration values.These values can be loaded/saved at runtime by the user or by calling calibrateADC/calibrateDAC

Unable to build the latest version of libm2k on linux

Hey Guys,
I have been using ADALM2000 with libm2k on Windows System and the fix last month on pushing non-cyclic buffers has helped me a lot on a project I am working on. Now we need to run our programs on a Linux system, and therefore I would have to install the latest version of libm2k. However, after following the commands provided on "https://github.com/analogdevicesinc/libm2k/wiki/Building-libm2k-on-Linux" I was getting errors in building libm2k. One of the errors says "class M2K Digital has no member named 'getTriggerMode', did you mean 'getTrigger'?" I know in our latest commits some functions haven been renamed and I noticed a file named "LinuxPackaging.cmake" was 4 month old. Is that the reason that we are unable to build the latest libm2k on linux? (I am new to Linux and CMake...)

Thanks in advance for your help!
Steven

missing some Cmake vars?

Following instructions at:
https://wiki.analog.com/university/tools/m2k/libm2k/libm2k

rgetz@brain:~/github/libm2k/build$ sudo apt-get install git cmake swig g++ python3-dev python3-setuptools
Reading package lists... Done
Building dependency tree       
Reading state information... Done
cmake is already the newest version (3.13.4-1).
g++ is already the newest version (4:8.3.0-1).
python3-setuptools is already the newest version (40.8.0-1).
python3-dev is already the newest version (3.7.3-1).
python3-dev set to manually installed.
swig is already the newest version (3.0.12-2).
git is already the newest version (1:2.20.1-2+deb10u3).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
rgetz@brain:~/github/libm2k/build$ rm * -rf
rgetz@brain:~/github/libm2k/build$ cmake ../ -DENABLE_PYTHON=ON
-- The CXX compiler identification is GNU 8.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/bin/git (found version "2.20.1") 
-- Found SWIG: /usr/bin/swig3.0 (found version "3.0.12") 
---- Building Python bindings
-- Found Python: /usr/bin/python3.7 (found version "3.7.3") found components:  Interpreter Development 
CMake Warning (dev) at /usr/share/cmake-3.13/Modules/UseSWIG.cmake:564 (message):
  Policy CMP0078 is not set.  Run "cmake --help-policy CMP0078" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.
Call Stack (most recent call first):
  bindings/python/CMakeLists.txt:54 (SWIG_ADD_LIBRARY)
This warning is for project developers.  Use -Wno-dev to suppress it.

---- Building C# bindings
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rgetz/github/libm2k/build

looking at the warnings:

rgetz@brain:~/github/libm2k/build$ cmake --help-policy CMP0078
CMP0078
-------

Starting with CMake 3.13, ``UseSWIG`` generates now standard target
names. This policy provides compatibility with projects that expect the legacy
behavior.

The ``OLD`` behavior for this policy relies on
``UseSWIG_TARGET_NAME_PREFERENCE`` variable that can be used to specify an
explicit preference.  The value may be one of:

* ``LEGACY``: legacy strategy is applied. Variable
  ``SWIG_MODULE_<name>_REAL_NAME`` must be used to get real target name.
  This is the default if not specified.
* ``STANDARD``: target name matches specified name.

This policy was introduced in CMake version 3.13.  CMake version
3.13.4 warns when the policy is not set and uses ``OLD`` behavior.
Use the ``cmake_policy()`` command to set it to ``OLD`` or ``NEW``
explicitly.

.. note::
  The ``OLD`` behavior of a policy is
  ``deprecated by definition``
  and may be removed in a future version of CMake.

libiio error codes are not handled

libiio provides error codes for most of it's calls, but these errors are mostly not taken into consideration in libm2k. That is, the return value of the iio call is either not used anywhere, or the error code and/or string is not logged nor thrown in the exception.

Some examples,

/* In devicegeneric_impl.cpp. Return value not considered.
if (Context::iioDevHasAttribute(m_dev, attr)) {
    iio_device_attr_read(m_dev, attr.c_str(), value, sizeof(value));  /* <------ */
} else {
    throw_exception(EXC_INVALID_PARAMETER, dev_name +   " has no " + attr + " attribute");
/* In devicegeneric_impl.cpp. Return value considered, but not handled. */
/* The thrown string does not contain the reason for the error. */
int ret = iio_context_get_attr(m_context, attrIdx, &name, &value);
    if (ret < 0) {
        throw_exception(EXC_RUNTIME_ERROR, "Device: Can't get context attribute " +
/* In context_impl.cpp. Return value not considered. */
iio_context_get_version(m_context, &ctx_major, &ctx_minor, ctx_git_tag);

etc, etc.

You can get the error string from the error code with the iio_strerror function provided by libiio. The return value for the functions that do return an error code is

  • @return On success, 0 is returned
  • @return On error, a negative errno code is returned

There are currently 134 defined errors in libiio.

This is just ignoring useful information that could prove useful in case of bugs and/or abnormal behavior from the library.

Configure DAC trigger

Add the functionality of configuring the AnalogOut interface so that the signal generation starts when an event on a different interface occurs.
The possible interfaces that can notify the AnalogOut are: AnalogIn, DigitalIn, TI and TO pins.

Mixed signal acquisition

Create a functionality so that the end-user can easily synchronize the digital and analogical acquisition.

m2k and fmcomms are products, not devices

Both m2k and fmcomms appear as devices throughout the code, but they are products (as it's clearly stated on their official ADI product pages [1] [2]), available through contexts, that they themselves contain multiple devices.

Some examples,

In contextbuilder.hpp,

enum DeviceTypes {
    DevFMCOMMS,
    DevM2K,
    Other
};

In the folder structure,

libm2k/src/devices/FMCOMMS
libm2k/src/devices/M2K

In enums.hpp. Similar name to enum DeviceTypes from above, different contents,

namespace utils {
	enum DEVICE_TYPE {
		ANALOG_DEV = 1,
		DIGITAL_DEV = 2,
		NO_DEV = 3
	};
...
}

In the devices namespace (m2k.hpp), where it clearly inherits from a context,
so from a product, so clearly not a device,

namespace devices {
    class LIBM2K_API M2k : public Context

Device has a special meaning within IIO, and it corresponds to a single hardware sensor and it provides all the information needed by a driver handling a device. [3], or devices are in some sense analog to digital or digital to analog converters [4].

Redefining already established terminology both in the Linux IIO community and in ADI's own documentation only adds unnecessary confusion and complexity for no actual gain.

[1] m2k
[2] fmcomms
[3] Linux kernel device terminology
[4] Analog Device's own terminology

deviceOpen-ing a device not in m_dev_map throws 'std::logic_error'

I have a valid network device (LiDAR), that can be opened and handled via libiio,

iio_context* ctx = iio_create_context_from_uri("ip:10.48.65.117");
cout << iio_context_get_name(ctx);

=> network

Trying to do the same with libm2k throws a 'std::logic_error',

Context *context = ContextBuilder::deviceOpen("ip:10.48.65.117");

=> terminate called after throwing an instance of 'std::logic_error'
         what():  basic_string::_M_construct null not valid

Compilation aborted (core dumped) at Mon Oct  7 11:55:08

Expected result: a generic device (product, actually) is returned which would support at least some identification functions from iiolib (list of devices, context name, context attributes, etc..)

Short code-jumping without actually knowing where the problem comes from,

  • identifyDevice returns Other if device is not in m_dev_map list, which is the case of the device from above (ok).

  • m_dev_name_map.at(type) in buildDevice should then return Generic (ok).

  • ContextImpl constructor then receives the device uri together with the Generic name for this device. I'm not sure what the Generic name is used for as it doesn't appear to be used in this constructor. So the fact that this device is not in the list of known devices is not taken into consideration?! Maybe you're assuming this is a known device and try to stuff it doesn't actually support?! I'm just assuming here.

Calling context methods on an m2k object fails with "segmentation fault"

This returns the actual device description,

Context *context = ContextBuilder::deviceOpen("usb:1.2.5");
string desc = context->getContextDescription();

But this fails with a segmentation fault error, using the same context object from above,

M2k *m2k = context->toM2k();
string desc = m2k->getContextDescription();

The same thing happens to the rest of the m2k methods that I've tested, like getAllDevices, getSerialNumber, calibrateADC, etc. The same thing happens when the object is instantiated directly with M2k *context = m2kOpen();.

M2k extends the Context class and the Context class has some of these methods as public, so it would be expected that these methods can also be called from an M2k instance without any problem.

Some atributes have changed / nolonger work in libm2k master.402 build?

Hi:
I just updated my version of libm2k (with Python bindings) and something has changed that renders this error:

Traceback (most recent call last):
File "C:\ALICEm2k\alice-desktop-2.1.pyw", line 17613, in
ConnectDevice() # find attached M2K
File "C:\ALICEm2k\alice-desktop-2.1.pyw", line 8162, in ConnectDevice
trig.setAnalogCondition(0,libm2k.RISING_EDGE) # RISING_EDGE)
AttributeError: module 'libm2k' has no attribute 'RISING_EDGE'

The example code here seems to still have this usage:

#uncomment the following block to enable triggering
#trig.setAnalogSource(0) # Channel 0 as source
#trig.setAnalogCondition(0,libm2k.RISING_EDGE)
#trig.setAnalogLevel(0,0.5) # Set trigger level at 0.5
#trig.setAnalogDelay(0) # Trigger is centered
#trig.setAnalogMode(1, libm2k.ANALOG)

Can't find where in the source code the allowed attributes are enumerated and the auto generated help does not list allowed values for the various functions:

https://analogdevicesinc.github.io/libm2k/group__m2ktrigger.html#ga276a274638000400f8c6ccf2efcb18c5

This is another place where things no longer seem to work for aout.push(buffer)

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python37\lib\tkinter_init_.py", line 1705, in call
return self.func(*args)
File "C:\ALICEm2k\alice-desktop-2.1.pyw", line 14046, in onAWGBscroll
UpdateAWGB()
File "C:\ALICEm2k\alice-desktop-2.1.pyw", line 10153, in UpdateAWGB
aout.push(buffer)
File "C:\Python37\lib\site-packages\libm2k.py", line 1582, in push
return _libm2k.M2kAnalogOut_push(self, *args)
ValueError: Module libm2k error: ERR: Invalid argument - Buffer: Can't create the TX buffer

So what is a programmer supposed to do?

Thanks

Doug

Do not destroy TX buffer after canceling it

A later issue revealed an inconsistency in destroying the RX buffer in a multithreaded program after both canceling and refilling the buffer.
In the current version of the library, stopping a TX buffer is performed by canceling and destroying the buffer. Also when the push function returns an error code, the buffer is destroyed. This may lead in the same problem described at #142.

listDevices() returns contexts, not devices, as its name would suggest

There are two functions for returning a list of devices as strings. One of them, getAllDevices actually returns what it says it is returning, but the other one, listDevices, returns contexts and not devices as it's name would suggest.

Example code,

auto devs = ContextBuilder::listDevices();
for (auto dev = devs.begin(); dev != devs.end(); ++dev)
    cout << *dev << " ";
==> usb:1.2.5 
;; This returns the available contexts, not devices (confusing).
Context *context = ContextBuilder::deviceOpen("usb:1.2.5");
unordered_set<string> devices = context->getAllDevices();
for(auto dev = devices.begin(); dev != devices.end(); ++ dev) {
    cout << *dev << ", ";
==> cf-ad9361-lpc, cf-ad9361-dds-core-lpc, adm1177, xadc, ad9361-phy
;; This actually returns what it's name suggests, devices (ok).

A better name would be listContexts, or even getAllContexts since it has a similar structure with getAllDevices.

How do I set or change the scope input hardware offset?

Hi:

I'm going through the various things I used in libiio to control the m2k and finding the corresponding function in libm2k. I'm finding a lot of them but have not found how to set or control the analog input channel hardware DC offset, used to change the vertical position. This was done in libiio by changing the value sent to the ad5625 quad DAC as follows:

ad5625 = ctx.find_device("ad5625")
Scope1Offset = ad5625.find_channel("voltage2", True)
Scope2Offset = ad5625.find_channel("voltage3", True)
Scope1Offset.attrs["raw"].value = '2009'
Scope2Offset.attrs["raw"].value = '2028'

Changing the DC offset or position is a very important function which allows for example, in the high gain range setting the nominal -2.5 V to 2.5 V span to be shifted to 0 to +5 V.

So the question is what function in the API is used to do this?

Thanks

Doug

getSamplesRawInterleaved and manually converting from raw sample to voltage

Dear Developers,

Thank you for the latest fix on the python bindings which made it possible for us to get samples faster by using the getSamplesRawInterleaved function. However, after playing with the function for a while and looking through the newly implemented convertRawToVolts() and convRawToVolts() functions, I have a few questions regarding the raw samples and its conversion to the float point voltage:

  1. The first thing I noticed is that if I call getSamplesRawInterleaved(10000), for example, it will return an array of 40000 samples of integer type. I initially expected to see 20000 because my understanding was that samples of two channels (analog in 1 and analog in 2) are interleaved and thus generating two times of samples... How should I properly interpret the samples returned by the getSamplesRawInterleaved function? (Is that because we are getting 1+,1- ,2+,2- and thus four times of samples?) Since in our project we are only using one channel (1+,1-), I am thinking about extracting the samples using Python slicing (e.g.: data_demultiplexed1=list(data)[0::4]) but not sure which positions of samples correspond to analog input 1.

  2. The second issue is that since we have adopted multiprocessing in our communication system, on the receiver side there are two parallel processes: 1. A process continuously call getSamples and pass the samples to the second process through Python queue. 2. A process does all the processing job such as demodulation of OOK samples.
    Now I would like to process the raw samples on the second process, but it doesn't have access to the context and cannot control m2k (I called ctx=libm2k.m2kOpen() in the first "getsamples" process already). Now, in order to process the raw samples and converting them to float point voltage, I have the following idea and could you guys kindly check if it makes sense?

  3. Use the first process, which has control over m2k, to obtain hw_gain, correctionGain, filterCompensation, offset.

  4. Pass these four parameters to process 2 via queue.

  5. Plug into the formula ((sample * 0.78) / ((1 << 11) * 1.3 * hw_gain) *correctionGain * filterCompensation) + offset to obtain the samples.

Since we are really concerned about the processing time, I would like to know if hw_gain, correctionGain, filterCompensation, offset are constantly changing while ADALM is running? If not, once the calibration is done and the ADALM is initiated I can only pass these four parameters through queue once and not worrying about them again...

Finally, could you please confirm what functions to call in order to get the hw_gain, correctionGain, filterCompensation, offset? I kind of know getValueForRange gives hw_gain and getFilterCompensation gives filterCompensation but not sure about the other two..

Thank you very much and we appreciate any insights you guys could provide!

Thanks,
Steven

Provide getSamplesInVector methods

Provide getSamplesInVector methods. These methods will get the samples in a buffer that is created/owned by the client, therefore no allocation is done in the library.

Add command-line tools

Add M2K examples that will be deployed with the library and can be used as command-line tools such as:

  • Setup the ADC and capture samples: Example: ./m2k_capture < samplerate > <trigger y/n>
  • Setup the DAC and push samples: Example: ./m2k_generate < samples_file.csv
  • Similar for the digital part.
  • Calibrate ADC/DAC
  • Get voltage

Each tool should be designed with the appropriate parameters.
This list should be expanded.

OS X Build Problem with Exceptions

I am trying to build libm2k from the master repo on Mac OS X 10.14.5, and there appears to be a problem with exception handling in the include files. Recurring error of "use of undeclared identifier '__try'"

For context, I have installed libiio via MacPorts (https://github.com/macports/macports-ports/blob/master/science/libiio/Portfile).

My command log and output are below.

[JNL-ND-iMac:] jnl% uname -a
Darwin JNL-ND-iMac.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4
2/RELEASE_X86_64 x86_64
[JNL-ND-iMac:] jnl% git clone https://github.com/analogdevicesinc/libm2k.git
Cloning into 'libm2k'...
remote: Enumerating objects: 43, done.
remote: Counting objects: 100% (43/43), done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 2225 (delta 14), reused 20 (delta 6), pack-reused 2182
Receiving objects: 100% (2225/2225), 699.90 KiB | 3.17 MiB/s, done.
Resolving deltas: 100% (1498/1498), done.
[JNL-ND-iMac:
] jnl% cd libm2k
[JNL-ND-iMac:~/libm2k] jnl% cmake ./
-- The CXX compiler identification is AppleClang 10.0.1.10010046
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/bin/git (found version "2.20.1 (Apple Git-117)")
-- Found SWIG: /opt/local/bin/swig (found version "3.0.12")
---- Building Python bindings
-- Found PythonLibs: /opt/local/lib/libpython2.7.dylib (found version "2.7.10")
-- Found PythonInterp: /opt/local/bin/python2.7 (found version "2.7.16")
CMake Warning (dev) at /opt/local/share/cmake-3.14/Modules/UseSWIG.cmake:600 (message):
Policy CMP0078 is not set: UseSWIG generates standard target names. Run
"cmake --help-policy CMP0078" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.

Call Stack (most recent call first):
bindings/python/CMakeLists.txt:23 (SWIG_ADD_LIBRARY)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at /opt/local/share/cmake-3.14/Modules/UseSWIG.cmake:460 (message):
Policy CMP0086 is not set: UseSWIG honors SWIG_MODULE_NAME via -module
flag. Run "cmake --help-policy CMP0086" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.

Call Stack (most recent call first):
/opt/local/share/cmake-3.14/Modules/UseSWIG.cmake:695 (SWIG_ADD_SOURCE_TO_MODULE)
bindings/python/CMakeLists.txt:23 (SWIG_ADD_LIBRARY)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jnl/libm2k
[JNL-ND-iMac:~/libm2k] jnl% make all
Scanning dependencies of target libm2k
[ 1%] Building CXX object src/CMakeFiles/libm2k.dir/analog/dmm.cpp.o
[ 3%] Building CXX object src/CMakeFiles/libm2k.dir/analog/genericanalogin.cpp.o
In file included from /Users/jnl/libm2k/src/analog/genericanalogin.cpp:20:
/Users/jnl/libm2k/src/analog/private/genericanalogin_impl.cpp:51:35: warning:
'libm2k::analog::GenericAnalogIn::GenericAnalogInImpl::getSamples' hides
overloaded virtual functions [-Woverloaded-virtual]
std::vector<std::vector> getSamples(unsigned int nb_samples,
^
/Users/jnl/libm2k/include/libm2k/utils/devicein.hpp:44:38: note: hidden
overloaded virtual function 'libm2k::utils::DeviceIn::getSamples' declared
here: different number of parameters (1 vs 2)
virtual std::vector getSamples(unsigned int nb_samples);
^
/Users/jnl/libm2k/include/libm2k/utils/devicein.hpp:45:44: note: hidden
overloaded virtual function 'libm2k::utils::DeviceIn::getSamples' declared
here: type mismatch at 2nd parameter ('std::function<double
(int16_t, unsigned int)>' (aka 'function<double (short, unsigned int)>')
vs 'bool')
virtual std::vector<std::vector > getSamples(unsigned in...
^
In file included from /Users/jnl/libm2k/src/analog/genericanalogin.cpp:20:
/Users/jnl/libm2k/src/analog/private/genericanalogin_impl.cpp:94:15: warning:
private field 'm_nb_channels' is not used [-Wunused-private-field]
unsigned int m_nb_channels;
^
/Users/jnl/libm2k/src/analog/private/genericanalogin_impl.cpp:95:7: warning:
private field 'm_cyclic' is not used [-Wunused-private-field]
bool m_cyclic;
^
3 warnings generated.
[ 5%] Building CXX object src/CMakeFiles/libm2k.dir/analog/genericanalogout.cpp.o
In file included from /Users/jnl/libm2k/src/analog/genericanalogout.cpp:20:
/Users/jnl/libm2k/src/analog/private/genericanalogout_impl.cpp:93:7: warning:
'libm2k::analog::GenericAnalogOut::GenericAnalogOutImpl::push' hides
overloaded virtual functions [-Woverloaded-virtual]
void push(std::vector const &data, unsigned int chn_idx)
^
/Users/jnl/libm2k/include/libm2k/utils/deviceout.hpp:44:15: note: hidden
overloaded virtual function 'libm2k::utils::DeviceOut::push' declared
here: different number of parameters (4 vs 2)
virtual void push(std::vector const &data, unsigned int channel,
^
/Users/jnl/libm2k/include/libm2k/utils/deviceout.hpp:46:15: note: hidden
overloaded virtual function 'libm2k::utils::DeviceOut::push' declared
here: different number of parameters (3 vs 2)
virtual void push(std::vector const &data, unsigned int ...
^
In file included from /Users/jnl/libm2k/src/analog/genericanalogout.cpp:20:
/Users/jnl/libm2k/src/analog/private/genericanalogout_impl.cpp:98:7: warning:
'libm2k::analog::GenericAnalogOut::GenericAnalogOutImpl::push' hides
overloaded virtual functions [-Woverloaded-virtual]
void push(std::vector const &data, unsigned int chn_idx)
^
/Users/jnl/libm2k/include/libm2k/utils/deviceout.hpp:44:15: note: hidden
overloaded virtual function 'libm2k::utils::DeviceOut::push' declared
here: different number of parameters (4 vs 2)
virtual void push(std::vector const &data, unsigned int channel,
^
/Users/jnl/libm2k/include/libm2k/utils/deviceout.hpp:46:15: note: hidden
overloaded virtual function 'libm2k::utils::DeviceOut::push' declared
here: different number of parameters (3 vs 2)
virtual void push(std::vector const &data, unsigned int ...
^
2 warnings generated.
[ 7%] Building CXX object src/CMakeFiles/libm2k.dir/analog/m2kanalogin.cpp.o
In file included from /Users/jnl/libm2k/src/analog/m2kanalogin.cpp:20:
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:161:35: warning:
'libm2k::analog::M2kAnalogIn::M2kAnalogInImpl::getSamples' hides
overloaded virtual functions [-Woverloaded-virtual]
std::vector<std::vector> getSamples(unsigned int nb_samples,
^
/Users/jnl/libm2k/include/libm2k/utils/devicein.hpp:44:38: note: hidden
overloaded virtual function 'libm2k::utils::DeviceIn::getSamples' declared
here: different number of parameters (1 vs 2)
virtual std::vector getSamples(unsigned int nb_samples);
^
/Users/jnl/libm2k/include/libm2k/utils/devicein.hpp:45:44: note: hidden
overloaded virtual function 'libm2k::utils::DeviceIn::getSamples' declared
here: type mismatch at 2nd parameter ('std::function<double
(int16_t, unsigned int)>' (aka 'function<double (short, unsigned int)>')
vs 'bool')
virtual std::vector<std::vector > getSamples(unsigned in...
^
In file included from /Users/jnl/libm2k/src/analog/m2kanalogin.cpp:20:
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:355:3: error: use of
undeclared identifier '__try'
__try {
^
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:372:3: error: use of
undeclared identifier '__try'
__try {
^
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:389:3: error: use of
undeclared identifier '__try'
__try {
^
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:405:3: error: use of
undeclared identifier '__try'
__try {
^
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:426:3: error: use of
undeclared identifier '__try'
__try {
^
/Users/jnl/libm2k/src/analog/private/m2kanalogin_impl.cpp:437:3: error: use of
undeclared identifier '__try'
__try {
^
1 warning and 6 errors generated.
make[2]: *** [src/CMakeFiles/libm2k.dir/analog/m2kanalogin.cpp.o] Error 1
make[1]: *** [src/CMakeFiles/libm2k.dir/all] Error 2
make: *** [all] Error 2

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

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

  • D3 photo D3

    Data-Driven Documents codes.