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
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