example_hand_motion_detection_main.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 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 <stdbool.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include "acc_config.h"
14 #include "acc_integration.h"
15 #include "acc_processing.h"
16 #include "acc_rss_a121.h"
17 #include "acc_sensor.h"
18 #include "acc_version.h"
21 
22 #define SENSOR_ID (1U)
23 #define SENSOR_TIMEOUT_MS (1000U)
24 
25 /**
26  * @brief Frees any allocated resources
27  */
29 
30 /**
31  * @brief Performs sensor calibration (with retry)
32  */
33 static bool do_sensor_calibration(acc_sensor_t *sensor, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size);
34 
35 /**
36  * @brief Handle sensor indications
37  */
41  acc_cal_result_t *cal_result,
42  void *buffer,
43  uint32_t buffer_size,
44  bool *data_reliable);
45 
46 /**
47  * @brief Print a processor result in a human-readable format
48  */
50 
51 static bool enter_hibernate(acc_sensor_t *sensor);
52 
53 static bool exit_hibernate(acc_sensor_t *sensor);
54 
55 int acconeer_main(int argc, char *argv[])
56 {
57  (void)argc;
58  (void)argv;
59  acc_sensor_t *sensor = NULL;
60  acc_cal_result_t cal_result;
61  void *buffer = NULL;
62  uint32_t buffer_size = 0;
63 
64  hand_motion_detection_config_t *hand_motion_detection_config = NULL;
66  hand_motion_detection_result_t hand_motion_detection_result = {0};
67 
68  printf("Acconeer software version %s\n", acc_version_get());
69 
71 
72  if (!acc_rss_hal_register(hal))
73  {
74  return EXIT_FAILURE;
75  }
76 
77  hand_motion_detection_config = hand_motion_detection_config_create();
78 
79  if (hand_motion_detection_config == NULL)
80  {
81  printf("hand_motion_detection_config_create() failed\n");
82  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
83  return EXIT_FAILURE;
84  }
85 
87 
89  if (hand_motion_detection_handle == NULL)
90  {
91  printf("hand_motion_detection_handle_create() failed\n");
92  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
93  return EXIT_FAILURE;
94  }
95 
97 
99  {
100  printf("acc_rss_get_buffer_size() failed\n");
101  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
102  return EXIT_FAILURE;
103  }
104 
106  if (buffer == NULL)
107  {
108  printf("buffer allocation failed\n");
109  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
110  return EXIT_FAILURE;
111  }
112 
115 
117  if (sensor == NULL)
118  {
119  printf("acc_sensor_create() failed\n");
120  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
121  return EXIT_FAILURE;
122  }
123 
124  if (!do_sensor_calibration(sensor, &cal_result, buffer, buffer_size))
125  {
126  printf("do_sensor_calibration() failed\n");
128  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
129  return EXIT_FAILURE;
130  }
131 
132  while (true)
133  {
135  {
136  printf("hand_motion_detection_prepare() failed\n");
137  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
138  return EXIT_FAILURE;
139  }
140 
142  {
143  printf("acc_sensor_measure failed\n");
145  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
146  return EXIT_FAILURE;
147  }
148 
150  {
151  printf("Sensor interrupt timeout\n");
153  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
154  return EXIT_FAILURE;
155  }
156 
158  {
159  printf("acc_sensor_read failed\n");
161  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
162  return EXIT_FAILURE;
163  }
164 
165  if (!enter_hibernate(sensor))
166  {
167  printf("enter_hibernate failed\n");
168  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
169  return EXIT_FAILURE;
170  }
171 
172  hand_motion_detection_process(hand_motion_detection_handle, buffer, &hand_motion_detection_result);
173 
174  bool data_reliable;
175 
177  &hand_motion_detection_result,
178  sensor,
179  &cal_result,
180  buffer,
181  buffer_size,
182  &data_reliable))
183  {
184  printf("handle_indications() failed\n");
185  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
186  return EXIT_FAILURE;
187  }
188 
189  if (data_reliable)
190  {
191  print_hand_motion_detection_result(&hand_motion_detection_result);
192  }
193 
195 
196  if (!exit_hibernate(sensor))
197  {
198  printf("exit_hibernate failed\n");
199  return EXIT_FAILURE;
200  }
201  }
202 
203  cleanup(sensor, buffer, hand_motion_detection_config, hand_motion_detection_handle);
204 
205  printf("Application finished OK\n");
206 
207  return EXIT_SUCCESS;
208 }
209 
211 {
214 
215  if (sensor != NULL)
216  {
218  }
219 
220  if (buffer != NULL)
221  {
223  }
224 
225  if (config != NULL)
226  {
228  }
229 
230  if (handle != NULL)
231  {
233  }
234 }
235 
236 static bool do_sensor_calibration(acc_sensor_t *sensor, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
237 {
238  bool status = false;
239  bool cal_complete = false;
240  const uint16_t calibration_retries = 1U;
241 
242  // Random disturbances may cause the calibration to fail. At failure, retry at least once.
243  for (uint16_t i = 0; !status && (i <= calibration_retries); i++)
244  {
245  // Reset sensor before calibration by disabling/enabling it
248 
249  do
250  {
251  status = acc_sensor_calibrate(sensor, &cal_complete, cal_result, buffer, buffer_size);
252 
253  if (status && !cal_complete)
254  {
256  }
257  } while (status && !cal_complete);
258  }
259 
260  if (status)
261  {
262  // Reset sensor after calibration by disabling/enabling it
265  }
266 
267  return status;
268 }
269 
273  acc_cal_result_t *cal_result,
274  void *buffer,
275  uint32_t buffer_size,
276  bool *data_reliable)
277 {
278  bool status = true;
279 
280  *data_reliable = true;
281 
282  if (result->proc_result.data_saturated)
283  {
284  *data_reliable = false;
285 
286  printf("Data saturated. Try to reduce the sensor gain.\n");
287  }
288 
289  if (result->proc_result.frame_delayed)
290  {
291  printf("Frame delayed. Could not read data fast enough.\n");
292  printf("Try lowering the frame rate or call 'acc_sensor_read' more frequently.\n");
293  }
294 
295  if (result->proc_result.calibration_needed)
296  {
297  printf("The current calibration is not valid for the current temperature.\n");
298  printf("Re-calibrating sensor...\n");
299 
300  if (!exit_hibernate(sensor))
301  {
302  printf("exit_hibernate failed\n");
303  status = false;
304  }
305 
306  if (status)
307  {
308  if (!do_sensor_calibration(sensor, cal_result, buffer, buffer_size))
309  {
310  printf("do_sensor_calibration() failed\n");
312  status = false;
313  }
314  else
315  {
316  printf("Sensor recalibration done!\n");
317  }
318  }
319 
320  if (status)
321  {
322  if (!hand_motion_detection_prepare(handle, sensor, cal_result, buffer, buffer_size, true))
323  {
324  printf("hand_motion_detection_prepare() failed\n");
325  status = false;
326  }
327  }
328 
329  if (status)
330  {
331  if (!enter_hibernate(sensor))
332  {
333  printf("enter_hibernate failed\n");
334  status = false;
335  }
336  }
337 
338  *data_reliable = false;
339 
340  printf("The sensor was successfully re-calibrated.\n");
341  }
342 
343  return status;
344 }
345 
347 {
348  printf("App mode: %s\n", result->app_mode == HAND_MOTION_DETECTION_APP_MODE_PRESENCE ? "presence" : "handmotion");
349 
350  if (result->algo_result_available)
351  {
352  printf("Detection state: ");
353 
354  switch (result->algo_result.detection_state)
355  {
357  printf("No detection\n");
358  break;
360  printf("Detection\n");
361  break;
363  printf("Retention\n");
364  break;
365  }
366  }
367 }
368 
370 {
371  bool status = true;
372 
374  {
375  printf("acc_sensor_hibernate_on failed\n");
377  status = false;
378  }
379 
381  return status;
382 }
383 
385 {
386  bool status = true;
387 
390  {
391  printf("acc_sensor_hibernate_off failed\n");
393  status = false;
394  }
395 
396  return status;
397 }
cleanup
static void cleanup(acc_sensor_t *sensor, void *buffer, hand_motion_detection_config_t *config, hand_motion_detection_handle_t *handle)
Frees any allocated resources.
Definition: example_hand_motion_detection_main.c:210
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
cargo_result_t::calibration_needed
bool calibration_needed
Definition: example_cargo.h:112
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
hand_motion_detection_prepare
bool hand_motion_detection_prepare(hand_motion_detection_handle_t *handle, acc_sensor_t *sensor, const acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size, bool force_prepare)
Prepare hand motion.
Definition: example_hand_motion_detection.c:295
enter_hibernate
static bool enter_hibernate(acc_sensor_t *sensor)
Definition: example_hand_motion_detection_main.c:369
acc_sensor_read
bool acc_sensor_read(const acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
Read out radar data.
buffer
void * buffer
Definition: i2c_example_cargo.c:40
acc_version.h
hand_motion_detection_config_create
hand_motion_detection_config_t * hand_motion_detection_config_create(void)
Create a hand motion configuration.
Definition: example_hand_motion_detection.c:63
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
hand_motion_detection_config_destroy
void hand_motion_detection_config_destroy(hand_motion_detection_config_t *config)
Destroy a hand motion configuration.
Definition: example_hand_motion_detection.c:81
HAND_MOTION_DETECTION_STATE_RETENTION
@ HAND_MOTION_DETECTION_STATE_RETENTION
Definition: example_hand_motion_detection.h:39
hand_motion_detection_handle_create
hand_motion_detection_handle_t * hand_motion_detection_handle_create(const hand_motion_detection_config_t *hand_motion_detection_config, acc_sensor_id_t sensor_id)
Create a hand_motion handle.
Definition: example_hand_motion_detection.c:137
acc_integration.h
hand_motion_detection_result_t
Result type.
Definition: example_hand_motion_detection.h:81
print_hand_motion_detection_result
static void print_hand_motion_detection_result(const hand_motion_detection_result_t *result)
Print a processor result in a human-readable format.
Definition: example_hand_motion_detection_main.c:346
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
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_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_rss_hal_register
bool acc_rss_hal_register(const acc_hal_a121_t *hal)
Register an integration.
acc_sensor.h
buffer_size
uint32_t buffer_size
Definition: i2c_example_cargo.c:41
sensor
acc_sensor_t * sensor
Definition: i2c_example_cargo.c:33
example_hand_motion_detection.h
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
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: example_hand_motion_detection_main.c:55
acc_hal_integration_a121.h
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
HAND_MOTION_DETECTION_APP_MODE_PRESENCE
@ HAND_MOTION_DETECTION_APP_MODE_PRESENCE
Definition: example_hand_motion_detection.h:31
acc_sensor_hibernate_off
bool acc_sensor_hibernate_off(const acc_sensor_t *sensor)
Restore sensor after exiting hibernation.
hand_motion_detection_process
void hand_motion_detection_process(hand_motion_detection_handle_t *handle, void *buffer, hand_motion_detection_result_t *hand_motion_detection_result)
Process Sparse IQ data.
Definition: example_hand_motion_detection.c:322
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.
printf
#define printf
Definition: printf.h:60
HAND_MOTION_DETECTION_PRESET_FAUCET
@ HAND_MOTION_DETECTION_PRESET_FAUCET
Definition: example_hand_motion_detection.h:26
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_hal_definitions_a121.h
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
HAND_MOTION_DETECTION_STATE_DETECTION
@ HAND_MOTION_DETECTION_STATE_DETECTION
Definition: example_hand_motion_detection.h:38
do_sensor_calibration
static bool do_sensor_calibration(acc_sensor_t *sensor, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Performs sensor calibration (with retry)
Definition: example_hand_motion_detection_main.c:236
hand_motion_detection_get_buffer_size
bool hand_motion_detection_get_buffer_size(hand_motion_detection_handle_t *handle, uint32_t *buffer_size)
Get buffer size needed.
Definition: example_hand_motion_detection.c:269
example_hand_motion_detection_main.h
acc_sensor_hibernate_on
bool acc_sensor_hibernate_on(acc_sensor_t *sensor)
Prepare sensor for entering hibernation.
exit_hibernate
static bool exit_hibernate(acc_sensor_t *sensor)
Definition: example_hand_motion_detection_main.c:384
handle_indications
static bool handle_indications(hand_motion_detection_handle_t *handle, hand_motion_detection_result_t *result, acc_sensor_t *sensor, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size, bool *data_reliable)
Handle sensor indications.
Definition: example_hand_motion_detection_main.c:270
SENSOR_ID
#define SENSOR_ID
Definition: example_hand_motion_detection_main.c:22
acc_sensor_status
void acc_sensor_status(const acc_sensor_t *sensor)
Check the status of the sensor.
HAND_MOTION_DETECTION_STATE_NO_DETECTION
@ HAND_MOTION_DETECTION_STATE_NO_DETECTION
Definition: example_hand_motion_detection.h:37
hand_motion_detection_handle_destroy
void hand_motion_detection_handle_destroy(hand_motion_detection_handle_t *handle)
Destroy a hand_motion handle.
Definition: example_hand_motion_detection.c:207
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
acc_integration_sleep_until_periodic_wakeup
void acc_integration_sleep_until_periodic_wakeup(void)
Put the system in sleep until the periodic timer triggers.
Definition: acc_integration_stm32.c:552
hand_motion_detection_set_config
void hand_motion_detection_set_config(hand_motion_detection_preset_t preset, hand_motion_detection_config_t *config)
Set config specified by the preset.
Definition: example_hand_motion_detection.c:94
acc_config.h
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.
hand_motion_detection_handle
Definition: example_hand_motion_detection.c:23
acc_sensor_measure
bool acc_sensor_measure(acc_sensor_t *sensor)
Start a radar measurement with previously prepared configuration.
acc_processing.h
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
hand_motion_detection_config_log
void hand_motion_detection_config_log(hand_motion_detection_handle_t *handle)
Print configuration.
Definition: example_hand_motion_detection.c:240
SENSOR_TIMEOUT_MS
#define SENSOR_TIMEOUT_MS
Definition: example_hand_motion_detection_main.c:23
acc_sensor_destroy
void acc_sensor_destroy(acc_sensor_t *sensor)
Destroy a sensor instance freeing any resources allocated.
acc_sensor_create
acc_sensor_t * acc_sensor_create(acc_sensor_id_t sensor_id)
Create a sensor instance.
hand_motion_detection_config_t
Configuration for hand_motion.
Definition: example_hand_motion_detection.h:62