Analog IO

The Red Pitaya features a set of 4 auxiliary analog inputs and 4 auxiliary analog outputs, based on the Zynq-7000 XADC (12-bit, 4x250kSa/s) and filtered PWM (12-bit, fc=190kHz). In this example we perform an analog ramp-up and ramp-down on analog_out_0 and analog_out_1, which are captured on analog_in_0 and analog_in_1.

Required hardware connection (see README for IO Names and Pin Mapping):

  • Header wires between analog_out_0 <-> analog_in_0

  • Header wires between analog_out_1 <-> analog_in_1

Imports

import time 
import numpy as np
from matplotlib import pyplot as plt
from openlabctrl.device import Rp_125_14_Z7010
from openlabctrl.sequence import IoSequence
from openlabctrl.frame import IoSyncFrame
from openlabctrl.io.scope import ScopeSource

Device instances

rp_0 = Rp_125_14_Z7010(ip="192.168.1.143", label="rp_0", force=True)

IO Sequences & IO Frames instances

seq = IoSequence(device_list=[rp_0])
fr_0 = IoSyncFrame(device_type=Rp_125_14_Z7010, trig=None)
fr_1 = IoSyncFrame(device_type=Rp_125_14_Z7010, trig=None)

Frame definitions

#FRAME O (initialization)
fr_0.reset()

fr_0.analog_out_0.duty_cycle(0)
fr_0.analog_out_1.duty_cycle(1)
fr_0.delay(10000)

#FRAME 1 (PWM sweep)
fr_1.reset()
fr_1.scope_0.source(ScopeSource.ANALOG_IN_0)
fr_1.scope_1.source(ScopeSource.ANALOG_IN_1)
fr_1.scope_0.decimation(500) # 250kSa/s
fr_1.scope_1.decimation(500) # 250kSa/s
fr_1.scope_0.acquire(400, label="acq_1")
fr_1.scope_1.acquire(400, label="acq_2")
fr_1.delay(1000)
fr_1.set_time_increment(500) # 250kSa/s
for i in range(256):
    fr_1.analog_out_0.duty_cycle(i/256)
    fr_1.analog_out_1.duty_cycle(1 - i/256)

Sequence definition

seq.reset()
seq.add_frame(frame=fr_0, device=rp_0, label="init")
seq.add_frame(frame=fr_1, device=rp_0, label="analog sweep")

print(seq.sequence_description())
+--------------------+
| rp_0@192.168.1.143 |
+--------------------+
| init               |
| analog sweep       |
+--------------------+
NOTE: Frames with (*) are triggered by external trigger source.

Upload & Run sequence

seq.upload()
seq.start()
while not seq.is_done():
    if seq.is_error():
        print("Sequence error. Please check status.")
        break
    time.sleep(0.01)
seq.get_status()
{'rp_0@192.168.1.143': {'enabled': True,
  'done': True,
  'error': False,
  'current_frame': 'analog sweep',
  'io': {'rf_out_0': {'error': False, 'done': True},
   'rf_out_1': {'error': False, 'done': True},
   'digital_io_0': {'error': False, 'done': True},
   'digital_io_1': {'error': False, 'done': True},
   'digital_io_2': {'error': False, 'done': True},
   'digital_io_3': {'error': False, 'done': True},
   'analog_out_0': {'error': False, 'done': True},
   'analog_out_1': {'error': False, 'done': True},
   'analog_out_2': {'error': False, 'done': True},
   'analog_out_3': {'error': False, 'done': True},
   'scope_0': {'error': False, 'done': True},
   'scope_1': {'error': False, 'done': True},
   'led': {'error': False, 'done': True}}}}
seq.stop()

Plot acquisitions

scope_dict = seq.get_scope()

for device_id in scope_dict.keys():
    for frame_label in scope_dict[device_id].keys():
        for scope_label in scope_dict[device_id][frame_label].keys():
            for acq_label in scope_dict[device_id][frame_label][scope_label].keys():
                t = scope_dict[device_id][frame_label][scope_label][acq_label]["t"]
                dec = scope_dict[device_id][frame_label][scope_label][acq_label]["dec"]
                samples = scope_dict[device_id][frame_label][scope_label][acq_label]["samples"]
                src = scope_dict[device_id][frame_label][scope_label][acq_label]["src"]
                data = scope_dict[device_id][frame_label][scope_label][acq_label]["data"]
                print(f"Device: {device_id}")
                print(f"Frame: {frame_label}")
                print(f"Scope: {scope_label}")
                print(f"Label: {acq_label}")
                print(f"Time: {t}")
                print(f"Decimation: {dec}")
                print(f"Samples: {samples}")
                print(f"Source: {src}")
                plt.figure()
                plt.plot(data)
                plt.show()
    
Device: rp_0@192.168.1.143
Frame: analog sweep
Scope: scope_0
Label: acq_1
Time: 2
Decimation: 500
Samples: 400
Source: ANALOG_IN_0
../_images/ff9d47fc0ad454530e1cacda69769fd7f1ad3abeae6f6e06af6b332c843ccc71.png
Device: rp_0@192.168.1.143
Frame: analog sweep
Scope: scope_1
Label: acq_2
Time: 2
Decimation: 500
Samples: 400
Source: ANALOG_IN_1
../_images/aeee14b45768fae4f90f2b9002d145ab873a8ff11e558521c49c9dda05eb47da.png