switch to 16-bit dumps & add a script for dumping cleaned waveforms
I can see very clear signal when I: - tape only the contacts of the sensor to the table, and - bend the free end into the air, and release (it snaps down)
This commit is contained in:
70
scripts/itm-to-pcm.py
Executable file
70
scripts/itm-to-pcm.py
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
'''
|
||||||
|
Convert itm.txt dumps to pcm (wave) files
|
||||||
|
|
||||||
|
usage: itmdump -f /tmp/itm.txt > dump.txt
|
||||||
|
itm-to-pcm.py dump.txt dump.wav
|
||||||
|
'''
|
||||||
|
|
||||||
|
import wave
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def read_itm(file_in):
|
||||||
|
f = open(file_in, 'rb')
|
||||||
|
while True:
|
||||||
|
samples = f.read(2)
|
||||||
|
if not samples: break
|
||||||
|
#if len(set(samples)) != 1: continue # corrupted
|
||||||
|
#yield samples[0]
|
||||||
|
yield samples[0] + 0x100*samples[1]
|
||||||
|
#for line in f:
|
||||||
|
# try:
|
||||||
|
# if line.startswith(b'ADC:'):
|
||||||
|
# sample = int(line[len('ADC: '):].strip(), 16)
|
||||||
|
# if sample < 0x1000: yield sample
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
def frames_from_samples(itm):
|
||||||
|
b = bytearray()
|
||||||
|
for sample in itm:
|
||||||
|
sample = (sample + 0x10000) % 0x10000 # counteract Python's signed mod badness
|
||||||
|
lsb0 = sample % 0x100
|
||||||
|
lsb1 = (sample // 0x100) % 0x100
|
||||||
|
b.append(lsb0)
|
||||||
|
b.append(lsb1)
|
||||||
|
|
||||||
|
return b
|
||||||
|
|
||||||
|
def clean_frames(frames):
|
||||||
|
# Run a median filter over the frames to clean outliers:
|
||||||
|
post_med = [0]*len(frames)
|
||||||
|
for i, _ in enumerate(frames):
|
||||||
|
left = max(0, i-2)
|
||||||
|
right = min(len(frames), i+3)
|
||||||
|
post_med[i] = median(frames[left:right])
|
||||||
|
# Remove DC component
|
||||||
|
dc = sum(post_med) / len(post_med)
|
||||||
|
post_dc = [f - dc for f in post_med]
|
||||||
|
# Amplify to [-0x7fff, 0x7fff]
|
||||||
|
prev_max = max(abs(f) for f in post_dc)
|
||||||
|
amp_factor = 0x7fff / prev_max
|
||||||
|
post_amp = [f*amp_factor for f in post_dc]
|
||||||
|
# Round to int
|
||||||
|
return [int(round(f)) for f in post_amp]
|
||||||
|
|
||||||
|
def median(samples):
|
||||||
|
x = list(sorted(samples))
|
||||||
|
return x[len(x) // 2]
|
||||||
|
|
||||||
|
def main():
|
||||||
|
_self, file_in, file_out = sys.argv
|
||||||
|
itm = clean_frames(list(read_itm(file_in)))
|
||||||
|
wave_out = wave.open(file_out, 'wb')
|
||||||
|
wave_out.setnchannels(1)
|
||||||
|
wave_out.setsampwidth(2)
|
||||||
|
wave_out.setframerate(1000)
|
||||||
|
wave_out.writeframes(frames_from_samples(itm))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
94
src/main.rs
94
src/main.rs
@@ -232,15 +232,15 @@ fn main() -> ! {
|
|||||||
// 0b110 = 181.5 clocks
|
// 0b110 = 181.5 clocks
|
||||||
// 0b111 = 601.5 clocks
|
// 0b111 = 601.5 clocks
|
||||||
per.adc1.smpr1.modify(|_, w| {
|
per.adc1.smpr1.modify(|_, w| {
|
||||||
unsafe { w.smp1().bits(0b101) };
|
unsafe { w.smp1().bits(0b010) };
|
||||||
unsafe { w.smp2().bits(0b101) };
|
unsafe { w.smp2().bits(0b010) };
|
||||||
unsafe { w.smp3().bits(0b101) };
|
unsafe { w.smp3().bits(0b010) };
|
||||||
unsafe { w.smp4().bits(0b101) };
|
unsafe { w.smp4().bits(0b010) };
|
||||||
unsafe { w.smp5().bits(0b101) };
|
unsafe { w.smp5().bits(0b010) };
|
||||||
unsafe { w.smp6().bits(0b101) };
|
unsafe { w.smp6().bits(0b010) };
|
||||||
unsafe { w.smp7().bits(0b101) };
|
unsafe { w.smp7().bits(0b010) };
|
||||||
unsafe { w.smp8().bits(0b101) };
|
unsafe { w.smp8().bits(0b010) };
|
||||||
unsafe { w.smp9().bits(0b101) };
|
unsafe { w.smp9().bits(0b010) };
|
||||||
w
|
w
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -262,48 +262,44 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// We have 48 KBytes of ram
|
// We have 48 KBytes of ram
|
||||||
// But sizes >= 4096 seem to cause faults :s
|
// But sizes >= 4096 seem to cause faults :s
|
||||||
let mut buffer = [0u8; 2048];
|
// let mut buffer = [0u8; 1024];
|
||||||
loop {
|
// let mut background_level = 0; // 0 .. 65536
|
||||||
for sample in buffer.iter_mut() {
|
// loop {
|
||||||
*sample = (per.adc1.dr.read().bits() >> 4) as u8;
|
// for sample in &mut buffer[..256] {
|
||||||
}
|
// *sample = (per.adc1.dr.read().bits() >> 4) as u8;
|
||||||
itm::write_all(&mut per.itm.stim[0], &buffer);
|
// }
|
||||||
//let avg_sample = (buffer.iter().map(|x| *x as u32).sum::<u32>() / buffer.len() as u32) as u16;
|
// let bg_this_iter = buffer[..256].iter().map(|&x| x as u32).sum::<u32>();
|
||||||
//if buffer.iter().any(|&s| s as u32 * 4 > avg_sample as u32 * 5 || s as u32 * 5 < avg_sample as u32 * 4) {
|
// if background_level == 0 {
|
||||||
// // Dump the buffer:
|
// background_level = bg_this_iter;
|
||||||
// itm::write_all(&mut per.itm.stim[0], &buffer);
|
// }
|
||||||
// //for sample in buffer.iter() {
|
// let thresh = background_level / 230;
|
||||||
// ////for i in 0..2048 {
|
// if buffer[..256].iter().any(|&s| s as u32 > thresh) {
|
||||||
// // //let data = (buffer[i] >> 4) as u32;
|
// for sample in &mut buffer[256..] {
|
||||||
// // let data = (sample >> 4) as u8;
|
// *sample = (per.adc1.dr.read().bits() >> 4) as u8;
|
||||||
// // while !per.itm.stim[0].is_fifo_ready() {}
|
// }
|
||||||
// // per.itm.stim[0].write_u8(data);
|
// itm::write_all(&mut per.itm.stim[0], &buffer);
|
||||||
// // //per.itm.stim[0].write_u32(data | (data << 8) | (data << 16) | (data << 24));
|
// //itm::write_all(&mut per.itm.stim[0], &buffer[..1024]);
|
||||||
// // //delay(10000);
|
// //delay(8000000);
|
||||||
// //}
|
// //itm::write_all(&mut per.itm.stim[0], &buffer[1024..2048]);
|
||||||
//}
|
// //delay(8000000);
|
||||||
}
|
// //itm::write_all(&mut per.itm.stim[0], &buffer[2048..3072]);
|
||||||
|
// //delay(8000000);
|
||||||
|
// //itm::write_all(&mut per.itm.stim[0], &buffer[3072..]);
|
||||||
|
// //delay(8000000);
|
||||||
|
// }
|
||||||
|
// background_level = (background_level*7 + bg_this_iter) / 8; // LPF
|
||||||
|
// }
|
||||||
|
|
||||||
|
// continuous dump mode (8-bit):
|
||||||
|
// loop {
|
||||||
|
// let sample = (per.adc1.dr.read().bits() >> 4) as u8;
|
||||||
|
// itm::write_all(&mut per.itm.stim[0], &[sample]);
|
||||||
|
// }
|
||||||
loop {
|
loop {
|
||||||
iprintln!(&mut per.itm.stim[0], "hello!");
|
let sample = (per.adc1.dr.read().bits() << 4) as u16;
|
||||||
}
|
let high = (sample >> 8) as u8;
|
||||||
|
let low = (sample & 0xff) as u8;
|
||||||
loop {
|
itm::write_all(&mut per.itm.stim[0], &[low, high]);
|
||||||
//let push_button = per.gpioa.idr.read().idr0().bit();
|
|
||||||
//let push_button = per.gpiod.idr.read().idr0().bit();
|
|
||||||
//per.gpioe.odr.modify(|_, w| {
|
|
||||||
// w.odr8().bit(push_button)
|
|
||||||
//});
|
|
||||||
//iprintln!(&mut per.itm.stim[0], "ADC: {:x}", per.adc1.dr.read().bits());
|
|
||||||
//per.itm.stim[0].write_u32(per.adc1.dr.read().bits());
|
|
||||||
while !per.itm.stim[0].is_fifo_ready() {}
|
|
||||||
let adc = per.adc1.dr.read().bits();
|
|
||||||
//let data = adc as u16;
|
|
||||||
//per.itm.stim[0].write_u16(data);
|
|
||||||
let data = (adc >> 4) as u32;
|
|
||||||
//per.itm.stim[0].write_u8(data);
|
|
||||||
per.itm.stim[0].write_u32(data | (data << 8) | (data << 16) | (data << 24));
|
|
||||||
delay(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user