rp_GenArbWaveform: buffer-size in in Channel 2 unused?

Applications, development tools, FPGA, C, WEB
Post Reply
ThomasGobmaier
Posts: 6
Joined: Tue Mar 01, 2016 6:56 pm

rp_GenArbWaveform: buffer-size in in Channel 2 unused?

Post by ThomasGobmaier » Tue Jun 28, 2016 4:42 pm

Hello,
my aim is to get a precise frequency on both channels (see viewtopic.php?f=9&t=504&p=1954&hilit=AW ... sion#p1954)
So I set the frequency and calculate how long the buffer has to be to get the exact frequency.
Channel 1 is working (blue line in the pic), it shows the sine with buffer-size 14000.
On channel 2 (red line) the frequency is lower, and there are some zero's (seems the difference between 14000 and the max. buffer size of 16384)
--> so can it be, that the software does not update the buffer size of channel 2 and uses the init values 16384 instead ?

The code is

Code: Select all

        rp_GenWaveform(RP_CH_1, RP_WAVEFORM_ARBITRARY);
        rp_GenWaveform(RP_CH_2, RP_WAVEFORM_ARBITRARY);

        rp_GenArbWaveform(RP_CH_1, x_sin, buff_size);
        rp_GenArbWaveform(RP_CH_2, x_sin, buff_size); // same data and buffer-size

        rp_GenAmp(RP_CH_1, 1.0);
        rp_GenAmp(RP_CH_2, 1.0);

        rp_GenFreq(RP_CH_1, Sollfrequenz);
        rp_GenFreq(RP_CH_2, Sollfrequenz); // same frequency

        rp_GenOutEnable(RP_CH_1);
        rp_GenOutEnable(RP_CH_2);
Best,
Thomas
You do not have the required permissions to view the files attached to this post.

Nils Roos
Posts: 1441
Joined: Sat Jun 07, 2014 12:49 pm
Location: Königswinter

Re: rp_GenArbWaveform: buffer-size in in Channel 2 unused?

Post by Nils Roos » Tue Jun 28, 2016 6:07 pm

Hi Thomas,

congratulations, you found another bug in the RP api. When setting an arbitrary waveform for channel 2, its length is stored in the length field of channel 1. I can't see any work-around, your only option would be to rebuild the api library with a fix for the error.

The code is in gen_handler.c

Code: Select all

    if (channel == RP_CH_1) {
        chA_arb_size = length;
        if(chA_waveform==RP_WAVEFORM_ARBITRARY){
        	return synthesize_signal(channel);
        }
    }
    else if (channel == RP_CH_2) {
    	chA_arb_size = length;                        // <- should be chB_arb_size
        if(chB_waveform==RP_WAVEFORM_ARBITRARY){
        	return synthesize_signal(channel);
        }
    }
    else {
        return RP_EPN;
    }

ThomasGobmaier
Posts: 6
Joined: Tue Mar 01, 2016 6:56 pm

Re: rp_GenArbWaveform: buffer-size in in Channel 2 unused?

Post by ThomasGobmaier » Wed Jun 29, 2016 2:35 pm

Thanks for the quick reply !

I wanted to get a very precise frequency of 50.000 Hz +/- 0.2mHz, and it works very well !

Here is the full code for the precise frequency generator:

Code: Select all

/********************************************************
Precise Signal Generator for low frequencies with Red Pitaya

The Signal Generation writes the buffer of the DAC (fast RF output)
The speed is 125 MSamples/step-size, the step-size is a
integer, so the frequency generator searches the nearest
step size. So 1.00 Hz gets to 1.0477 Hz.
The arbitrary wave generator can work with reduced buffer size,
so the precision of the generated frequency can be enhanced.
This example is based on the example generate_arbitrary_waveform.c

Usage: gen_sin_V02.c FrequencyYouWant
example:
 - for 150 Hz: LD_LIBRARY_PATH=/opt/redpitaya/lib ./gen_sin_V02 1.50e2
 - for 150 Hz: LD_LIBRARY_PATH=/opt/redpitaya/lib ./gen_sin_V02 150
 - switch off: LD_LIBRARY_PATH=/opt/redpitaya/lib ./gen_sin_V02 0
********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "redpitaya/rp.h"

#define M_PI 3.14159265358979323846

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

        int i;
        int buff_size = 16384;

        double Sollfrequenz = 10.0; // Frequenz in Hz
        double Istfrequenz;
        double step_size;
        int step_size_int;
        double f=-1.0;

        if (argv[1] !=0) f =  atof(argv[1]); // get arguments from command lind
        else { printf("Beispiel-Frequenz: %.5f Hz\n", Sollfrequenz); f=Sollfrequenz;} // or use example frequency

        if (f>0) {
            Sollfrequenz = f;
            printf("Frequenzeingabe: %.5f Hz\n", Sollfrequenz);
        }
        else { // stop signal generation
                printf("Frequenzgenerator AUS\n");
                if(rp_Init() != RP_OK){
                        fprintf(stderr, "Rp api init failed!\n");
                }
                rp_GenOutDisable(RP_CH_1);
                rp_GenOutDisable(RP_CH_2);
                rp_Release();
                exit(0);
        }


        step_size = 65536.0*Sollfrequenz/125000000.0*16384;
        step_size_int =(int)(step_size+0.5); // kein +0,5 fuer runden, da sonst buffer>max raus kommt

        // if step_size is rounded up, then the buffer_size gets bigger than max
        // so we decrease frequency to get smaller step size with the value corresponding with 0.5 step size
        if (step_size<(double)step_size_int) { // rounded up
                //printf("StepSize rounded up --> reducing frequency \n");
                // second time calculating with reduced frequency
                step_size = 65536.0*(Sollfrequenz-0.058207661)/125000000.0*16384;
                step_size_int =(int)(step_size+0.5); // kein +0,5 fuer runden, da sonst buffer>max raus kommt
        }
        //printf("Step: %f wird zu %d\n", step_size, step_size_int);


        Istfrequenz = (125000000.0/(double)buff_size)*((double)step_size_int/65536);
        //printf("Soll in Hz: %.5f     Ist in Hz: %.5f \n", Sollfrequenz, Istfrequenz);

        buff_size = (int)(((double)buff_size/Sollfrequenz*Istfrequenz)+0.5);
        if (buff_size>16384) printf(" ## Achtung: Frequenz zu hoch !! Buffer waere zu gross !\n");
        Istfrequenz = (125000000.0/(double)buff_size)*((double)step_size_int/65536);
        //printf("Mit buffer Reduktion von 16384 auf %d erhaelt man Frequenz von %.5f Hz (Fehler %.2f Prozent) \n", buff_size, Istfrequenz, (Sollfrequenz-Istfrequenz)/Sollfrequenz*100.0);
        printf("Soll in Hz: %.5f    Ist in Hz: %.5f     (Frequenzfehler %.5f%%)\n", Sollfrequenz, Istfrequenz,  (Sollfrequenz-Istfrequenz)/Sollfrequenz*100.0);

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

        // build frequency
        float *t = (float *)malloc(buff_size * sizeof(float));
        float *x_sin = (float *)malloc(buff_size * sizeof(float));

        for(i = 1; i < buff_size; i++){ //time base
                t[i] = (2 * M_PI) / buff_size * i;
        }

        for (i = 0; i < buff_size; ++i){ // sine wave
                //x[i] = -(float)i/(float)buff_size*0.9-0.05;
                x_sin[i] = sin(t[i]);
        }

        rp_GenWaveform(RP_CH_1, RP_WAVEFORM_ARBITRARY);
        rp_GenWaveform(RP_CH_2, RP_WAVEFORM_ARBITRARY);

        rp_GenArbWaveform(RP_CH_1, x_sin, buff_size);
        rp_GenArbWaveform(RP_CH_2, x_sin, buff_size);

        rp_GenAmp(RP_CH_1, 1.0);
        rp_GenAmp(RP_CH_2, 1.0);

        rp_GenFreq(RP_CH_1, Sollfrequenz);
        rp_GenFreq(RP_CH_2, Sollfrequenz);

        rp_GenOutEnable(RP_CH_1);
        rp_GenOutEnable(RP_CH_2);

        /* Releasing resources */
        free(t);
        free(x_sin);
        rp_Release();
}

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