Skip to content

Continuous Triggered IQ Capture to .MAT Files Using the RSA API #22

@ImNiceButActuallyNot

Description

@ImNiceButActuallyNot

Description

Hi, I'm a new user of RSA API due to Signal-Vu being slower.

I tried to make a continuous capture of IQ data to .mat file and didn't find a relevant example.

I made one myself (the formatting of .mat is the same as Signal-Vu's):


def continuous_block_iq_by_trigger(
            self,
            file_path: str,
            freq: float            = 2.402,
            ref_level_dbm: float   = 0.0,
            span: float            = 10e6,
            capture_ms: float      = 1e-3,
            trig_level_dbm: float  = -35.0,
            captures_num: int      = 300000
        ):
        freq =  freq * 1e9  # Convert GHz to Hz
        span = span * 1e6    # Convert MHz to Hz
        recordLength = int(span * capture_ms)
        os.makedirs(file_path, exist_ok=True)
        
        captures_num = 300000
        self.rsa.TRIG_SetTriggerSource(TriggerSource.TriggerSourceIFPowerLevel)
        self.rsa.TRIG_SetTriggerTransition(TriggerTransition.TriggerTransitionLH)
        self.rsa.TRIG_SetIFPowerTriggerLevel(c_double(trig_level_dbm))
        self.rsa.TRIG_SetTriggerMode(TriggerMode.triggered))
        self.rsa.TRIG_SetTriggerPositionPercent(c_double(1.0))

        self.rsa.CONFIG_SetAutoAttenuationEnable.argtypes = [c_bool]
        self.rsa.CONFIG_SetAutoAttenuationEnable(c_bool(False))

        self.rsa.CONFIG_SetRFPreampEnable.argtypes = [c_bool]
        self.rsa.CONFIG_SetRFPreampEnable(c_bool(True))

        self.rsa.CONFIG_SetRFAttenuator.argtypes = [c_double]
        self.rsa.CONFIG_SetRFAttenuator(c_double(0.0))

        # updated call: freq, span
        self.config_block_iq(freq, ref_level_dbm, span, recordLength)

        sr = c_double()
        self.err_check(self.rsa.IQBLK_GetIQSampleRate(byref(sr)))
        fs = sr.value

        print(f'Armed for triggers @ {freq/1e6:.3f} MHz, {span/1e6:.1f} MHz BW…')

        capture_index = 0
        while (not self._stop_event.is_set()) and (capture_index < captures_num):

            iq = self.acquire_block_iq(recordLength)

            metadata_xml = (
                f'<DataFile>\n'
                f'  <CenterFrequency units="Hz">{freq}</CenterFrequency>\n'
                f'  <Span units="Hz">{span}</Span>\n'
                f'  <SampleRate units="Hz">{fs}</SampleRate>\n'
                f'</DataFile>'
            )

            mat_dict = {
                'rsaMetadata': np.array([metadata_xml], dtype='<U'),
                'InputCenter': np.array([[freq]]),
                'InputZoom':   np.array([[1]], dtype=np.uint8),
                'Span':        np.array([[span]]),
                'XDelta':      np.array([[1.0 / fs]]),
                'Y':           iq.astype(np.complex64)
            }

            ts = dt.datetime.now().strftime("%Y%m%d_%H%M%S_%f")
            fname = os.path.join(
                file_path,
                f"iq_{int(freq/1e6)}MHz_{ts}.mat"
            )
            savemat(fname, mat_dict)
            capture_index += 1

I used a separate thread to start the recording, and I stop the capture by terminating the thread.

Is there an easier way to do this? If so, could it be added as a feature?

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions