File: analog_sequential_triggering.py

package info (click to toggle)
libm2k 0.9.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 95,580 kB
  • sloc: xml: 1,611,497; cpp: 16,278; python: 4,181; cs: 516; sh: 471; ansic: 403; makefile: 35
file content (152 lines) | stat: -rw-r--r-- 5,749 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#
# Copyright (c) 2024 Analog Devices Inc.
#
# This file is part of libm2k
# (see http://www.github.com/analogdevicesinc/libm2k).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Requirements: x1 ADALM2000

This example assumes the following connections:
    W1      ->    1+
    W2      ->    2+
    GND     ->    1-
    GND     ->    2-
    DIO_0   ->    TI

This demo application alternates between generating a rising ramp signal and a sine wave on both output channels, W1 and W2.
The generated signal is then fed back into the analog input channels for further analysis or processing.
This rising edge is generated using the DIO_0  pin but could be generated from an external source.
The channel idles with the last sample of the current buffer until the next trigger event.

Rearm functionality:
    - When rearm is enabled, the non-cyclic buffers are sent sequentially after each trigger event.
    - When rearm is disabled, a trigger event will send all the buffers in the queue.

    NOTE: Due to HDL limitation it is recommend combining small buffers into a small buffers when REARM is disabled.
    NOTE: All buffers must be of the same size.
"""

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

# NOTE: change to see the effect of rearm on non-cyclic buffers
WITH_REARM = True

DAC_SR = 75_000_000
INPUT_BUFFER_SIZE = 20_000
DELAY = 8192
TRIGGER_THRESHOLD = 1

N_SAMPLES = 2048
AMPLITUDE = 5

# Each push operation consumes one kernel buffer for the specified channel. 
# Therefore, if you plan to perform N push operations, ensure that you have N + 1 kernel buffers available.
KB_COUNT_OUT = 5

def main():
    try:
        context: libm2k.M2k = libm2k.m2kOpen("ip:192.168.2.1")
        if context is None:
            print("Connection Error: No ADALM2000 device available/connected to your PC.")
            exit(1)

        ain: libm2k.M2kAnalogIn = context.getAnalogIn()
        aout: libm2k.M2kAnalogOut = context.getAnalogOut()
        dig: libm2k.M2kDigital = context.getDigital()
        trig: libm2k.M2kHardwareTrigger = ain.getTrigger()

        # Prevent bad initial configuration
        context.reset()
        context.calibrateADC()
        context.calibrateDAC()
        context.setTimeout(10_000)  # [ms]

        ain.setSampleRate(100_000_000)
        ain.enableChannel(libm2k.ANALOG_IN_CHANNEL_1, True)
        ain.enableChannel(libm2k.ANALOG_IN_CHANNEL_2, True)

        aout.setSampleRate(0, DAC_SR)
        aout.setSampleRate(1, DAC_SR)
        aout.enableChannel(0, True)
        aout.enableChannel(1, True)
        aout.setKernelBuffersCount(0, KB_COUNT_OUT)
        aout.setKernelBuffersCount(1, KB_COUNT_OUT)
        aout.setCyclic(False)

        dig.setSampleRateOut(100_000_000)
        dig.setDirection(libm2k.DIO_CHANNEL_0, libm2k.DIO_OUTPUT)
        dig.setOutputMode(libm2k.DIO_CHANNEL_0, libm2k.DIO_PUSHPULL)
        dig.setValueRaw(libm2k.DIO_CHANNEL_0, libm2k.LOW)
        dig.enableChannel(libm2k.DIO_CHANNEL_0, True)

        # ain acquisition trigger
        trig.setAnalogSource(libm2k.ANALOG_IN_CHANNEL_1)
        trig.setAnalogCondition(libm2k.ANALOG_IN_CHANNEL_1, libm2k.RISING_EDGE_ANALOG)
        trig.setAnalogLevel(libm2k.ANALOG_IN_CHANNEL_1, TRIGGER_THRESHOLD)
        trig.setAnalogDelay(-DELAY)
        trig.setAnalogMode(libm2k.ANALOG_IN_CHANNEL_1, libm2k.ANALOG)
        trig.setAnalogMode(libm2k.ANALOG_IN_CHANNEL_1, libm2k.ANALOG)

        # aout triggering: starts when the TI pin is triggered
        trig.setAnalogOutTriggerSource(libm2k.TRIGGER_TI)
        trig.setAnalogOutTriggerCondition(libm2k.RISING_EDGE_OUT)
        trig.setAnalogOutTriggerStatus(libm2k.START)
        aout.setBufferRearmOnTrigger(WITH_REARM)

        print("Starting acquisition ...")
        ain.startAcquisition(INPUT_BUFFER_SIZE)

        print("Sending waveforms to DAC ...")
        rising_ramp = AMPLITUDE * (np.linspace(-1, 1, N_SAMPLES))

        sine = AMPLITUDE * np.sin(np.linspace(0, 2 * np.pi, N_SAMPLES))
        # sine = AMPLITUDE * np.sin(np.linspace(0, 2 * np.pi, N_SAMPLES))

        aout.push([rising_ramp, rising_ramp])
        aout.push([sine, sine])
        aout.push([rising_ramp, rising_ramp])
        aout.push([sine, sine])

        for i in range(4 if WITH_REARM else 1):
            print("Waiting for trigger ...")
            time.sleep(0.5)

            print("Sending trigger event ...")
            dig.setValueRaw(libm2k.DIO_CHANNEL_0, libm2k.HIGH)

            data = np.array(ain.getSamples(INPUT_BUFFER_SIZE))
            time_axis = np.linspace(0, len(data[0]) / ain.getSampleRate(), len(data[0])) * 1e6
            plt.plot(time_axis, data[0], label="W1")
            plt.plot(time_axis, data[1], label="W2")
            plt.xlabel("Time [us]")
            plt.ylabel("Voltage [V]")
            plt.legend(loc="upper right")
            plt.grid(True)
            plt.show() 

            dig.setValueRaw(libm2k.DIO_CHANNEL_0, libm2k.LOW)
    except Exception as e:
        print("Timeout occurred ... No trigger event detected")
        print(e)

    libm2k.contextClose(context)


if __name__ == '__main__':
    main()