+98
-34
Diff
round #1
+20
Cargo.lock
+20
Cargo.lock
···
300
300
"embassy-time",
301
301
"heapless 0.9.2",
302
302
"pollster",
303
+
"rand",
304
+
"wyrand",
303
305
]
304
306
305
307
[[package]]
···
839
841
"proc-macro2",
840
842
]
841
843
844
+
[[package]]
845
+
name = "rand"
846
+
version = "0.9.2"
847
+
source = "registry+https://github.com/rust-lang/crates.io-index"
848
+
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
849
+
dependencies = [
850
+
"rand_core 0.9.5",
851
+
]
852
+
842
853
[[package]]
843
854
name = "rand_core"
844
855
version = "0.6.4"
···
1137
1148
"windows-link",
1138
1149
]
1139
1150
1151
+
[[package]]
1152
+
name = "wyrand"
1153
+
version = "0.3.2"
1154
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1155
+
checksum = "15e0359b0b8d9cdef235a1fd4a8c5d02e4c9204e9fac861c14c229a8e803d1a6"
1156
+
dependencies = [
1157
+
"rand_core 0.9.5",
1158
+
]
1159
+
1140
1160
[[package]]
1141
1161
name = "zerocopy"
1142
1162
version = "0.8.33"
+2
embassy-strike-driver/Cargo.toml
+2
embassy-strike-driver/Cargo.toml
+14
-5
embassy-strike-driver/src/analysis.rs
+14
-5
embassy-strike-driver/src/analysis.rs
···
1
1
use crate::{BLOCK_SIZE, traits::BufferMut};
2
2
3
-
pub fn analyse_buffer_by_stepped_windows<B: BufferMut<usize>>(
3
+
pub fn analyse_buffer_by_stepped_windows<B: BufferMut<(usize, u16)>>(
4
4
threshold: u16,
5
5
buf: &[u16],
6
6
average: u16,
···
13
13
let mut len = 0u32;
14
14
15
15
for (i, window) in buf.windows(CHUNK_SIZE).enumerate().step_by(CHUNK_STEP) {
16
-
let window_total = window.iter().copied().sum::<u16>();
17
-
let window_avg = window_total / CHUNK_SIZE as u16;
18
-
let diff = average.saturating_sub(window_avg);
16
+
let (window_total, window_diff) =
17
+
window
18
+
.iter()
19
+
.copied()
20
+
.fold((0, 0), |(total, diff), sample| {
21
+
(
22
+
total + sample,
23
+
diff + ((average as i16) - sample as i16).unsigned_abs(),
24
+
)
25
+
});
26
+
27
+
let diff = window_diff / CHUNK_SIZE as u16;
19
28
20
29
if diff > threshold {
21
-
peaks.push(i);
30
+
peaks.push((i, diff));
22
31
} else {
23
32
total += window_total as u32;
24
33
len += CHUNK_SIZE as u32;
+62
-29
embassy-strike-driver/src/lib.rs
+62
-29
embassy-strike-driver/src/lib.rs
···
67
67
Detection {
68
68
timestamp: i64,
69
69
samples: &'a [u16],
70
-
peaks: &'a [usize],
70
+
peaks: &'a [(usize, u16)],
71
71
},
72
72
}
73
73
···
112
112
}
113
113
114
114
pub async fn tune(&mut self, samples: &mut [u16]) {
115
-
// info!("Tuning Detector for correct voltage settings");
116
115
let mut duty = 0;
117
116
self.pwm.set_duty(duty);
118
117
Timer::after_secs(2).await;
119
118
let mut act_value = self.adc.sample_average(samples).await;
120
119
121
-
// info!("initial ACT: {}", act_value);
122
-
123
120
while act_value < 1364 {
124
121
duty += 2;
125
122
if duty >= 256 {
···
127
124
self.pwm.set_duty(duty);
128
125
Timer::after_secs(2).await;
129
126
act_value = self.adc.sample_average(samples).await;
130
-
// info!("Restarting tuning");
131
127
continue;
132
128
}
133
129
self.pwm.set_duty(duty);
134
130
Timer::after_millis(250).await;
135
131
act_value = self.adc.sample_average(samples).await;
136
-
// info!("ACT: {}, Duty: {}", act_value, duty);
137
132
}
138
133
self.state.max_duty.set(duty as u8);
139
-
duty = (duty / 3) * 2;
134
+
duty = (duty / 6) * 5;
140
135
self.pwm.set_duty(duty);
141
136
self.state.duty.set(duty as u8);
142
-
// info!("Set detection duty to: {}", duty);
143
137
// Allow voltage level to stabilize after tuning
144
138
Timer::after_secs(2).await;
145
139
let avg = self.adc.sample_average(samples).await;
···
166
160
peaks: &mut B,
167
161
update: F,
168
162
) where
169
-
B: BufferMut<usize>,
163
+
B: BufferMut<(usize, u16)>,
170
164
F: Fn(DetectorUpdate<'_>),
171
165
{
172
166
peaks.clear();
···
201
195
peaks: &'d mut B,
202
196
update: F,
203
197
) where
204
-
B: BufferMut<usize>,
198
+
B: BufferMut<(usize, u16)>,
205
199
F: Fn(DetectorUpdate<'_>),
206
200
{
207
201
loop {
···
256
250
257
251
#[cfg(test)]
258
252
mod tests {
259
-
use core::future::poll_fn;
253
+
use core::{future::poll_fn, ops::RangeBounds, slice::SliceIndex};
260
254
use embassy_time::MockDriver;
255
+
use rand::{Rng, distr::uniform::SampleRange};
261
256
262
257
#[cfg(not(feature = "alloc"))]
263
258
extern crate alloc;
···
310
305
}
311
306
312
307
#[cfg(not(feature = "alloc"))]
313
-
impl BufferMut<usize> for alloc::vec::Vec<usize> {
314
-
fn push(&mut self, value: usize) {
308
+
impl BufferMut<(usize, u16)> for alloc::vec::Vec<(usize, u16)> {
309
+
fn push(&mut self, value: (usize, u16)) {
315
310
self.push(value);
316
311
}
317
312
···
327
322
self.is_empty()
328
323
}
329
324
330
-
fn as_slice(&self) -> &[usize] {
325
+
fn as_slice(&self) -> &[(usize, u16)] {
331
326
self
332
327
}
333
328
}
···
351
346
.await;
352
347
}
353
348
354
-
fn generate_signal(samples: &mut [u16]) {
349
+
fn generate_noisy_signal<
350
+
I: SliceIndex<[u16], Output = [u16]> + RangeBounds<usize>,
351
+
S: RangeBounds<i16> + SampleRange<i16> + Clone,
352
+
>(
353
+
samples: &mut [u16],
354
+
amplitude: S,
355
+
range: I,
356
+
) {
357
+
let mut noise = wyrand::WyRand::new(141);
358
+
359
+
let samples = samples
360
+
.get_mut(range)
361
+
.expect("Range to be sized the same or smaller than the slice");
362
+
363
+
for sample in samples.iter_mut() {
364
+
*sample = ((*sample as i16) - noise.random_range(amplitude.clone())) as u16;
365
+
}
366
+
}
367
+
368
+
fn generate_drop_signal(samples: &mut [u16]) {
355
369
// Example voltage drop signal
356
370
samples[5] -= 60;
357
371
samples[6] -= 55;
···
396
410
tune_detector_manually(&mut detector, &mut buf, driver).await;
397
411
398
412
assert_eq!(detector.state.max_duty.get(), 98);
399
-
assert_eq!(detector.state.duty.get(), 64);
400
-
assert_eq!(detector.adc.sample_average(&mut buf).await, 896);
413
+
assert_eq!(detector.state.duty.get(), 80);
414
+
assert_eq!(detector.adc.sample_average(&mut buf).await, 1120);
401
415
}
402
416
403
417
#[pollster::test]
···
466
480
467
481
let mut peaks = alloc::vec::Vec::with_capacity(512);
468
482
469
-
let update = |_update: DetectorUpdate<'_>| {
483
+
detector.detect_from_sample(0, &samples, &mut peaks, |_| {
470
484
panic!("This update function shouldn't be called");
471
-
};
472
-
473
-
detector.detect_from_sample(0, &samples, &mut peaks, update);
485
+
});
474
486
475
487
assert_eq!(peaks.len(), 0);
476
488
477
-
generate_signal(&mut samples);
489
+
generate_drop_signal(&mut samples);
478
490
479
-
let expected_peaks = alloc::vec![0, 8];
491
+
let expected_peaks = alloc::vec![(0, 25), (8, 21)];
480
492
let called = Cell::new(false);
481
493
482
-
let update = |update: DetectorUpdate<'_>| {
494
+
detector.detect_from_sample(0, &samples, &mut peaks, |update: DetectorUpdate<'_>| {
483
495
called.set(true);
484
496
assert_eq!(
485
497
update,
···
489
501
peaks: expected_peaks.as_slice()
490
502
}
491
503
)
492
-
};
493
-
494
-
detector.detect_from_sample(0, &samples, &mut peaks, update);
504
+
});
495
505
496
506
assert_eq!(peaks.len(), 2);
497
507
assert!(called.get());
508
+
509
+
called.set(false);
510
+
511
+
let mut samples = alloc::vec![0; BLOCK_SIZE];
512
+
let expected_peaks = alloc::vec![(16, 15), (24, 19), (32, 18)];
513
+
514
+
detector.adc.sample(&mut samples).await;
515
+
generate_noisy_signal(&mut samples, -40..=40, 20..55);
516
+
517
+
detector.detect_from_sample(0, &samples, &mut peaks, |update| {
518
+
called.set(true);
519
+
assert_eq!(
520
+
update,
521
+
DetectorUpdate::Detection {
522
+
timestamp: 0,
523
+
samples: &samples,
524
+
peaks: expected_peaks.as_slice()
525
+
}
526
+
)
527
+
});
528
+
529
+
assert_eq!(peaks.len(), 3);
530
+
assert!(called.get());
498
531
}
499
532
500
533
#[pollster::test]
···
512
545
detector.state.avg.set(896);
513
546
514
547
let mut samples = alloc::vec![0; BLOCK_SIZE];
515
-
let mut peaks: alloc::vec::Vec<usize> = alloc::vec::Vec::with_capacity(BLOCK_SIZE);
548
+
let mut peaks = alloc::vec::Vec::with_capacity(BLOCK_SIZE);
516
549
517
550
// Require bigger size blips.
518
551
detector.config.blip_size.set(3);
519
552
520
553
detector.adc.sample(&mut samples).await;
521
-
generate_signal(&mut samples);
554
+
generate_drop_signal(&mut samples);
522
555
523
556
detector.detect_from_sample(0, &samples, &mut peaks, |_update| {
524
557
panic!("Update shouldn't be called");
History
3 rounds
0 comments
1 commit
expand
collapse
refactor: Signal detection algorithm tweaks
1/1 success
expand
collapse
expand 0 comments
pull request successfully merged
1 commit
expand
collapse
refactor: Signal detection algorithm tweaks
1/1 success
expand
collapse
expand 0 comments
1 commit
expand
collapse
refactor: Signal detection algorithm tweaks