Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Applications, development tools, FPGA, C, WEB
Post Reply
earlforeal
Posts: 33
Joined: Thu Aug 20, 2020 9:00 pm

Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by earlforeal » Mon Jun 26, 2023 5:26 pm

I am having trouble getting the acquire_4ch_trigger_software.c example to trigger from a positive edge. Here is the original example: https://github.com/RedPitaya/RedPitaya/ ... software.c

The original example's trigger is defined at line 46:

Code: Select all

       rp_AcqSetTriggerSrc(RP_TRIG_SRC_NOW);
        rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;

        while(1){
                rp_AcqGetTriggerState(&state);
                if(state == RP_TRIG_STATE_TRIGGERED){
                sleep(1);
                break;
                }
        }
Looking in rp.h I found this:

Code: Select all

/**
 * Type representing different trigger sources used at acquiring signal.
 */
typedef enum {
    RP_TRIG_SRC_DISABLED = 0, //!< Trigger is disabled
    RP_TRIG_SRC_NOW      = 1, //!< Trigger triggered now (immediately)
    RP_TRIG_SRC_CHA_PE   = 2, //!< Trigger set to Channel A threshold positive edge
    RP_TRIG_SRC_CHA_NE   = 3, //!< Trigger set to Channel A threshold negative edge
    RP_TRIG_SRC_CHB_PE   = 4, //!< Trigger set to Channel B threshold positive edge
    RP_TRIG_SRC_CHB_NE   = 5, //!< Trigger set to Channel B threshold negative edge
    RP_TRIG_SRC_EXT_PE   = 6, //!< Trigger set to external trigger positive edge (DIO0_P pin)
    RP_TRIG_SRC_EXT_NE   = 7, //!< Trigger set to external trigger negative edge (DIO0_P pin)
    RP_TRIG_SRC_AWG_PE   = 8, //!< Trigger set to arbitrary wave generator application positive edge
    RP_TRIG_SRC_AWG_NE   = 9, //!< Trigger set to arbitrary wave generator application negative edge
    RP_TRIG_SRC_CHC_PE   = 10,//!< Trigger set to Channel B threshold positive edge
    RP_TRIG_SRC_CHC_NE   = 11,//!< Trigger set to Channel B threshold negative edge
    RP_TRIG_SRC_CHD_PE   = 12,//!< Trigger set to Channel B threshold positive edge
    RP_TRIG_SRC_CHD_NE   = 13 //!< Trigger set to Channel B threshold negative edge
} rp_acq_trig_src_t;
So I simply changed the source to channel A positive edge, and next used the rp_AcqSetTriggerLevel function defined in rp.h:

Code: Select all

/**
 * Sets the trigger threshold value in volts. Makes the trigger when ADC value crosses this value.
 * @param voltage Threshold value for the channel
 * @return If the function is successful, the return value is RP_OK.
 * If the function is unsuccessful, the return value is any of RP_E* values that indicate an error.
 */
int rp_AcqSetTriggerLevel(rp_channel_trigger_t channel, float voltage);

I have modified the original to try to implement a positive edge trigger:

Code: Select all

        rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE); // rp.h line 269
        rp_AcqSetTriggerLevel(RP_T_CH_1, 0.05);         //  rp.h line 824
        
        rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;

        while(1){
                rp_AcqGetTriggerState(&state);
                if(state == RP_TRIG_STATE_TRIGGERED){
                sleep(1);
                break;
                }
        }
However, this does not work. The program just hangs indefinitely. The input pulse is a 1V step function. Can someone please give some insight as to why this isn't working as intended?

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

Re: Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by earlforeal » Mon Jun 26, 2023 5:50 pm

Progress:

Calling rp_AcqSetTriggerLevel() before rp_SetTriggerSrc() now makes the program "Acquire" something. Though I am sending in a 1V step function and the values it is returning are from 0.01-0.07 volts. The redpitaya is calibrated and using the oscilliscope web app shows the step function accurately.

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

Re: Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by earlforeal » Mon Jun 26, 2023 7:57 pm

I now have a working positive edge trigger program based on the acquire_ch_trigger_software.c example. My application requires I read in ~5 microsecond guassian pulses that range from 0-10V in amplitude. By placing this .c file in /RedPitaya/Examples/C you can use the make command to compile it.

One thing I cannot get around currently is the trigger level. It seems to only work when it is set to 0.3 volts, and I cannot go lower. Given the input pulses clearly start well below 0.3 volts, I don't see why values like 0.1 volts will not work. Here is a screenshot from the oscilliscope web app of the input pulse: https://imgur.com/a/TsbhSNS

Code: Select all

/* Red Pitaya C API example Acquiring a signal from a buffer
 * This application acquires a signal on a specific channel */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "rp.h" // /RedPitaya/rp-api/api/include/redpitaya
#include "rp_hw-profiles.h" // /RedPitaya/rp-api/api-hw-profiles/include



int main(int argc, char **argv){

        uint8_t c = 0;
        if (rp_HPGetFastADCChannelsCount(&c) != RP_HP_OK){
                fprintf(stderr,"[Error] Can't get fast ADC channels count\n");
                return 1;
        }

        if (c!= 4){
                fprintf(stderr,"[Error] The number of channels is wrong\n");
                return 1;
        }

        /* Print error, if rp_Init() function failed */
        if(rp_Init() != RP_OK){
                fprintf(stderr, "Rp api init failed!\n");
        }

        uint32_t buff_size = 256;
        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));
        float *buff_ch4 = (float *)malloc(buff_size * sizeof(float));


        rp_AcqReset();
        rp_AcqSetDecimation(RP_DEC_1);
        rp_AcqSetTriggerDelay(0);
        
        rp_AcqSetGain(0, RP_HIGH);
        rp_AcqSetGain(1, RP_HIGH);
        rp_AcqSetGain(2, RP_HIGH);
        rp_AcqSetGain(3, RP_HIGH);
        rp_AcqSetTriggerLevel(RP_CH_1, 0.3);         //  rp.h line 824
        
        rp_AcqStart();

        /* After acquisition is started some time delay is needed in order to acquire fresh samples in to buffer*/
        /* Here we have used time delay of one second but you can calculate exact value taking in to account buffer*/
        /*length and smaling rate*/

        sleep(0.01);
        
        
        rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE); // rp.h line 269
        
        rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
        

        while(1){
                rp_AcqGetTriggerState(&state);
                if(state == RP_TRIG_STATE_TRIGGERED){
                sleep(1);
                break;
                }
        }


        bool fillState = false;
        while(!fillState){
		rp_AcqGetBufferFillState(&fillState);
	}
        
        uint32_t pos = 0;
	rp_AcqGetWritePointerAtTrig(&pos);
        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;
        b.ch_f[3] = buff_ch4; 

        rp_AcqGetDataV2(pos, &b);

        int i;
        for(i = 0; i < buff_size; i++){
                printf("%f\n", buff_ch1[i]);
        } 

   
        /* Releasing resources */
        free(buff_ch1);
        free(buff_ch2);
        free(buff_ch3);
        free(buff_ch4);
        rp_Release();

        return 0;
}

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

Re: Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by redpitaya » Mon Jul 03, 2023 2:48 pm

Hello, earlforeal,

Sorry for the late reply.

You have set the Gain settings to HV (trigger level between 0-20 V), so there may be a lower limit to the trigger level on HV settings. I'll consult with the team and let you know.

Which OS are you using for the STEMlab 125-14 4-Input? Because the

Code: Select all

bool fillState = false;
while(!fillState){
      rp_AcqGetBufferFillState(&fillState);
}
is supported from the 2.00 OS onward (make a print command between the two infinite loops to check how far the program comes).

Please also check that you are triggering the source after the acquisition is triggered (if dealing with burst signals).

The external trigger is bugged in the 2.00 OS (for the 4-Input), we have fixed it in the latest test OS.

Please update me on the situation.

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

Re: Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by earlforeal » Wed Jul 05, 2023 3:57 pm

Thanks for the reply, I am using OS 2.0. I have used the below program successfully to acquire ~5us gaussian pulses on all 4 channels with internal trigger on channel 1. Though I would like to use an external trigger. When is this update going live?

Code: Select all

#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;        //seconds
        if (a_time > 300) {
                a_time = 300;
        }

        /* Print error, if rp_Init() function failed */
        if (rp_Init() != RP_OK){
                fprintf(stderr, "Rp api init failed!\n");
        }

        bool terminate = false;
        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.0004);
                
                /* 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;
}

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

Re: Acquire signal with positive edge trigger in acquire_4ch_trigger_softwar.c

Post by redpitaya » Thu Jul 06, 2023 8:21 am

Hello, earlforeal!

We still need to do some minor tweaks for the official release, but we added the Nightly Builds option so that all users can use the latest TEST OS:
https://downloads.redpitaya.com/downloa ... ly_builds/

The external trigger issue is fixed in the Test OS. Please note that the Test OS might have some bugs, but at this stage is quite good.

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