sim-fft
sim-fft is an easy to use Fast Fourier Transform library primarily meant for embedded systems.
Features
The library offers the following features:
- Easy to use
- Suitable for
no_std
environments - fft: Fast Fourier Transform Algorithm
- ifft: Inverse Fast Fourier Transform Algorithm
- Peak Value
- magnitude and frequency calculation
- window function:
- hamming
- hann
- blackman
- kaiser
Examples
for STM32F103:
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt::info;
use defmt_rtt as _;
use panic_semihosting as _;
use sim_fft::{Complex, SimpleFft};
#[entry]
fn main() -> ! {
//sample freq 1Mhz
let freq = 1_000_000;
//test freg 93KHZ
let mut buf = [
4091, 4089, 4091, 4093, 4092, 4091, 2, 1, 1, 1, 1, 1, 4092, 4091, 4091, 4092, 4093, 2, 2,
1, 1, 1, 4090, 4091, 4092, 4093, 4093, 4092, 2, 1, 1, 2, 1, 4092, 4093, 4093, 4093, 4091,
2, 1, 2, 1, 2, 2, 4093, 4093, 4091, 4092, 4093, 2, 2, 1, 2, 1, 1, 4093, 4092, 4092, 4091,
4092, 2, 2, 1, 1, 2, 4092, 4092, 4091, 4092, 4092, 4091, 2, 1, 2, 1, 2, 4091, 4094, 4093,
4091, 4093, 2, 2, 1, 1, 1, 1, 4092, 4091, 4093, 4093, 4092, 2, 1, 1, 2, 1, 2, 4092, 4092,
4093, 4094, 4093, 2, 2, 1, 2, 1, 4092, 4091, 4092, 4092, 4091, 4092, 2, 2, 1, 1, 1, 4092,
4092, 4089, 4090, 4093, 3, 2, 1, 1,
];
cal_hz(&mut buf, freq as f64, freq as f64);
//221KHZ
let mut buf = [
4089, 4089, 1, 0, 4089, 4091, 4092, 0, 0, 4092, 4091, 1, 0, 4089, 4090, 4092, 2, 0, 4092,
4090, 1, 0, 4089, 4091, 4092, 1, 0, 4090, 4090, 1, 0, 4089, 4090, 4090, 1, 0, 4092, 4090,
1, 1, 4089, 4090, 4092, 1, 1, 4092, 4092, 1, 0, 4045, 4090, 4092, 1, 0, 4091, 4090, 1, 0,
0, 4090, 4092, 1, 0, 4091, 4091, 0, 0, 0, 4090, 4091, 1, 0, 4090, 4089, 1, 0, 0, 4090,
4091, 1, 0, 4092, 4091, 1, 0, 0, 4090, 4092, 1, 0, 4092, 4091, 1, 1, 0, 4090, 4090, 1, 0,
4093, 4091, 1, 0, 0, 4091, 4092, 1, 1, 4092, 4091, 0, 1, 0, 4090, 4092, 1, 0, 4092, 4090,
1078, 0, 0, 4092, 4092, 1, 0, 4092, 4091,
];
cal_hz(&mut buf, freq as f64, freq as f64);
//250Khz
let mut buf = [
1, 1, 1, 4092, 4092, 1, 0, 4089, 4089, 1, 0, 4089, 4092, 1, 0, 4092, 4092, 1, 0, 4092,
4089, 1, 0, 4091, 4092, 1, 0, 4092, 4092, 1, 0, 4090, 4091, 1, 0, 4089, 4091, 1, 1, 4092,
4092, 1, 0, 4092, 4089, 1, 0, 4089, 4092, 1, 0, 4092, 4092, 1, 0, 4091, 4091, 0, 0, 4090,
4092, 1, 0, 4092, 4092, 1, 0, 4092, 4091, 1, 1, 4089, 4092, 1, 1, 4092, 4090, 1, 0, 4092,
4091, 1, 0, 4089, 4092, 1, 0, 4092, 4092, 1, 0, 4091, 4089, 1, 0, 4091, 4092, 1, 1, 4090,
4089, 1, 0, 4092, 4091, 0, 0, 4089, 4092, 1, 1, 4092, 4092, 1, 0, 4092, 4089, 1, 0, 4089,
4092, 1, 0, 4090, 4090, 1, 0, 4092,
];
cal_hz(&mut buf, freq as f64, freq as f64);
//125khz
let mut buf = [
1, 4089, 4089, 0, 0, 0, 0, 4091, 4089, 4092, 4092, 1, 0, 0, 0, 4092, 4092, 4089, 4092, 1,
1, 0, 0, 4091, 4092, 4091, 4089, 1, 0, 1, 0, 4092, 4091, 4092, 4092, 1, 0, 0, 1, 4092,
4091, 4091, 4092, 1, 0, 0, 0, 4089, 4092, 4092, 4091, 1, 1, 0, 0, 4091, 4089, 4092, 4090,
1, 0, 0, 0, 4090, 4091, 4091, 4092, 1, 0, 0, 0, 4089, 4092, 4092, 4089, 1, 0, 0, 0, 4091,
4089, 4090, 4089, 1, 0, 0, 0, 4092, 4092, 4089, 4092, 1, 1, 0, 0, 4091, 4092, 4092, 4089,
1, 0, 1, 0, 4090, 4090, 4090, 4092, 1, 0, 0, 1, 4092, 4092, 4091, 4092, 1, 0, 0, 0, 4089,
4092, 4092, 4091, 1, 1, 1, 0, 4091,
];
cal_hz(&mut buf, freq as f64, freq as f64);
panic!("exit");
loop {}
}
const ADC_BUFFER_SIZE: usize = 128;
fn cal_hz(buf: &mut [u16], clk1: f64, clk2: f64) {
//size=2^n
let mut sin_table = [0.0; ADC_BUFFER_SIZE / 4 + 1];
let mut data = [Complex::new(0.0, 0.0); ADC_BUFFER_SIZE];
let mut fft = SimpleFft::new(&mut data, &mut sin_table, clk2 as f64);
fft.init_sin_table();
fft.load_data_u16(&buf);
fft.apply_kaiser_window(5.);
fft.fft();
let (freq1, _) = fft.dominant_frequency();
let (freq2, mag) = fft.dominant_freq(clk1);
let freq = (freq1 + freq2) / 2000.;
info!("freg:{}+{}= {} KHz, mag: {}", freq1, freq2, freq, mag);
// // print top 10 freq
// for i in 1..=10 {
// info!("f={}Hz, mag={}", fft.frequency(i), fft.magnitude(i));
// }
}