@@ -303,18 +303,6 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
303303 const TEST_STAGE_SLEEP_MS : usize = 100 ;
304304 const MAX_SAMPLE_ATTEMPTS : usize = 2 * TEST_SAMPLES * TEST_STAGE_SLEEP_MS ;
305305
306- let mut avg_x_pos: f32 = 0.0 ;
307- let mut avg_y_pos: f32 = 0.0 ;
308- let mut avg_z_pos: f32 = 0.0 ;
309-
310- let mut avg_x_neg: f32 = 0.0 ;
311- let mut avg_y_neg: f32 = 0.0 ;
312- let mut avg_z_neg: f32 = 0.0 ;
313-
314- let mut avg_x_unbiased: f32 = 0.0 ;
315- let mut avg_y_unbiased: f32 = 0.0 ;
316- let mut avg_z_unbiased: f32 = 0.0 ;
317-
318306 // 1. Configure self-test settings
319307 // Control 1: 1600 HZ, High-Performance, 14bit resolution, LowPower1, 50 HZ
320308 let control1: u8 = self
@@ -381,24 +369,13 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
381369 embassy_time:: Timer :: after_millis ( TEST_STAGE_SLEEP_MS as u64 ) . await ;
382370 self . flush_samples ( ) . await ?;
383371
384- let mut sample: usize = 0 ;
385- let mut attempts: usize = 0 ;
386- while sample < TEST_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS {
387- if self . status ( ) . await ?. drdy ( ) {
388- let unbiased_acc: ( f32 , f32 , f32 ) = self . acc_mgs ( ) . await ?;
389- avg_x_unbiased += unbiased_acc. 0 ;
390- avg_y_unbiased += unbiased_acc. 1 ;
391- avg_z_unbiased += unbiased_acc. 2 ;
392- sample += 1 ;
372+ let avg_unbiased: ( f32 , f32 , f32 ) = match self . record_sample_averages ( TEST_SAMPLES , MAX_SAMPLE_ATTEMPTS ) . await ?
373+ {
374+ Some ( val) => val,
375+ None => {
376+ return Ok ( false ) ;
393377 }
394- attempts += 1 ;
395- }
396- if sample == 0 {
397- return Ok ( false ) ;
398- }
399- avg_x_unbiased /= TEST_SAMPLES as f32 ;
400- avg_y_unbiased /= TEST_SAMPLES as f32 ;
401- avg_z_unbiased /= TEST_SAMPLES as f32 ;
378+ } ;
402379
403380 // 3. Enable Self-Test mode, beginning with Positive Sign
404381 let mut _control3 = self
@@ -409,24 +386,12 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
409386 self . flush_samples ( ) . await ?;
410387
411388 // 4. Record positive accelerometer samples
412- sample = 0 ;
413- attempts = 0 ;
414- while sample < TEST_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS {
415- if self . status ( ) . await ?. drdy ( ) {
416- let pos_acc: ( f32 , f32 , f32 ) = self . acc_mgs ( ) . await ?;
417- avg_x_pos += pos_acc. 0 ;
418- avg_y_pos += pos_acc. 1 ;
419- avg_z_pos += pos_acc. 2 ;
420- sample += 1 ;
389+ let avg_pos: ( f32 , f32 , f32 ) = match self . record_sample_averages ( TEST_SAMPLES , MAX_SAMPLE_ATTEMPTS ) . await ? {
390+ Some ( val) => val,
391+ None => {
392+ return Ok ( false ) ;
421393 }
422- attempts += 1 ;
423- }
424- if sample == 0 {
425- return Ok ( false ) ;
426- }
427- avg_x_pos /= TEST_SAMPLES as f32 ;
428- avg_y_pos /= TEST_SAMPLES as f32 ;
429- avg_z_pos /= TEST_SAMPLES as f32 ;
394+ } ;
430395
431396 // 5. Set Negative Sign Self-Test
432397 _control3 = self
@@ -437,24 +402,12 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
437402 self . flush_samples ( ) . await ?;
438403
439404 // 6. Record negative self-test accelerometer samples
440- sample = 0 ;
441- attempts = 0 ;
442- while sample < TEST_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS {
443- if self . status ( ) . await ?. drdy ( ) {
444- let neg_acc: ( f32 , f32 , f32 ) = self . acc_mgs ( ) . await ?;
445- avg_x_neg += neg_acc. 0 ;
446- avg_y_neg += neg_acc. 1 ;
447- avg_z_neg += neg_acc. 2 ;
448- sample += 1 ;
405+ let avg_neg: ( f32 , f32 , f32 ) = match self . record_sample_averages ( TEST_SAMPLES , MAX_SAMPLE_ATTEMPTS ) . await ? {
406+ Some ( val) => val,
407+ None => {
408+ return Ok ( false ) ;
449409 }
450- attempts += 1 ;
451- }
452- if sample == 0 {
453- return Ok ( false ) ;
454- }
455- avg_x_neg /= TEST_SAMPLES as f32 ;
456- avg_y_neg /= TEST_SAMPLES as f32 ;
457- avg_z_neg /= TEST_SAMPLES as f32 ;
410+ } ;
458411
459412 // 7. Reset the changed accelerometer registers to their previous setting
460413 self . write_reg ( Register :: Control1 , control1) . await ?;
@@ -464,12 +417,12 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
464417
465418 // 8. Compare differences to expected values
466419 // Average across test samples
467- let pos_dif_x: f32 = avg_x_pos - avg_x_unbiased ;
468- let pos_dif_y: f32 = avg_y_pos - avg_y_unbiased ;
469- let pos_dif_z: f32 = avg_z_pos - avg_z_unbiased ;
470- let neg_dif_x: f32 = avg_x_unbiased - avg_x_neg ;
471- let neg_dif_y: f32 = avg_y_unbiased - avg_y_neg ;
472- let neg_dif_z: f32 = avg_z_unbiased - avg_z_neg ;
420+ let pos_dif_x: f32 = avg_pos . 0 - avg_unbiased . 0 ;
421+ let pos_dif_y: f32 = avg_pos . 1 - avg_unbiased . 1 ;
422+ let pos_dif_z: f32 = avg_pos . 2 - avg_unbiased . 2 ;
423+ let neg_dif_x: f32 = avg_unbiased . 0 - avg_neg . 0 ;
424+ let neg_dif_y: f32 = avg_unbiased . 1 - avg_neg . 1 ;
425+ let neg_dif_z: f32 = avg_unbiased . 2 - avg_neg . 2 ;
473426
474427 // Ensure all differences line up within defined range
475428 let res: bool = pos_dif_x > LOW_DIFF_MGS
@@ -502,6 +455,34 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
502455 Ok ( samples)
503456 }
504457
458+ /// Record an average acceleration over a certain number of attempts
459+ async fn record_sample_averages (
460+ & mut self ,
461+ test_samples : usize ,
462+ max_attempts : usize ,
463+ ) -> Result < Option < ( f32 , f32 , f32 ) > , I2C :: Error > {
464+ let mut count: usize = 0 ;
465+ let mut attempts: usize = 0 ;
466+ let mut avg: ( f32 , f32 , f32 ) = ( 0.0 , 0.0 , 0.0 ) ;
467+ while count < test_samples && attempts < max_attempts {
468+ if self . status ( ) . await ?. drdy ( ) {
469+ let sample: ( f32 , f32 , f32 ) = self . acc_mgs ( ) . await ?;
470+ avg. 0 += sample. 0 ;
471+ avg. 1 += sample. 1 ;
472+ avg. 2 += sample. 2 ;
473+ count += 1 ;
474+ }
475+ attempts += 1 ;
476+ }
477+ if count == 0 {
478+ return Ok ( None ) ;
479+ }
480+ avg. 0 /= test_samples as f32 ;
481+ avg. 1 /= test_samples as f32 ;
482+ avg. 2 /= test_samples as f32 ;
483+ Ok ( Some ( avg) )
484+ }
485+
505486 // -------------------------- Helper Functions --------------------------
506487
507488 /// Converts i16 temperature representation to degrees Celsius
0 commit comments