acquire_signal_check.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Red Pitaya C API example Acquiring a signal from a buffer and check it
  2. * This application acquires a signal on a specific channel */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <math.h>
  7. #include <string.h>
  8. #include "rp_hw-profiles.h"
  9. #include "rp.h"
  10. #define EPS 0.05
  11. #define EPS_F 100
  12. uint32_t getADCRate(){
  13. uint32_t c = 0;
  14. if (rp_HPGetBaseFastADCSpeedHz(&c) != RP_HP_OK){
  15. fprintf(stderr,"[Error] Can't get fast ADC channels count\n");
  16. }
  17. return c;
  18. }
  19. #define c_osc_fpga_smpl_freq getADCRate()
  20. #define c_meas_time_thr (ADC_BUFFER_SIZE / (1000000000 / getADCRate()))
  21. const float c_meas_freq_thr = 0.05;
  22. const float c_min_period = 19.6e-9; // 51 MHz
  23. void filterBuffer(float *_buffer,int _size){
  24. float *n_b = malloc(_size * sizeof(float));
  25. memcpy(n_b,_buffer,_size);
  26. float core[] = { 1.0 / 8.0 , 1.0 / 4.0 , 1.0 / 4.0 , 1.0 / 4.0 , 1.0 / 8.0};
  27. for(int i = 2 ; i < _size - 2 ; i++ ){
  28. float sum = 0;
  29. for (int j = -2 ; j <= 2 ; j++ ){
  30. sum += core[j + 2] * _buffer [i + j];
  31. }
  32. n_b[i] = sum;
  33. }
  34. memcpy(_buffer,n_b,_size);
  35. free(n_b);
  36. }
  37. bool checkAmplitudeAndFreq(float *_buff, uint32_t _size,float _nominal,float *min, float *max,float *frequency){
  38. int trig_t[2] = { 0, 0 };
  39. int trig_cnt = 0;
  40. int state = 0;
  41. if (_size > 0){
  42. *min = _buff[0];
  43. *max = _buff[0];
  44. for (int i = 1 ; i < _size ; ++i){
  45. if (*min > _buff[i]) *min = _buff[i];
  46. if (*max < _buff[i]) *max = _buff[i];
  47. }
  48. uint32_t dec_factor = 1;
  49. rp_AcqGetDecimationFactor(&dec_factor);
  50. float acq_dur=(float)(_size)/((float) c_osc_fpga_smpl_freq) * (float) dec_factor;
  51. float cen = (*max + *min) / 2;
  52. float thr1 = cen + 0.2 * (*min - cen);
  53. float thr2 = cen + 0.2 * (*max - cen);
  54. float res_period = 0;
  55. for(int i = 0; i < _size; i++) {
  56. float sa = _buff[i];
  57. if((state == 0) && (sa < thr1)) {
  58. state = 1;
  59. }
  60. if((state == 1) && (sa >= thr2) ) {
  61. state = 0;
  62. if (trig_cnt++ == 0) {
  63. trig_t[0] = i;
  64. } else {
  65. trig_t[1] = i;
  66. }
  67. }
  68. if ((trig_t[1] - trig_t[0]) > c_meas_time_thr) {
  69. break;
  70. }
  71. }
  72. if(trig_cnt >= 2) {
  73. res_period = (float)(trig_t[1] - trig_t[0]) /
  74. ((float)c_osc_fpga_smpl_freq * (trig_cnt - 1)) * dec_factor;
  75. }
  76. if( ((thr2 - thr1) < c_meas_freq_thr) ||
  77. (res_period * 3 >= acq_dur) ||
  78. (res_period < c_min_period) ){
  79. res_period = 0;
  80. }
  81. float period = res_period * 1000.f;
  82. period = (period == 0.f) ? 0.000001f : period;
  83. *frequency = (float) (1 / (period / 1000.0));
  84. if ((fabs(*min + _nominal) < EPS) && (fabs(*max - _nominal) < EPS))
  85. return true;
  86. return false;
  87. }
  88. return false;
  89. }
  90. float trapezoidalApprox(double *data, float T, int size){
  91. double result = 0;
  92. for(int i = 0; i < size - 1; i++){
  93. result += data[i] + data[i+1];
  94. }
  95. result = ((T / 2.0) * result);
  96. return result;
  97. }
  98. bool isSineTester(float *data, uint32_t size)
  99. {
  100. uint32_t dec_factor = 1;
  101. rp_AcqGetDecimationFactor(&dec_factor);
  102. double T = (dec_factor / getADCRate());
  103. double ch_rms[size];
  104. double ch_avr[size];
  105. for(int i = 0; i < size; i++) {
  106. ch_rms[i] = data[i] * data[i];
  107. ch_avr[i] = fabs(data[i]);
  108. }
  109. double K0 = sqrtf(T * size * trapezoidalApprox(ch_rms, T, size)) / trapezoidalApprox(ch_avr, T, size);
  110. return ((K0 > 1.10) && (K0 < 1.12));
  111. }
  112. int main(int argc, char **argv){
  113. bool fillState = false;
  114. int counter=100;
  115. /* Print error, if rp_Init() function failed */
  116. if(rp_Init() != RP_OK){
  117. fprintf(stderr, "Rp api init failed!\n");
  118. }
  119. rp_GenReset();
  120. rp_GenFreq(RP_CH_1, 20000.0);
  121. rp_GenAmp(RP_CH_1, 1.0);
  122. rp_GenWaveform(RP_CH_1, RP_WAVEFORM_SINE);
  123. rp_GenOutEnable(RP_CH_1);
  124. uint32_t buff_size = 16384;
  125. float *buff = (float *)malloc(buff_size * sizeof(float));
  126. rp_AcqReset();
  127. rp_AcqSetDecimation(RP_DEC_8);
  128. rp_AcqSetTriggerLevel(RP_CH_1, 0);
  129. rp_AcqSetTriggerDelay(ADC_BUFFER_SIZE/2.0);
  130. while(counter--){
  131. fillState = false;
  132. rp_AcqStart();
  133. /* After acquisition is started some time delay is needed in order to acquire fresh samples in to buffer*/
  134. /* Here we have used time delay of one second but you can calculate exact value taking in to account buffer*/
  135. /*length and smaling rate*/
  136. sleep(1);
  137. rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE);
  138. rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
  139. while(1){
  140. rp_AcqGetTriggerState(&state);
  141. if(state == RP_TRIG_STATE_TRIGGERED){
  142. break;
  143. }
  144. }
  145. while(!fillState){
  146. rp_AcqGetBufferFillState(&fillState);
  147. }
  148. rp_AcqStop();
  149. rp_AcqGetOldestDataV(RP_CH_1, &buff_size, buff);
  150. filterBuffer(buff,buff_size);
  151. printf("Acquiring Done\n");
  152. float min = 0;
  153. float max = 0;
  154. float frequency = 0;
  155. bool isBrokenSignal = false;
  156. if (checkAmplitudeAndFreq(buff,buff_size,1.0, &min , &max , &frequency)) {
  157. printf("\tAmplitude is correct MIN = %0.4f , MAX = %0.4f\n",min,max);
  158. }else{
  159. printf("\tAmplitude is not correct MIN = %0.4f , MAX = %0.4f\n",min,max);
  160. isBrokenSignal = true;
  161. }
  162. if (fabs(frequency - 20000.0) < EPS_F) {
  163. printf("\tFrequency is correct %0.4f\n",frequency);
  164. }else{
  165. printf("\tFrequency is not correct %0.4f\n",frequency);
  166. isBrokenSignal = true;
  167. }
  168. if (isSineTester(buff,buff_size)){
  169. printf("\tSignal form is sine\n");
  170. }else{
  171. printf("\tSignal form is not sine\n");
  172. isBrokenSignal = true;
  173. }
  174. printf("Signal is %s\n\n",isBrokenSignal ? "not correct" : "correct");
  175. }
  176. /* Releasing resources */
  177. free(buff);
  178. rp_Release();
  179. return 0;
  180. }