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();
}