ref_app_touchless_button.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2023-2024
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6 
7 #include <complex.h>
8 #include <math.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include "acc_algorithm.h"
15 #include "acc_config.h"
16 #include "acc_definitions_common.h"
19 #include "acc_integration.h"
20 #include "acc_integration_log.h"
21 #include "acc_processing.h"
22 #include "acc_rss_a121.h"
23 #include "acc_sensor.h"
24 #include "acc_version.h"
25 
26 #define SENSOR_ID (1U)
27 // The time to measure for the application presets should be well below 1s.
28 // If timeouts occurs, try increasing the number.
29 #define SENSOR_TIMEOUT_MS (1000U)
30 
31 /**
32  * @brief Application measurement type
33  */
34 typedef enum
35 {
36  /**
37  * Corresponds to a range of approximate 0 cm - 5 cm
38  */
40  /**
41  * Corresponds to a range of approximate 0 cm - 24 cm
42  */
44  /**
45  * Gives two detection outputs, one for each range
46  */
49 
50 /**
51  * @brief Touchless button application config
52  */
53 typedef struct
54 {
55  /**
56  * Sensitivity for close range detection. High sensitivity equals low
57  * detection threshold, low sensitivity equals high detection threshold
58  */
60  /**
61  * Number of frames in a row above threshold to count as a new close range detection,
62  * also number of frames in a row below threshold to count as end of detection
63  */
64  uint16_t patience_close;
65  /**
66  * Sensitivity for far range detection. High sensitivity equals low
67  * detection threshold, low sensitivity equals high detection threshold
68  */
70  /**
71  * Number of frames in a row above threshold to count as a new close range detection,
72  * also number of frames in a row below threshold to count as end of detection
73  */
74  uint16_t patience_far;
75  /**
76  * Calibration duration in seconds
77  */
79  /**
80  * Interval between calibrations in seconds. When reached a new calibration is made.
81  * Should not be set lower than the longest estimated continuous detection event
82  */
84  /**
85  * The measurement type
86  * See @ref acc_touchless_button_measurement_type_t for more information
87  */
89  /**
90  * The sensor configuration
91  */
94 
95 typedef enum
96 {
102 
103 #define DEFAULT_PRESET ACC_TOUCHLESS_BUTTON_PRESET_CLOSE
104 
105 /**
106  * @brief Touchless button application handle
107  */
108 typedef struct
109 {
115  void *buffer;
116  uint32_t buffer_size;
119  float complex *arg_norm;
120  float *ampl_mean;
121  float *ampl_std;
122  float *phase_mean;
123  float *phase_std;
125  uint16_t cal_sweeps;
134  bool run_close;
135  bool run_far;
137  uint16_t far_num_points;
138  uint16_t close_signal;
139  uint16_t far_signal;
141  uint16_t far_non_signal;
145 
146 /**
147  * @brief Touchless button range result
148  */
149 typedef enum
150 {
155 
156 /**
157  * @brief Touchless button application result
158  */
159 typedef struct
160 {
164 
166 
168 
170 
172 
174 
175 static float get_threshold(float sensitivity);
176 
178 
180 
182 
184 
185 static bool check_count(uint16_t *count, uint16_t check_offset, uint16_t check_length);
186 
188 
189 static bool get_detection(bool current_detection, uint16_t sig_count, uint16_t non_sig_count, uint16_t patience);
190 
192 
194 
195 int acconeer_main(int argc, char *argv[]);
196 
197 int acconeer_main(int argc, char *argv[])
198 {
199  (void)argc;
200  (void)argv;
201 
203  handle.sensor = NULL;
204  handle.processing = NULL;
205  handle.buffer = NULL;
206  handle.double_buffer_filter_buffer = NULL;
207  handle.frame_variance = NULL;
208  handle.arg_norm = NULL;
209  handle.ampl_mean = NULL;
210  handle.ampl_std = NULL;
211  handle.phase_mean = NULL;
212  handle.phase_std = NULL;
213  handle.dynamic_background = NULL;
214  handle.dynamic_background_guard = NULL;
215  handle.threshold_check_count = NULL;
216 
217  printf("Acconeer software version %s\n", acc_version_get());
218 
220 
221  if (!acc_rss_hal_register(hal))
222  {
223  return EXIT_FAILURE;
224  }
225 
226  handle.config.sensor_config = acc_config_create();
227  if (handle.config.sensor_config == NULL)
228  {
229  printf("acc_config_create() failed\n");
230  cleanup(&handle);
231  return EXIT_FAILURE;
232  }
233 
234  set_config(&handle.config, DEFAULT_PRESET);
235 
236  if (!validate_config(&handle.config))
237  {
238  cleanup(&handle);
239  return EXIT_FAILURE;
240  }
241 
242  config_log(&handle.config);
243 
244  if (!init_handle(&handle))
245  {
246  printf("Failed to init handle\n");
247  cleanup(&handle);
248  return EXIT_FAILURE;
249  }
250 
251  if (!init_sensor(&handle))
252  {
253  printf("Failed to init sensor\n");
254  cleanup(&handle);
255  return EXIT_FAILURE;
256  }
257 
258  while (true)
259  {
260  if (!measure(&handle))
261  {
262  printf("Failed to measure\n");
263  cleanup(&handle);
264  return EXIT_FAILURE;
265  }
266 
267  if (handle.proc_result.data_saturated)
268  {
269  printf("Data saturated. The detector result is not reliable.\n");
270  }
271 
272  if (handle.proc_result.frame_delayed)
273  {
274  printf("Frame delayed. Could not read data fast enough.\n");
275  printf("Try lowering the frame rate or call 'acc_sensor_read' more frequently.\n");
276  }
277 
278  if (handle.proc_result.calibration_needed)
279  {
280  printf("The current calibration is not valid for the current temperature.\n");
281  printf("The sensor needs to be re-calibrated.\n");
282 
284  {
285  printf("do_sensor_calibration_and_prepare() failed\n");
286  acc_sensor_status(handle.sensor);
287  cleanup(&handle);
288  return EXIT_FAILURE;
289  }
290 
292 
293  printf("The sensor was successfully re-calibrated.\n");
294  }
295  else
296  {
298 
299  if (!process(&handle, &result))
300  {
301  printf("Failed to process sensor result\n");
302  cleanup(&handle);
303  return EXIT_FAILURE;
304  }
305 
307  }
308  }
309 
310  cleanup(&handle);
311 
312  printf("Application finished OK\n");
313 
314  return EXIT_SUCCESS;
315 }
316 
318 {
321 
322  if (handle->config.sensor_config != NULL)
323  {
324  acc_config_destroy(handle->config.sensor_config);
325  }
326 
327  if (handle->sensor != NULL)
328  {
329  acc_sensor_destroy(handle->sensor);
330  }
331 
332  if (handle->processing != NULL)
333  {
334  acc_processing_destroy(handle->processing);
335  }
336 
337  if (handle->buffer != NULL)
338  {
340  }
341 
342  if (handle->double_buffer_filter_buffer != NULL)
343  {
344  acc_integration_mem_free(handle->double_buffer_filter_buffer);
345  }
346 
347  if (handle->frame_variance != NULL)
348  {
349  acc_integration_mem_free(handle->frame_variance);
350  }
351 
352  if (handle->arg_norm != NULL)
353  {
354  acc_integration_mem_free(handle->arg_norm);
355  }
356 
357  if (handle->ampl_mean != NULL)
358  {
359  acc_integration_mem_free(handle->ampl_mean);
360  }
361 
362  if (handle->ampl_std != NULL)
363  {
364  acc_integration_mem_free(handle->ampl_std);
365  }
366 
367  if (handle->phase_mean != NULL)
368  {
369  acc_integration_mem_free(handle->phase_mean);
370  }
371 
372  if (handle->phase_std != NULL)
373  {
374  acc_integration_mem_free(handle->phase_std);
375  }
376 
377  if (handle->dynamic_background != NULL)
378  {
379  acc_integration_mem_free(handle->dynamic_background);
380  }
381 
382  if (handle->dynamic_background_guard != NULL)
383  {
384  acc_integration_mem_free(handle->dynamic_background_guard);
385  }
386 
387  if (handle->threshold_check_count != NULL)
388  {
389  acc_integration_mem_free(handle->threshold_check_count);
390  }
391 }
392 
394 {
395  switch (preset)
396  {
398  break;
400  acc_config_sweeps_per_frame_set(config->sensor_config, 16U);
401  acc_config_sweep_rate_set(config->sensor_config, 320U);
402  acc_config_continuous_sweep_mode_set(config->sensor_config, true);
403  acc_config_double_buffering_set(config->sensor_config, true);
406  acc_config_num_points_set(config->sensor_config, 3U);
408  acc_config_receiver_gain_set(config->sensor_config, 0U);
409  acc_config_hwaas_set(config->sensor_config, 40U);
410  acc_config_start_point_set(config->sensor_config, 0U);
411  acc_config_step_length_set(config->sensor_config, 6U);
412 
413  config->sensitivity_close = 1.9f;
414  config->patience_close = 2U;
415  config->calibration_duration_s = 0.6f;
416  config->calibration_interval_s = 20.0f;
417  config->measurement_type = ACC_TOUCHLESS_BUTTON_CLOSE_RANGE;
418  break;
420  acc_config_sweeps_per_frame_set(config->sensor_config, 16U);
421  acc_config_sweep_rate_set(config->sensor_config, 320U);
422  acc_config_continuous_sweep_mode_set(config->sensor_config, true);
423  acc_config_double_buffering_set(config->sensor_config, true);
426  acc_config_num_points_set(config->sensor_config, 3U);
428  acc_config_receiver_gain_set(config->sensor_config, 5U);
429  acc_config_hwaas_set(config->sensor_config, 60U);
430  acc_config_start_point_set(config->sensor_config, 0U);
431  acc_config_step_length_set(config->sensor_config, 24U);
432 
433  config->sensitivity_far = 2.0f;
434  config->patience_far = 2U;
435  config->calibration_duration_s = 0.6f;
436  config->calibration_interval_s = 20.0f;
437  config->measurement_type = ACC_TOUCHLESS_BUTTON_FAR_RANGE;
438  break;
440  acc_config_num_subsweeps_set(config->sensor_config, 2U);
441  acc_config_sweeps_per_frame_set(config->sensor_config, 16U);
442  acc_config_sweep_rate_set(config->sensor_config, 320U);
443  acc_config_continuous_sweep_mode_set(config->sensor_config, true);
444  acc_config_double_buffering_set(config->sensor_config, true);
447 
448  acc_config_subsweep_num_points_set(config->sensor_config, 3U, 0U);
450  acc_config_subsweep_receiver_gain_set(config->sensor_config, 0U, 0U);
451  acc_config_subsweep_hwaas_set(config->sensor_config, 40U, 0U);
452  acc_config_subsweep_start_point_set(config->sensor_config, 0U, 0U);
453  acc_config_subsweep_step_length_set(config->sensor_config, 6U, 0U);
454 
455  acc_config_subsweep_num_points_set(config->sensor_config, 3U, 1U);
457  acc_config_subsweep_receiver_gain_set(config->sensor_config, 5U, 1U);
458  acc_config_subsweep_hwaas_set(config->sensor_config, 60U, 1U);
459  acc_config_subsweep_start_point_set(config->sensor_config, 0U, 1U);
460  acc_config_subsweep_step_length_set(config->sensor_config, 24U, 1U);
461 
462  config->sensitivity_close = 1.9f;
463  config->patience_close = 2U;
464  config->sensitivity_far = 2.0f;
465  config->patience_far = 2U;
466  config->calibration_duration_s = 0.6f;
467  config->calibration_interval_s = 20.0f;
469  break;
470  }
471 }
472 
474 {
475  bool status = true;
476 
477  if (acc_config_num_subsweeps_get(config->sensor_config) != 2U && config->measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE)
478  {
479  printf("Number of subsweeps must be 2 for 'close and far'\n");
480  status = false;
481  }
482 
483  if (acc_config_num_subsweeps_get(config->sensor_config) != 1U &&
484  (config->measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_RANGE || config->measurement_type == ACC_TOUCHLESS_BUTTON_FAR_RANGE))
485  {
486  printf("Number of subsweeps must be 1 for 'close' and 'far'\n");
487  status = false;
488  }
489 
490  float sweep_rate = acc_config_sweep_rate_get(config->sensor_config);
491  uint16_t spf = acc_config_sweeps_per_frame_get(config->sensor_config);
492 
493  if (sweep_rate == 0.0f)
494  {
495  printf("Sweep rate must be set\n");
496  status = false;
497  }
498  else
499  {
500  if (spf > (config->calibration_duration_s * sweep_rate))
501  {
502  float calibration_limit = (float)spf / sweep_rate;
503 
504  printf("Calibration duration must be at least %" PRIfloat " s\n", ACC_LOG_FLOAT_TO_INTEGER(calibration_limit));
505  status = false;
506  }
507  }
508 
509  return status;
510 }
511 
513 {
514  float sensitivity_close = config->sensitivity_close;
515  uint16_t patience_close = config->patience_close;
516  float sensitivity_far = config->sensitivity_far;
517  uint16_t patience_far = config->patience_far;
518  float calibration_duration_s = config->calibration_duration_s;
519  float calibration_interval_s = config->calibration_interval_s;
520  acc_touchless_button_measurement_type_t measurement_type = config->measurement_type;
521 
522  printf("Reference application Touchless Button config\n");
523 
524  if (measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_RANGE || measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE)
525  {
526  printf("sensitivity close: %" PRIfloat "\n", ACC_LOG_FLOAT_TO_INTEGER(sensitivity_close));
527  printf("patience close: %" PRIu16 "\n", patience_close);
528  }
529 
530  if (measurement_type == ACC_TOUCHLESS_BUTTON_FAR_RANGE || measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE)
531  {
532  printf("sensitivity far: %" PRIfloat "\n", ACC_LOG_FLOAT_TO_INTEGER(sensitivity_far));
533  printf("patience far: %" PRIu16 "\n", patience_far);
534  }
535 
536  printf("calibration duration: %" PRIfloat "\n", ACC_LOG_FLOAT_TO_INTEGER(calibration_duration_s));
537  printf("calibration interval: %" PRIfloat "\n", ACC_LOG_FLOAT_TO_INTEGER(calibration_interval_s));
538 
539  char *measurement_type_str = "";
540 
541  switch (measurement_type)
542  {
544  measurement_type_str = "close";
545  break;
547  measurement_type_str = "far";
548  break;
550  measurement_type_str = "close and far";
551  break;
552  }
553 
554  printf("measurement type: %s\n", measurement_type_str);
555 
556  printf("Sensor config\n");
557  acc_config_log(config->sensor_config);
558 }
559 
561 {
562  bool status = true;
563 
564  if (!acc_rss_get_buffer_size(handle->config.sensor_config, &handle->buffer_size))
565  {
566  printf("acc_rss_get_buffer_size() failed\n");
567  status = false;
568  }
569 
570  if (status)
571  {
572  handle->processing = acc_processing_create(handle->config.sensor_config, &handle->proc_metadata);
573  handle->buffer = acc_integration_mem_alloc(handle->buffer_size);
574 
575  uint16_t spf = acc_config_sweeps_per_frame_get(handle->config.sensor_config);
576  float sweep_rate = acc_config_sweep_rate_get(handle->config.sensor_config);
577  float frame_rate = sweep_rate / (float)spf;
578 
579  handle->cal_interval_frames = (uint16_t)((frame_rate * handle->config.calibration_interval_s) + 0.5f);
580  handle->cal_sweeps = (uint16_t)((sweep_rate * handle->config.calibration_duration_s) + 0.5f);
581  uint16_t num_points = handle->proc_metadata.sweep_data_length;
582 
583  handle->double_buffer_filter_buffer = acc_integration_mem_alloc((spf - 2U) * sizeof(*handle->double_buffer_filter_buffer));
584  handle->frame_variance = acc_integration_mem_alloc(handle->proc_metadata.frame_data_length * sizeof(*handle->frame_variance));
585  handle->arg_norm = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->arg_norm));
586  handle->ampl_mean = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->ampl_mean));
587  handle->ampl_std = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->ampl_std));
588  handle->phase_mean = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->phase_mean));
589  handle->phase_std = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->phase_std));
590  handle->dynamic_background = acc_integration_mem_alloc(handle->cal_sweeps * num_points * sizeof(*handle->dynamic_background));
591  handle->dynamic_background_guard =
592  acc_integration_mem_alloc(handle->proc_metadata.frame_data_length * sizeof(*handle->dynamic_background_guard));
593  handle->threshold_check_count = acc_integration_mem_alloc(handle->proc_metadata.sweep_data_length * sizeof(*handle->threshold_check_count));
594 
595  status = (handle->processing != NULL && handle->buffer != NULL && handle->double_buffer_filter_buffer != NULL &&
596  handle->frame_variance != NULL && handle->arg_norm != NULL && handle->ampl_mean != NULL && handle->ampl_std != NULL &&
597  handle->phase_mean != NULL && handle->phase_std != NULL && handle->dynamic_background != NULL &&
598  handle->dynamic_background_guard != NULL && handle->threshold_check_count != NULL);
599  }
600 
601  if (status)
602  {
604 
605  handle->run_close = handle->config.measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_RANGE ||
606  handle->config.measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE;
607  handle->run_far = handle->config.measurement_type == ACC_TOUCHLESS_BUTTON_FAR_RANGE ||
608  handle->config.measurement_type == ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE;
609  handle->close_num_points = handle->run_close ? acc_config_subsweep_num_points_get(handle->config.sensor_config, 0U) : 0U;
610  handle->far_num_points = handle->run_far ? (handle->run_close ? acc_config_subsweep_num_points_get(handle->config.sensor_config, 1U)
611  : acc_config_num_points_get(handle->config.sensor_config))
612  : 0U;
613 
614  handle->close_threshold = get_threshold(handle->config.sensitivity_close);
615  handle->far_threshold = get_threshold(handle->config.sensitivity_far);
616 
617  handle->close_signal = 0U;
618  handle->far_signal = 0U;
619  handle->close_non_signal = handle->config.patience_close + 1U;
620  handle->far_non_signal = handle->config.patience_far + 1U;
621  handle->close_detection = false;
622  handle->far_detection = false;
623  }
624 
625  return status;
626 }
627 
628 static float get_threshold(float sensitivity)
629 {
630  return (1.0f / sensitivity) * 10.0f;
631 }
632 
634 {
635  handle->frames_since_last_cal = 0U;
636 
637  uint16_t spf = acc_config_sweeps_per_frame_get(handle->config.sensor_config);
638  uint16_t num_points = handle->proc_metadata.sweep_data_length;
639 
640  memset(handle->dynamic_background, 0, handle->cal_sweeps * num_points * sizeof(*handle->dynamic_background));
641  handle->rows_in_dynamic_background = 0U;
642  memset(handle->dynamic_background_guard, 0, spf * num_points * sizeof(*handle->dynamic_background_guard));
643  handle->update_background = false;
644 }
645 
647 {
650 
652 
653  if (handle->sensor == NULL)
654  {
655  return false;
656  }
657 
659  {
660  return false;
661  }
662 
663  return true;
664 }
665 
667 {
668  bool status = false;
669  bool cal_complete = false;
670  acc_cal_result_t cal_result;
671  const uint16_t calibration_retries = 1U;
672 
673  // Random disturbances may cause the calibration to fail. At failure, retry at least once.
674  for (uint16_t i = 0; !status && (i <= calibration_retries); i++)
675  {
676  // Reset sensor before calibration by disabling/enabling it
679 
680  do
681  {
682  status = acc_sensor_calibrate(handle->sensor, &cal_complete, &cal_result, handle->buffer, handle->buffer_size);
683 
684  if (status && !cal_complete)
685  {
687  }
688  } while (status && !cal_complete);
689  }
690 
691  if (status)
692  {
693  // Reset sensor after calibration by disabling/enabling it
696 
697  status = acc_sensor_prepare(handle->sensor, handle->config.sensor_config, &cal_result, handle->buffer, handle->buffer_size);
698  }
699 
700  return status;
701 }
702 
704 {
705  if (!acc_sensor_measure(handle->sensor))
706  {
707  printf("acc_sensor_measure failed\n");
708  acc_sensor_status(handle->sensor);
709  return false;
710  }
711 
713  {
714  printf("Sensor interrupt timeout\n");
715  acc_sensor_status(handle->sensor);
716  return false;
717  }
718 
719  if (!acc_sensor_read(handle->sensor, handle->buffer, handle->buffer_size))
720  {
721  printf("acc_sensor_read failed\n");
722  acc_sensor_status(handle->sensor);
723  return false;
724  }
725 
726  acc_processing_execute(handle->processing, handle->buffer, &handle->proc_result);
727 
728  return true;
729 }
730 
732 {
733  uint16_t sweep_data_length = handle->proc_metadata.sweep_data_length;
734 
735  acc_algorithm_mean_matrix_i16_complex(handle->dynamic_background, handle->cal_sweeps, sweep_data_length, handle->arg_norm, 0U);
736 
737  acc_algorithm_conj_f32(handle->arg_norm, sweep_data_length);
738 
739  acc_algorithm_normalize_f32_complex(handle->arg_norm, sweep_data_length);
740 
741  for (uint16_t c = 0U; c < sweep_data_length; c++)
742  {
743  float abs_mean = 0.0f;
744  float abs_sq_term = 0.0f;
745  float phase_mean = 0.0f;
746  float phase_sq_term = 0.0f;
747  for (uint16_t r = 0U; r < handle->cal_sweeps; r++)
748  {
749  float ac = handle->dynamic_background[r * sweep_data_length + c].real * crealf(handle->arg_norm[c]);
750  float bd = handle->dynamic_background[r * sweep_data_length + c].imag * cimagf(handle->arg_norm[c]);
751  float ad = handle->dynamic_background[r * sweep_data_length + c].real * cimagf(handle->arg_norm[c]);
752  float bc = handle->dynamic_background[r * sweep_data_length + c].imag * crealf(handle->arg_norm[c]);
753  float complex element = (ac - bd) + I * (ad + bc);
754 
755  float delta = cabsf(element) - abs_mean;
756  uint16_t div = (r == 0U) ? 1U : r;
757  abs_mean += (delta / (float)div);
758  abs_sq_term += delta * (cabsf(element) - abs_mean);
759 
760  delta = cargf(element) - phase_mean;
761  phase_mean += (delta / (float)div);
762  phase_sq_term += delta * (cargf(element) - phase_mean);
763  }
764 
765  handle->ampl_mean[c] = abs_mean;
766  handle->ampl_std[c] = sqrtf(abs_sq_term / handle->cal_sweeps);
767  handle->phase_mean[c] = phase_mean;
768  handle->phase_std[c] = sqrtf(phase_sq_term / handle->cal_sweeps);
769  }
770 
771  uint16_t spf = acc_config_sweeps_per_frame_get(handle->config.sensor_config);
772 
773  for (uint16_t r = 0U; r < spf; r++)
774  {
775  for (uint16_t c = 0U; c < sweep_data_length; c++)
776  {
777  float ac = handle->proc_result.frame[r * sweep_data_length + c].real * crealf(handle->arg_norm[c]);
778  float bd = handle->proc_result.frame[r * sweep_data_length + c].imag * cimagf(handle->arg_norm[c]);
779  float ad = handle->proc_result.frame[r * sweep_data_length + c].real * cimagf(handle->arg_norm[c]);
780  float bc = handle->proc_result.frame[r * sweep_data_length + c].imag * crealf(handle->arg_norm[c]);
781  float complex element = (ac - bd) + I * (ad + bc);
782  float a = (cabsf(element) - handle->ampl_mean[c]) / handle->ampl_std[c];
783  float b = (cargf(element) - handle->phase_mean[c]) / handle->phase_std[c];
784 
785  handle->frame_variance[r * sweep_data_length + c] = sqrtf(powf(a, 2.0f) + powf(b, 2.0f));
786  }
787  }
788 }
789 
790 static bool check_count(uint16_t *count, uint16_t check_offset, uint16_t check_length)
791 {
792  bool success = false;
793 
794  for (uint16_t i = 0U; i < check_length; i++)
795  {
796  if (count[check_offset + i] > 1U)
797  {
798  success = true;
799  }
800  }
801 
802  return success;
803 }
804 
806 {
807  uint16_t spf = acc_config_sweeps_per_frame_get(handle->config.sensor_config);
808 
810  handle->cal_sweeps,
811  handle->proc_metadata.sweep_data_length,
812  handle->dynamic_background_guard,
813  acc_config_sweeps_per_frame_get(handle->config.sensor_config),
814  false);
815 
816  handle->rows_in_dynamic_background += spf;
817  handle->rows_in_dynamic_background =
818  handle->rows_in_dynamic_background > handle->cal_sweeps ? handle->cal_sweeps : handle->rows_in_dynamic_background;
819  handle->frames_since_last_cal = 0U;
820 }
821 
822 static bool get_detection(bool current_detection, uint16_t sig_count, uint16_t non_sig_count, uint16_t patience)
823 {
824  bool new_detection = !current_detection && sig_count >= patience;
825  bool keep_detection = current_detection && non_sig_count <= patience;
826 
827  return new_detection || keep_detection;
828 }
829 
831 {
832  if (acc_config_double_buffering_get(handle->config.sensor_config))
833  {
835  acc_config_sweeps_per_frame_get(handle->config.sensor_config),
836  acc_config_num_points_get(handle->config.sensor_config),
837  handle->double_buffer_filter_buffer);
838  }
839 
840  memset(handle->frame_variance, 0, handle->proc_metadata.frame_data_length * sizeof(*handle->frame_variance));
841 
842  if (handle->frames_since_last_cal > handle->cal_interval_frames)
843  {
845  }
846  else if (handle->rows_in_dynamic_background == handle->cal_sweeps)
847  {
849  }
850 
851  uint16_t threshold_check_offset = 0U;
852 
853  if (handle->run_close)
854  {
856  acc_config_sweeps_per_frame_get(handle->config.sensor_config),
857  handle->proc_metadata.sweep_data_length,
858  handle->close_threshold,
859  handle->threshold_check_count,
860  threshold_check_offset,
861  handle->close_num_points,
862  1U);
863 
864  threshold_check_offset = handle->close_num_points;
865  }
866 
867  if (handle->run_far)
868  {
870  acc_config_sweeps_per_frame_get(handle->config.sensor_config),
871  handle->proc_metadata.sweep_data_length,
872  handle->far_threshold,
873  handle->threshold_check_count,
874  threshold_check_offset,
875  handle->far_num_points,
876  1U);
877  }
878 
879  if (check_count(handle->threshold_check_count, 0U, handle->proc_metadata.sweep_data_length))
880  {
881  uint16_t close_offset = 0U;
882  uint16_t far_offset = handle->close_num_points;
883 
884  if (handle->run_close)
885  {
886  if (check_count(handle->threshold_check_count, close_offset, handle->close_num_points))
887  {
888  handle->close_signal++;
889  handle->close_non_signal = 0U;
890  }
891  else
892  {
893  handle->close_signal = 0U;
894  handle->close_non_signal++;
895  }
896  }
897 
898  if (handle->run_far)
899  {
900  if (check_count(handle->threshold_check_count, far_offset, handle->far_num_points))
901  {
902  handle->far_signal++;
903  handle->far_non_signal = 0U;
904  }
905  else
906  {
907  handle->far_signal = 0U;
908  handle->far_non_signal++;
909  }
910  }
911 
912  handle->update_background = false;
913  memset(handle->dynamic_background_guard, 0, handle->proc_metadata.frame_data_length * sizeof(*handle->dynamic_background_guard));
914  handle->frames_since_last_cal++;
915  }
916  else
917  {
918  handle->close_signal = 0U;
919  handle->far_signal = 0U;
920  handle->close_non_signal++;
921  handle->far_non_signal++;
922 
923  if (handle->update_background)
924  {
926  }
927 
928  memcpy(handle->dynamic_background_guard,
929  handle->proc_result.frame,
930  handle->proc_metadata.frame_data_length * sizeof(*handle->dynamic_background_guard));
931  handle->update_background = true;
932  }
933 
934  memset(result, 0, sizeof(*result));
935 
938 
939  if (handle->run_close)
940  {
941  handle->close_detection =
942  get_detection(handle->close_detection, handle->close_signal, handle->close_non_signal, handle->config.patience_close);
944  }
945 
946  if (handle->run_far)
947  {
948  handle->far_detection = get_detection(handle->far_detection, handle->far_signal, handle->far_non_signal, handle->config.patience_far);
950  }
951 
952  return true;
953 }
954 
956 {
957  if (result->close_result != ACC_TOUCHLESS_BUTTON_RANGE_NOT_USED)
958  {
959  printf("Close detection: %s\n", result->close_result == ACC_TOUCHLESS_BUTTON_RANGE_DETECTION ? "True" : "False");
960  }
961 
962  if (result->far_result != ACC_TOUCHLESS_BUTTON_RANGE_NOT_USED)
963  {
964  printf("Far detection: %s\n", result->far_result == ACC_TOUCHLESS_BUTTON_RANGE_DETECTION ? "True" : "False");
965  }
966 }
acc_touchless_button_result_t
Touchless button application result.
Definition: ref_app_touchless_button.c:159
acc_touchless_button_handle_t::proc_result
acc_processing_result_t proc_result
Definition: ref_app_touchless_button.c:114
acc_config_start_point_set
void acc_config_start_point_set(acc_config_t *config, int32_t start_point)
Set the starting point of the sweep.
acc_touchless_button_handle_t::buffer
void * buffer
Definition: ref_app_touchless_button.c:115
acc_config_inter_frame_idle_state_set
void acc_config_inter_frame_idle_state_set(acc_config_t *config, acc_config_idle_state_t idle_state)
Set inter frame idle state.
acc_touchless_button_handle_t::config
acc_touchless_button_config_t config
Definition: ref_app_touchless_button.c:110
acc_hal_integration_sensor_supply_off
void acc_hal_integration_sensor_supply_off(acc_sensor_id_t sensor_id)
Power off sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:104
acc_rss_a121.h
acc_touchless_button_handle_t::far_threshold
float far_threshold
Definition: ref_app_touchless_button.c:132
acc_processing_destroy
void acc_processing_destroy(acc_processing_t *handle)
Destroy a processing instance identified with the provided processing handle.
acc_config_subsweep_num_points_get
uint16_t acc_config_subsweep_num_points_get(const acc_config_t *config, uint8_t index)
Get the number of data points to measure.
acc_hal_integration_sensor_supply_on
void acc_hal_integration_sensor_supply_on(acc_sensor_id_t sensor_id)
Power on sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:99
get_detection
static bool get_detection(bool current_detection, uint16_t sig_count, uint16_t non_sig_count, uint16_t patience)
Definition: ref_app_touchless_button.c:822
ACC_TOUCHLESS_BUTTON_PRESET_NONE
@ ACC_TOUCHLESS_BUTTON_PRESET_NONE
Definition: ref_app_touchless_button.c:97
acc_processing_result_t
Result provided by the processing module.
Definition: acc_processing.h:71
acc_touchless_button_handle_t::close_signal
uint16_t close_signal
Definition: ref_app_touchless_button.c:138
init_handle
static bool init_handle(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:560
acc_touchless_button_handle_t::far_non_signal
uint16_t far_non_signal
Definition: ref_app_touchless_button.c:141
ACC_TOUCHLESS_BUTTON_RANGE_DETECTION
@ ACC_TOUCHLESS_BUTTON_RANGE_DETECTION
Definition: ref_app_touchless_button.c:153
acc_sensor_read
bool acc_sensor_read(const acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
Read out radar data.
SENSOR_TIMEOUT_MS
#define SENSOR_TIMEOUT_MS
Definition: ref_app_touchless_button.c:29
acc_touchless_button_handle_t::sensor
acc_sensor_t * sensor
Definition: ref_app_touchless_button.c:111
acc_version.h
acc_touchless_button_handle_t::proc_metadata
acc_processing_metadata_t proc_metadata
Definition: ref_app_touchless_button.c:113
acc_rss_get_buffer_size
bool acc_rss_get_buffer_size(const acc_config_t *config, uint32_t *buffer_size)
Get the buffer size needed for the specified config.
acc_config_num_subsweeps_get
uint8_t acc_config_num_subsweeps_get(const acc_config_t *config)
Get the number of subsweeps to use.
acc_algorithm_normalize_f32_complex
void acc_algorithm_normalize_f32_complex(float complex *data, uint16_t data_length)
Normalize all elements in an array individually.
Definition: acc_algorithm.c:584
acc_touchless_button_config_t::patience_far
uint16_t patience_far
Definition: ref_app_touchless_button.c:74
acc_touchless_button_config_t::sensor_config
acc_config_t * sensor_config
Definition: ref_app_touchless_button.c:92
acc_config_profile_set
void acc_config_profile_set(acc_config_t *config, acc_config_profile_t profile)
Set a profile.
init_sensor
static bool init_sensor(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:646
acc_int16_complex_t
Data type for interger-based representation of complex numbers.
Definition: acc_definitions_common.h:40
acc_algorithm_double_buffering_frame_filter
void acc_algorithm_double_buffering_frame_filter(acc_int16_complex_t *frame, const uint16_t sweeps_per_frame, const uint16_t num_points, int32_t *work_buffer)
Double buffering frame filter.
Definition: acc_algorithm.c:774
acc_config_sweeps_per_frame_set
void acc_config_sweeps_per_frame_set(acc_config_t *config, uint16_t sweeps)
Set sweeps per frame.
acc_config_destroy
void acc_config_destroy(acc_config_t *config)
Destroy a configuration freeing any resources allocated.
ACC_TOUCHLESS_BUTTON_RANGE_NO_DETECTION
@ ACC_TOUCHLESS_BUTTON_RANGE_NO_DETECTION
Definition: ref_app_touchless_button.c:152
acc_touchless_button_handle_t::run_far
bool run_far
Definition: ref_app_touchless_button.c:135
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
acc_touchless_button_handle_t::close_non_signal
uint16_t close_non_signal
Definition: ref_app_touchless_button.c:140
acc_touchless_button_handle_t::close_detection
bool close_detection
Definition: ref_app_touchless_button.c:142
acc_processing_execute
void acc_processing_execute(acc_processing_t *handle, void *buffer, acc_processing_result_t *result)
Process the data according to the configuration used in create.
ACC_TOUCHLESS_BUTTON_FAR_RANGE
@ ACC_TOUCHLESS_BUTTON_FAR_RANGE
Definition: ref_app_touchless_button.c:43
get_threshold
static float get_threshold(float sensitivity)
Definition: ref_app_touchless_button.c:628
acc_config_inter_sweep_idle_state_set
void acc_config_inter_sweep_idle_state_set(acc_config_t *config, acc_config_idle_state_t idle_state)
Set inter sweep idle state.
acc_touchless_button_handle_t::update_background
bool update_background
Definition: ref_app_touchless_button.c:129
acc_config_create
acc_config_t * acc_config_create(void)
Create a configuration.
update_background
static void update_background(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:805
ACC_TOUCHLESS_BUTTON_PRESET_CLOSE_AND_FAR
@ ACC_TOUCHLESS_BUTTON_PRESET_CLOSE_AND_FAR
Definition: ref_app_touchless_button.c:100
acc_touchless_button_preset_t
acc_touchless_button_preset_t
Definition: ref_app_touchless_button.c:95
acc_integration.h
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
acc_touchless_button_config_t::calibration_duration_s
float calibration_duration_s
Definition: ref_app_touchless_button.c:78
acc_hal_rss_integration_get_implementation
const acc_hal_a121_t * acc_hal_rss_integration_get_implementation(void)
Get hal implementation reference.
Definition: acc_hal_integration_stm32cube_xm.c:152
acc_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:592
acc_processing_metadata_t
Metadata that will be populated by the processing module during creation.
Definition: acc_processing.h:36
acc_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_touchless_button_measurement_type_t
acc_touchless_button_measurement_type_t
Application measurement type.
Definition: ref_app_touchless_button.c:34
acc_rss_hal_register
bool acc_rss_hal_register(const acc_hal_a121_t *hal)
Register an integration.
acc_sensor.h
acc_touchless_button_handle_t::far_detection
bool far_detection
Definition: ref_app_touchless_button.c:143
acc_config_double_buffering_set
void acc_config_double_buffering_set(acc_config_t *config, bool enable)
Enable or disable double buffering.
acc_algorithm_mean_matrix_i16_complex
void acc_algorithm_mean_matrix_i16_complex(const acc_int16_complex_t *matrix, uint16_t rows, uint16_t cols, float complex *out, uint16_t axis)
Calculate mean array of a matrix.
Definition: acc_algorithm.c:554
acc_config_hwaas_set
void acc_config_hwaas_set(acc_config_t *config, uint16_t hwaas)
Set the hardware accelerated average samples (HWAAS)
acc_config_sweeps_per_frame_get
uint16_t acc_config_sweeps_per_frame_get(const acc_config_t *config)
Get the number of sweeps per frame.
acc_touchless_button_handle_t
Touchless button application handle.
Definition: ref_app_touchless_button.c:108
SENSOR_ID
#define SENSOR_ID
Definition: ref_app_touchless_button.c:26
acc_touchless_button_handle_t::ampl_std
float * ampl_std
Definition: ref_app_touchless_button.c:121
acc_touchless_button_handle_t::close_threshold
float close_threshold
Definition: ref_app_touchless_button.c:131
ACC_TOUCHLESS_BUTTON_CLOSE_RANGE
@ ACC_TOUCHLESS_BUTTON_CLOSE_RANGE
Definition: ref_app_touchless_button.c:39
acc_hal_integration_wait_for_sensor_interrupt
bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms)
Wait for a sensor interrupt.
Definition: acc_hal_integration_stm32cube_xm.c:130
acc_touchless_button_handle_t::rows_in_dynamic_background
uint16_t rows_in_dynamic_background
Definition: ref_app_touchless_button.c:127
acc_touchless_button_config_t::sensitivity_far
float sensitivity_far
Definition: ref_app_touchless_button.c:69
acc_hal_integration_a121.h
cleanup
static void cleanup(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:317
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
ACC_CONFIG_IDLE_STATE_READY
@ ACC_CONFIG_IDLE_STATE_READY
Definition: acc_definitions_a121.h:76
result
cargo_result_t result
Definition: i2c_example_cargo.c:43
acc_version_get
const char * acc_version_get(void)
Get the version of the Acconeer software.
acc_config_t
struct acc_config acc_config_t
Definition: acc_config.h:24
printf
#define printf
Definition: printf.h:60
acc_touchless_button_handle_t::phase_std
float * phase_std
Definition: ref_app_touchless_button.c:123
ACC_TOUCHLESS_BUTTON_RANGE_NOT_USED
@ ACC_TOUCHLESS_BUTTON_RANGE_NOT_USED
Definition: ref_app_touchless_button.c:151
acc_touchless_button_handle_t::dynamic_background
acc_int16_complex_t * dynamic_background
Definition: ref_app_touchless_button.c:126
acc_config_num_subsweeps_set
void acc_config_num_subsweeps_set(acc_config_t *config, uint8_t num_subsweeps)
Set the number of subsweeps to use.
acc_hal_integration_sensor_enable
void acc_hal_integration_sensor_enable(acc_sensor_id_t sensor_id)
Enable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:109
acc_touchless_button_handle_t::cal_sweeps
uint16_t cal_sweeps
Definition: ref_app_touchless_button.c:125
acc_config_step_length_set
void acc_config_step_length_set(acc_config_t *config, uint16_t step_length)
Set the step length in a sweep.
acc_config_num_points_set
void acc_config_num_points_set(acc_config_t *config, uint16_t num_points)
Set the number of data points to measure.
acc_config_subsweep_start_point_set
void acc_config_subsweep_start_point_set(acc_config_t *config, int32_t start_point, uint8_t index)
Set the starting point of the sweep.
acc_touchless_button_handle_t::buffer_size
uint32_t buffer_size
Definition: ref_app_touchless_button.c:116
acc_hal_definitions_a121.h
acc_touchless_button_handle_t::close_num_points
uint16_t close_num_points
Definition: ref_app_touchless_button.c:136
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: ref_app_touchless_button.c:197
acc_config_sweep_rate_set
void acc_config_sweep_rate_set(acc_config_t *config, float sweep_rate)
Set the sweep rate.
acc_config_subsweep_profile_set
void acc_config_subsweep_profile_set(acc_config_t *config, acc_config_profile_t profile, uint8_t index)
Set a profile.
acc_touchless_button_result_t::far_result
acc_touchless_button_range_result_t far_result
Definition: ref_app_touchless_button.c:162
acc_touchless_button_handle_t::frame_variance
float * frame_variance
Definition: ref_app_touchless_button.c:118
acc_touchless_button_handle_t::far_num_points
uint16_t far_num_points
Definition: ref_app_touchless_button.c:137
acc_algorithm_conj_f32
void acc_algorithm_conj_f32(float complex *data, uint16_t data_length)
Inline calculate conjugate of all elements in an array.
Definition: acc_algorithm.c:576
acc_touchless_button_range_result_t
acc_touchless_button_range_result_t
Touchless button range result.
Definition: ref_app_touchless_button.c:149
acc_hal_integration_sensor_disable
void acc_hal_integration_sensor_disable(acc_sensor_id_t sensor_id)
Disable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:119
acc_touchless_button_result_t::close_result
acc_touchless_button_range_result_t close_result
Definition: ref_app_touchless_button.c:161
acc_touchless_button_config_t::measurement_type
acc_touchless_button_measurement_type_t measurement_type
Definition: ref_app_touchless_button.c:88
acc_processing_t
struct acc_processing_handle acc_processing_t
Definition: acc_processing.h:30
validate_config
static bool validate_config(acc_touchless_button_config_t *config)
Definition: ref_app_touchless_button.c:473
acc_integration_log.h
acc_touchless_button_handle_t::double_buffer_filter_buffer
int32_t * double_buffer_filter_buffer
Definition: ref_app_touchless_button.c:117
ACC_LOG_FLOAT_TO_INTEGER
#define ACC_LOG_FLOAT_TO_INTEGER(a)
Definition: acc_integration_log.h:26
acc_touchless_button_config_t::patience_close
uint16_t patience_close
Definition: ref_app_touchless_button.c:64
reset_background
static void reset_background(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:633
acc_touchless_button_handle_t::run_close
bool run_close
Definition: ref_app_touchless_button.c:134
acc_config_continuous_sweep_mode_set
void acc_config_continuous_sweep_mode_set(acc_config_t *config, bool enabled)
Set continuous sweep mode.
process
static bool process(acc_touchless_button_handle_t *handle, acc_touchless_button_result_t *result)
Definition: ref_app_touchless_button.c:830
acc_sensor_status
void acc_sensor_status(const acc_sensor_t *sensor)
Check the status of the sensor.
acc_touchless_button_handle_t::dynamic_background_guard
acc_int16_complex_t * dynamic_background_guard
Definition: ref_app_touchless_button.c:128
acc_touchless_button_handle_t::processing
acc_processing_t * processing
Definition: ref_app_touchless_button.c:112
acc_config_subsweep_receiver_gain_set
void acc_config_subsweep_receiver_gain_set(acc_config_t *config, uint8_t gain, uint8_t index)
Set receiver gain setting.
acc_algorithm.h
acc_touchless_button_handle_t::ampl_mean
float * ampl_mean
Definition: ref_app_touchless_button.c:120
acc_touchless_button_handle_t::threshold_check_count
uint16_t * threshold_check_count
Definition: ref_app_touchless_button.c:133
calc_variance
static void calc_variance(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:731
acc_sensor_prepare
bool acc_sensor_prepare(acc_sensor_t *sensor, const acc_config_t *config, const acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Prepare a sensor to do a measurement.
ACC_TOUCHLESS_BUTTON_PRESET_FAR
@ ACC_TOUCHLESS_BUTTON_PRESET_FAR
Definition: ref_app_touchless_button.c:99
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
acc_config_double_buffering_get
bool acc_config_double_buffering_get(const acc_config_t *config)
Get the double buffering configuration.
acc_definitions_common.h
acc_config_subsweep_hwaas_set
void acc_config_subsweep_hwaas_set(acc_config_t *config, uint16_t hwaas, uint8_t index)
Set the hardware accelerated average samples (HWAAS)
acc_config_receiver_gain_set
void acc_config_receiver_gain_set(acc_config_t *config, uint8_t gain)
Set receiver gain setting.
acc_config_log
void acc_config_log(const acc_config_t *config)
Print a configuration to the log.
acc_config_subsweep_step_length_set
void acc_config_subsweep_step_length_set(acc_config_t *config, uint16_t step_length, uint8_t index)
Set the step length in a sweep.
check_count
static bool check_count(uint16_t *count, uint16_t check_offset, uint16_t check_length)
Definition: ref_app_touchless_button.c:790
acc_config.h
DEFAULT_PRESET
#define DEFAULT_PRESET
Definition: ref_app_touchless_button.c:103
acc_config_sweep_rate_get
float acc_config_sweep_rate_get(const acc_config_t *config)
Get the sweep rate.
ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE
@ ACC_TOUCHLESS_BUTTON_CLOSE_AND_FAR_RANGE
Definition: ref_app_touchless_button.c:47
acc_touchless_button_handle_t::frames_since_last_cal
uint16_t frames_since_last_cal
Definition: ref_app_touchless_button.c:130
acc_sensor_calibrate
bool acc_sensor_calibrate(acc_sensor_t *sensor, bool *cal_complete, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Calibrate a sensor.
acc_config_subsweep_num_points_set
void acc_config_subsweep_num_points_set(acc_config_t *config, uint16_t num_points, uint8_t index)
Set the number of data points to measure.
acc_config_num_points_get
uint16_t acc_config_num_points_get(const acc_config_t *config)
Get the number of data points to measure.
PRIfloat
#define PRIfloat
Specifier for printing float type using integers.
Definition: acc_integration_log.h:31
ACC_TOUCHLESS_BUTTON_PRESET_CLOSE
@ ACC_TOUCHLESS_BUTTON_PRESET_CLOSE
Definition: ref_app_touchless_button.c:98
ACC_CONFIG_PROFILE_1
@ ACC_CONFIG_PROFILE_1
Definition: acc_definitions_a121.h:52
acc_touchless_button_config_t::calibration_interval_s
float calibration_interval_s
Definition: ref_app_touchless_button.c:83
acc_sensor_measure
bool acc_sensor_measure(acc_sensor_t *sensor)
Start a radar measurement with previously prepared configuration.
acc_algorithm_count_points_above_threshold
void acc_algorithm_count_points_above_threshold(const float *matrix, uint16_t rows, uint16_t cols, const float threshold, uint16_t *count, uint16_t offset, uint16_t threshold_check_length, uint16_t axis)
Count points in matrix above threshold row-wise or col-wise.
Definition: acc_algorithm.c:1281
acc_touchless_button_handle_t::arg_norm
float complex * arg_norm
Definition: ref_app_touchless_button.c:119
acc_processing_create
acc_processing_t * acc_processing_create(const acc_config_t *config, acc_processing_metadata_t *processing_metadata)
Create a processing instance with the provided configuration.
measure
static bool measure(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:703
acc_touchless_button_config_t
Touchless button application config.
Definition: ref_app_touchless_button.c:53
acc_algorithm_roll_and_push_mult_matrix_i16_complex
void acc_algorithm_roll_and_push_mult_matrix_i16_complex(acc_int16_complex_t *data, uint16_t data_rows, uint16_t cols, const acc_int16_complex_t *matrix, uint16_t matrix_rows, bool pos_shift)
Roll row elements and push multiple columns.
Definition: acc_algorithm.c:237
acc_touchless_button_handle_t::phase_mean
float * phase_mean
Definition: ref_app_touchless_button.c:122
acc_processing.h
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
ACC_CONFIG_PROFILE_3
@ ACC_CONFIG_PROFILE_3
Definition: acc_definitions_a121.h:54
acc_touchless_button_config_t::sensitivity_close
float sensitivity_close
Definition: ref_app_touchless_button.c:59
acc_touchless_button_handle_t::far_signal
uint16_t far_signal
Definition: ref_app_touchless_button.c:139
do_sensor_calibration_and_prepare
static bool do_sensor_calibration_and_prepare(acc_touchless_button_handle_t *handle)
Definition: ref_app_touchless_button.c:666
acc_sensor_destroy
void acc_sensor_destroy(acc_sensor_t *sensor)
Destroy a sensor instance freeing any resources allocated.
print_result
static void print_result(acc_touchless_button_result_t *result)
Definition: ref_app_touchless_button.c:955
config_log
static void config_log(acc_touchless_button_config_t *config)
Definition: ref_app_touchless_button.c:512
set_config
static void set_config(acc_touchless_button_config_t *config, acc_touchless_button_preset_t preset)
Definition: ref_app_touchless_button.c:393
acc_sensor_create
acc_sensor_t * acc_sensor_create(acc_sensor_id_t sensor_id)
Create a sensor instance.
acc_touchless_button_handle_t::cal_interval_frames
uint16_t cal_interval_frames
Definition: ref_app_touchless_button.c:124