Any solution with OS version 2.00 for fast on on-trigger acquisition?

Applications, development tools, FPGA, C, WEB
Post Reply
werefkin
Posts: 7
Joined: Tue Jan 26, 2021 4:16 pm

Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by werefkin » Wed Apr 26, 2023 10:19 pm

Hi there,
As a new OS version is released I decided to dive again into the speeds of on-trigger acquisition available out of the box with SCPI. The latest versions before this required minimum of 100 ms to transfer the buffer to a PC independently on the frequency. It seems that the situation did not change, even though some possible solutions to this issue were discussed e.g. back to 2017:
viewtopic.php?t=1390
viewtopic.php?t=2018
https://github.com/alex123go/RedPitaya_Acquisition

Is there a ready to use (well described) solution to a problem? I found most of the manuals a bit old (e.g. rp_remote_acquire from the first example is not available anymore) or to have a very high entrance level -- there is some gap between compiling a C blinking app on the RP that is given as an example and this task.
Besides, with a new version also new functionally (or wrappers) seems to appear, like functions in a python library; a new example says e.g. rp_s.acq_set(), but one cannot check them, apparently these functions not yet in the redpitata.scpi in the official git repository to test. Is this just the same code wrapped to the functions?

I believe that this issue (together with a lack of manuals) is critical for many applications, and therefore reduces the attractiveness of these great devices for a general engineer.

User avatar
redpitaya
Site Admin
Posts: 883
Joined: Wed Mar 26, 2014 7:04 pm

Re: Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by redpitaya » Wed May 03, 2023 2:12 pm

Hello werefkin,

Thank you for the comment.

The best way to achieve fast data acquisition on Red Pitaya is to make a C program running on the board or to reprogram the FPGA. This way, you can avoid network delays.

For fast data transfer to your computer please use the Streaming application:
https://redpitaya.readthedocs.io/en/lat ... #streaming

The functions do not make the program run any faster - they just include the (ideal) sequence of SCPI commands (so that you only specify parameters and the function sends the relevant SCPI commands) - it is a quality-of-life improvement.

The functions can be found here (they will appear in the redpitaya_scpi.py after the merge):
https://github.com/RedPitaya/RedPitaya/pull/252

We did, however, add the option of setting the external trigger debounce filter (this way the acquisition trigger can be set in microseconds) - ACQ:TRIG:EXT:DEBouncerUs <utime> (SCPI command)

arparker
Posts: 10
Joined: Thu Jul 24, 2014 2:04 am

Re: Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by arparker » Mon Jun 12, 2023 2:14 am

We have been using the RP for a number of years (4) using a version of the OS (0.94) that has worked well thus far. We are using an external trigger and external clock and are able to achieve buffer sizes of up to 512K samples at 20Hz using a modified version of the axi_adc.c code. We would like to move to the latest version of the OS and take advantage of i2c (which was not working in the older version) to control a device in our system while acquiring data. Unfortunately, our code does not work with the latest version of the OS so I'm looking for a new version of the API under V2.0 that will handle AXI properly. The documentation offers an example for the "AXI mode" (section 2.3.3 of the documentation) but the example will not compile without errors. I don't believe that the API has been fully implemented to take advantage of these AXI function calls. I'm hoping for some guidance from RP to help solve this issue. It would be nice to bring our systems up to the current version of the OS and still achieve our overall requirements.

User avatar
redpitaya
Site Admin
Posts: 883
Joined: Wed Mar 26, 2014 7:04 pm

Re: Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by redpitaya » Mon Jun 12, 2023 1:26 pm

The AXI mode is currently still under development (the documentation has nevertheless been uploaded). The features will be available in one of the next OS releases.

werefkin
Posts: 7
Joined: Tue Jan 26, 2021 4:16 pm

Re: Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by werefkin » Fri Jun 16, 2023 10:42 am

arparker wrote:
Mon Jun 12, 2023 2:14 am
We have been using the RP for a number of years (4) using a version of the OS (0.94) that has worked well thus far. We are using an external trigger and external clock and are able to achieve buffer sizes of up to 512K samples at 20Hz using a modified version of the axi_adc.c code.
Hi arparker, do you have the modified version and the algorithm publically available?
something that one has out of the box is 6Hz for 16k samples
I would be happy to test your solution in my application. Bests

earlforeal
Posts: 33
Joined: Thu Aug 20, 2020 9:00 pm

Re: Any solution with OS version 2.00 for fast on on-trigger acquisition?

Post by earlforeal » Wed Jun 28, 2023 8:02 pm

Hello all,

I've been working on a fast on-trigger signal acquisition program running on OS 2.0. I am currently using the 125-14 4-input board and have good results so far. My application requires reading in ~5us pulses and binning them according to their pulse height. The program requires you to set an acquisition time, though it can be easily modified to do single acquisitions. The data is printed to a file as well as console. The code can be modified fairly easily to accommodate other needs I hope. I do not know exactly if this will work on the normal 2-input board right of the box but hopefully it is helpful.

Code: Select all

/* On trigger signal acquisition for 125-14 4 input board */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <stddef.h>
#include <sys/param.h>
#include <time.h>
#include <signal.h>
#include "rp.h" // /RedPitaya/rp-api/api/include/redpitaya
#include "rp_hw-profiles.h" // /RedPitaya/rp-api/api-hw-profiles/include


#define buff_size 50 // buffer length for storing ~5us  pulse
#define channels 256 // MCA channels. 256, 515, 1024, etc


const int N = 200;  // buffer length for file name string

int counts_ch1[channels];
int counts_ch2[channels];
int counts_ch3[channels];


int main(void){

        
        FILE *fp;
        time_t rawtime; struct tm *info; char buffer[N];
        time(&rawtime);
        info = localtime(&rawtime);
        strftime(buffer,N,"/RedPitaya/Examples/C/data/%m_%d_%y_%H_%M_%S.txt",info);
        fp = fopen(buffer, "w+");

        time_t start, end; double elapsed;
        start = time(NULL);
        int counter = 0;

        int a_time = 10;        // acquisition time in seconds

        /* Print error, if rp_Init() function failed */
        if (rp_Init() != RP_OK){
                fprintf(stderr, "failed to initialize RP API\n");
        }

        bool terminate = false; // will be updated once acquisition time is met.
        
        /* MAIN AQUISITION LOOP */
        while(!terminate){        
        
                end = time(NULL); elapsed = difftime(end, start);

                if (elapsed >= a_time){
                        terminate = true;
                }
                /* Allocate buffers */
                float *buff_ch1 = (float *)malloc(buff_size * sizeof(float));
                float *buff_ch2 = (float *)malloc(buff_size * sizeof(float));
                float *buff_ch3 = (float *)malloc(buff_size * sizeof(float));

                rp_AcqReset();
                rp_AcqSetDecimation(RP_DEC_8);
                rp_AcqSetTriggerDelay(0);
                
                /* Set Gains on Inputs to High (20V) */
                int i;
                for(i = 0; i < 4; i++){
                        rp_AcqSetGain(i,RP_HIGH);
                }
                
                rp_AcqSetTriggerLevel(RP_CH_1, 0.2);     //  Set trigger source and value in VOLTS.
                rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE); // rp.h line 269
                rp_AcqStart();
                sleep(0.01);
                
                /* Wait for trigger */
                rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
                while(1){
                        rp_AcqGetTriggerState(&state);
                        if(state == RP_TRIG_STATE_TRIGGERED){
                        break;
                        }
                }
                /* Once triggered, wait for buffer to be filled */
                bool fillState = false;
                while(!fillState){
                        rp_AcqGetBufferFillState(&fillState);
                }
                /* Get write pointer where trigger was met. */
                uint32_t pos = 0;
                rp_AcqGetWritePointerAtTrig(&pos);

                /* Get buffer data from channels A, B, and C */
                buffers_t b;
                b.size = buff_size;
                b.ch_f[0] = buff_ch1; b.ch_f[1] = buff_ch2; b.ch_f[2] = buff_ch3;
                rp_AcqGetDataV2(pos, &b);
                
                /* Find max value of pulse for channels A, B, C */
                float max_ch1 = buff_ch1[0];
                float max_ch2 = buff_ch2[0];
                float max_ch3 = buff_ch3[0];

                for(i = 1; i < buff_size; i++){

                        if(buff_ch1[i] > max_ch1){
                                max_ch1 = buff_ch1[i];    
                        }
                        if(buff_ch2[i] > max_ch2){
                                max_ch2 = buff_ch2[i];
                        }
                        if(buff_ch3[i] > max_ch3){
                                max_ch3 = buff_ch3[i];       
                        }

                }

                /* Place max values into channel */
                float volt_range = 10.00;
                float bin_width = volt_range/channels;
                int cha_ch, chb_ch, chc_ch; // channel that pulse will end up in aka LET value of pulse

                for(i = 0; i < channels; i++){

                        if(max_ch1 < 0){
                                counts_ch1[0]++;
                                break;
                        }
                        else if(max_ch1 >= i*bin_width && max_ch1 < (i+1)*bin_width){
                                counts_ch1[i]++;
                                cha_ch = i;
                                break;
                        }
                        else if(max_ch1 > channels*bin_width){
                                counts_ch1[channels]++;
                                cha_ch = i;
                                break;
                        }
                }
                for(i = 0; i < channels; i++){

                        if(max_ch2 < 0){
                                counts_ch2[0]++;
                                break;
                        }
                        else if(max_ch2 >= i*bin_width && max_ch2 < (i+1)*bin_width){
                                counts_ch2[i]++;
                                chb_ch = i;
                                break;
                        }
                        else if(max_ch2 > channels*bin_width){
                                counts_ch2[channels]++;
                                break;
                        }
                }
                for(i = 0; i < channels; i++){

                        if(max_ch3 < 0){
                                counts_ch3[0]++;
                                break;
                        }
                        else if(max_ch3 >= i*bin_width && max_ch3 < (i+1)*bin_width){
                                counts_ch3[i]++;
                                chc_ch = i;
                                break;
                        }
                        else if(max_ch3 > channels*bin_width){
                                counts_ch3[channels]++;
                                break;
                        }
                }
                
                printf("%.2fV\t Ch:%d/%d\n", max_ch3,chc_ch,channels);
        
                /* Releasing memory allocation */
                free(buff_ch1); free(buff_ch2); free(buff_ch3);
                counter++;
        }
        /* Releases the RP API library resources. */
        rp_Release();

        /* Print spectrum file */
        for (int i = 0; i < channels; i++){
                fprintf(fp, "%d	%d %d\n", counts_ch1[i], counts_ch2[i],counts_ch3[i]);
        }    
	fclose(fp);

        //printf("counter:%d",counter);

        return 0;
}

Post Reply
jadalnie klasyczne ekskluzywne meble wypoczynkowe do salonu ekskluzywne meble tapicerowane ekskluzywne meble do sypialni ekskluzywne meble włoskie

Who is online

Users browsing this forum: No registered users and 18 guests