Documentation and Examples for Jupyter Notebooks:
Jupyter Notebooks file:
Code Explanation
Importing Libraries
import time
import numpy as np
from matplotlib import pyplot as plt
from rp_overlay import overlay
import rp
time
: Used for delaying operations, ensuring that processes have enough time to complete.numpy
: A library for numerical computations, crucial for handling and analyzing data.matplotlib.pyplot
: Provides plotting functions to visualize data and results.rp_overlay
: A specific library for interfacing with the Red Pitaya's FPGA functionality.rp
: The main library for controlling the Red Pitaya board, including signal generation and acquisition.
Initialization
# Initialize Red Pitaya overlay
fpga = overlay()
rp.rp_Init()
- Initializes the FPGA overlay for the Red Pitaya, allowing custom logic to be loaded and used.
- Initializes the Red Pitaya board for operation.
Constants for the Experiment
start_freq = 100 # Hz
freq_step = 100 # Hz increment
max_freq = 5000 # Hz, adjust as needed
ampl = 1 # Amplitude
N = 16384 # Number of samples for acquisition
initial_gain = None
dec = rp.RP_DEC_128 # Decimation
sampling_rate = 125e6 / dec # Adjusted for decimation
- Defines the starting frequency, frequency step, and maximum frequency for the signal generation.
- Sets the amplitude of the generated signals.
- Specifies the number of samples to acquire, which affects the resolution of the acquisition.
- Initializes a variable for storing the initial gain measurement.
- Sets the decimation factor to reduce the sampling rate, and calculates the effective sampling rate.
Acquisition Settings
trig_lvl = 0.5
trig_dly = 0
acq_trig_sour = rp.RP_TRIG_SRC_AWG_PE
- Configures the trigger level and delay for signal acquisition.
- Specifies the source of the acquisition trigger, here set to the Arbitrary Waveform Generator (AWG) positive edge.
Signal Generation
Within the loop, the code resets the generator and acquisition settings, then configures the signal generator for a sine wave at the current frequency and amplitude. It enables the output and triggers the generator.
rp.rp_GenReset()
rp.rp_AcqReset()
print(f"Generating {freq} Hz signal")
rp.rp_GenWaveform(rp.RP_CH_1, rp.RP_WAVEFORM_SINE)
rp.rp_GenFreqDirect(rp.RP_CH_1, freq)
rp.rp_GenAmp(rp.RP_CH_1, ampl)
rp.rp_GenOutEnable(rp.RP_CH_1)
rp.rp_GenTriggerOnly(rp.RP_CH_1)
- Resets the signal generator and acquisition modules to clear any previous settings or data.
- Configures the generator to produce a sine wave on channel 1 with the specified frequency and amplitude.
- Enables the output of the generated signal and sets it to trigger mode, preparing for signal acquisition.
Signal Acquisition
The acquisition settings are applied, including decimation and trigger configuration. The acquisition is started, and the script waits for the trigger condition to be met and for the buffer to be full.
rp.rp_AcqSetDecimation(dec)
rp.rp_AcqSetTriggerLevel(rp.RP_T_CH_1, trig_lvl)
rp.rp_AcqSetTriggerDelay(trig_dly)
rp.rp_AcqSetGain(rp.RP_CH_2, rp.RP_HIGH)
rp.rp_AcqStart()
rp.rp_AcqSetTriggerSrc(acq_trig_sour)
- Configures the acquisition module with the specified decimation, trigger level, and delay.
- Sets the gain for channel 2, assuming it's the channel where the processed signal is observed.
- Starts the acquisition process and specifies the trigger source to begin data capture.
Waiting for Acquisition to Complete
time.sleep(1) # Wait to ensure acquisition is ready
rp.rp_GenTriggerOnly(rp.RP_CH_1) # Trigger generation
- Introduces a delay to ensure the acquisition system is fully prepared for data capture.
- Triggers the signal generation, starting the acquisition cycle.
Data Retrieval and Analysis
After acquisition, the data for both channels is retrieved and converted to numpy arrays for analysis. At 100 Hz, a phase difference analysis is performed. For each frequency, the script calculates the gain in dB and checks if the gain has dropped by 3 dB from the initial value, indicating the -3 dB point.
fbuff_ch1 = rp.fBuffer(N)
rp.rp_AcqGetOldestDataV(rp.RP_CH_1, N, fbuff_ch1)
fbuff_ch2 = rp.fBuffer(N)
rp.rp_AcqGetOldestDataV(rp.RP_CH_2, N, fbuff_ch2)
- Retrieves the captured data from both channels into buffers.
- Converts these buffers into numpy arrays for analysis, taking advantage of numpy's powerful numerical and analytical functions.
Phase Analysis at 100 Hz
if freq == 100:
# FFT analysis, phase calculation, and printing phase difference.
# Plotting input and output signals at 100 Hz.
- Performs a Fast Fourier Transform (FFT) analysis to find the phase difference between the input and output signals at 100 Hz.
- Identifies whether the system is inverting or non-inverting based on the phase difference.
- Plots the input and output signals to visually assess their relationship at this frequency.
Gain Calculation and -3dB Point Check
input_amplitude = np.max(data_V_ch1) - np.min(data_V_ch1)
output_amplitude = np.max(data_V_ch2) - np.min(data_V_ch2)
gain = 20 * np.log10(output_amplitude / input_amplitude)
- Calculates the peak-to-peak amplitude of the input and output signals.
- Computes the gain in decibels (dB) to quantify how much the signal amplitude has been amplified or attenuated.
if initial_gain is None:
initial_gain = gain
- Sets the initial gain value for comparison in subsequent iterations.
if gain <= initial_gain - 3:
# Plotting and breaking the loop at the -3dB point.
- Checks if the gain has dropped by 3 dB from its initial value, indicating the -3 dB point, which is significant in frequency response analysis as it marks the bandwidth limit of the system.
- Plots the signals at this frequency and exits the loop, concluding the frequency sweep.
Plotting
For specific conditions (at 100 Hz and at the -3 dB point), the script generates plots showing the input and output signals.
Cleanup
rp.rp_Release()
- Releases the resources used by the Red Pitaya library, ensuring a clean shutdown.