hz
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# ESP-DSP Examples
|
||||
|
||||
This directory contains a range of examples for ESP-DSP library.
|
||||
|
||||
These examples are intended to demonstrate part of ESP-DSP functionality (e.g. initialization, execution) and to provide code that you can copy and adapt into your own projects.
|
||||
|
||||
See the [README.md](../README.md) file in the upper level directory for more information about ESP-DSP.
|
||||
|
||||
# Example Layout
|
||||
|
||||
The examples are grouped into subdirectories by category. Each category directory contains one or more example projects:
|
||||
|
||||
* [Dot Product Calculation](./dotprod/README.md) Example
|
||||
* [Basic Math Operations](./basic_math/README.md) Example
|
||||
* [FFT](./fft/README.md) Example
|
||||
* [Matrix](./matrix/README.md) Example
|
||||
* [FFT Window](./fft_window/README.md) Example
|
||||
* [IIR Filter](./iir/README.md) Example
|
||||
* [Kalman Filter](./kalman/README.md) Example
|
||||
* [FIR Filter](.fir/README.md) Example
|
||||
* [2D Convolution](./conv2d//README.md) Example
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(basic_math)
|
||||
@@ -0,0 +1,75 @@
|
||||
# Basic Math Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use basic math functions from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the library
|
||||
2. Initialize input signals with 1024 samples
|
||||
3. Apply window to input signal by standard C loop.
|
||||
4. Calculate FFT for 1024 complex samples and show the result
|
||||
5. Show results on the plots
|
||||
6. Apply window to input signal by basic math functions dsps_mul_f32 and dsps_mulc_f32.
|
||||
7. Calculate FFT for 1024 complex samples
|
||||
8. Show results on the plots
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```bash
|
||||
I (132) main: *** Start Example. ***
|
||||
I (132) main: *** Multiply tone signal with Hann window by standard C loop. ***
|
||||
I (152) view: Data min[432] = -173.749878, Data max[205] = 23.849705
|
||||
________________________________________________________________
|
||||
0 | |
|
||||
1 | |
|
||||
2 | |
|
||||
3 || |
|
||||
4 | | |
|
||||
5 || | |
|
||||
6 ||| || |
|
||||
7 ||||| |||| |
|
||||
8||||||||||||||| |||||| |
|
||||
9 |||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (162) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
I (162) main: *** Multiply tone signal with Hann window by esp-dsp basic math functions. ***
|
||||
I (162) view: Data min[432] = -173.749878, Data max[205] = 23.849705
|
||||
________________________________________________________________
|
||||
0 | |
|
||||
1 | |
|
||||
2 | |
|
||||
3 || |
|
||||
4 | | |
|
||||
5 || | |
|
||||
6 ||| || |
|
||||
7 ||||| |||| |
|
||||
8||||||||||||||| |||||| |
|
||||
9 |||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (172) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
I (172) main: *** End Example. ***
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_math_main.c")
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use FFT from esp-dsp library
|
||||
|
||||
#define N_SAMPLES 1024
|
||||
int N = N_SAMPLES;
|
||||
// Input test array
|
||||
__attribute__((aligned(16)))
|
||||
float x1[N_SAMPLES];
|
||||
// Window coefficients
|
||||
__attribute__((aligned(16)))
|
||||
float wind[N_SAMPLES];
|
||||
// working complex array
|
||||
__attribute__((aligned(16)))
|
||||
float y_cf[N_SAMPLES * 2];
|
||||
// Pointers to result arrays
|
||||
float *y1_cf = &y_cf[0];
|
||||
|
||||
static void process_and_show(float *data, int length)
|
||||
{
|
||||
dsps_fft2r_fc32(data, length);
|
||||
// Bit reverse
|
||||
dsps_bit_rev_fc32(data, length);
|
||||
// Convert one complex vector to two complex vectors
|
||||
dsps_cplx2reC_fc32(data, length);
|
||||
|
||||
for (int i = 0 ; i < length / 2 ; i++) {
|
||||
data[i] = 10 * log10f((data[i * 2 + 0] * data[i * 2 + 0] + data[i * 2 + 1] * data[i * 2 + 1]) / N);
|
||||
}
|
||||
|
||||
// Show power spectrum in 64x10 window from -100 to 0 dB from 0..N/4 samples
|
||||
dsps_view(data, length / 2, 64, 10, -120, 40, '|');
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "*** Start Example. ***");
|
||||
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate Hann window
|
||||
dsps_wind_hann_f32(wind, N);
|
||||
|
||||
ESP_LOGI(TAG, "*** Multiply tone signal with Hann window by standard C loop. ***");
|
||||
// Generate input signal
|
||||
dsps_tone_gen_f32(x1, N, 1., 0.2, 0);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = x1[i] * wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGI(TAG, "*** Multiply tone signal with Hann window by esp-dsp basic math functions. ***");
|
||||
// Convert two input vectors to one complex vector with basic functions
|
||||
dsps_mul_f32(x1, wind, y_cf, N, 1, 1, 2); // Multiply input array with window and store as real part
|
||||
dsps_mulc_f32(&y_cf[1], &y_cf[1], N, 0, 2, 2); // Clear imaginary part of the complex signal
|
||||
process_and_show(y_cf, N);
|
||||
ESP_LOGI(TAG, "*** End Example. ***");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(conv2d)
|
||||
@@ -0,0 +1,57 @@
|
||||
# 2D convolution Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use 2D convolution dspi_conv_f32 from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the input arrays
|
||||
2. Calculate 2D convolution of two images
|
||||
|
||||
The example reproduce the Matlab code:
|
||||
|
||||
```
|
||||
A = ones(8);
|
||||
B = ones(4);
|
||||
Csame = conv2(A,B, "same")
|
||||
|
||||
```
|
||||
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (305) main: Start Example.
|
||||
I (305) main: 2D Convolution result.
|
||||
[ 0 .. 8, 0]: 9, 12, 12, 12, 12, 12, 9, 6,
|
||||
[ 0 .. 8, 1]: 12, 16, 16, 16, 16, 16, 12, 8,
|
||||
[ 0 .. 8, 2]: 12, 16, 16, 16, 16, 16, 12, 8,
|
||||
[ 0 .. 8, 3]: 12, 16, 16, 16, 16, 16, 12, 8,
|
||||
[ 0 .. 8, 4]: 12, 16, 16, 16, 16, 16, 12, 8,
|
||||
[ 0 .. 8, 5]: 12, 16, 16, 16, 16, 16, 12, 8,
|
||||
[ 0 .. 8, 6]: 9, 12, 12, 12, 12, 12, 9, 6,
|
||||
[ 0 .. 8, 7]: 6, 8, 8, 8, 8, 8, 6, 4,
|
||||
```
|
||||
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "conv2d_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "esp_dsp.h"
|
||||
#include "dsp_tests.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
|
||||
int max_N = 100;
|
||||
|
||||
float *data1 = (float *)memalign(16, max_N * sizeof(float));
|
||||
float *data2 = (float *)memalign(16, max_N * sizeof(float));
|
||||
float *data3 = (float *)memalign(16, max_N * sizeof(float));
|
||||
|
||||
image2d_t image1 = {data1, 1, 1, 8, 8, 8, 8}; // Image 8x8
|
||||
image2d_t image2 = {data2, 1, 1, 4, 4, 4, 4}; // Image 4x4
|
||||
image2d_t image3 = {data3, 1, 1, 10, 10, 0, 0}; // Image 10x10
|
||||
|
||||
for (int i = 0 ; i < max_N ; i++) {
|
||||
data1[i] = 0;
|
||||
data2[i] = 0;
|
||||
data3[i] = 0;
|
||||
}
|
||||
|
||||
for (int y = 0 ; y < image1.stride_y / image1.step_y ; y++) {
|
||||
for (int x = 0 ; x < image1.stride_x / image1.step_x ; x++) {
|
||||
data1[y * image1.stride_x * image1.step_y + x * image1.step_x] = 1;
|
||||
}
|
||||
}
|
||||
for (int y = 0 ; y < image2.stride_y / image2.step_y ; y++) {
|
||||
for (int x = 0 ; x < image2.stride_x / image2.step_x ; x++) {
|
||||
data2[y * image2.stride_x * image2.step_y + x * image2.step_x] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
dspi_conv_f32(&image1, &image2, &image3);
|
||||
|
||||
ESP_LOGI(TAG, "2D Convolution result.");
|
||||
|
||||
for (int y = 0 ; y < image3.size_y; y++) {
|
||||
printf("[%2i .. %2i, %2i]: ", 0, image3.size_x, y);
|
||||
for (int x = 0 ; x < image3.size_x; x++) {
|
||||
printf("%2.0f, ", data3[y * image3.stride_x * image3.step_y + x * image3.step_x]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
free(data1);
|
||||
free(data2);
|
||||
free(data3);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1,4 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(dotprod)
|
||||
@@ -0,0 +1,42 @@
|
||||
# Dot Product Calculation Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use dotprod dsps_dotprod_f32 from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the input arrays
|
||||
2. Calculate dot product of two arrays
|
||||
3. Compare results and calculate execution time in cycles.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (55) main: Start Example.
|
||||
I (55) main: The sum of 101 elements from 0..100 = 5050.000000
|
||||
I (55) main: Operation for 101 samples took 1381 cycles
|
||||
I (65) main: End Example.
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_dotproduct_main.c")
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use dsps_dotprod_f32 and dsps_dotprode_f32 functions
|
||||
|
||||
#define N_SAMPLES 256
|
||||
int N = N_SAMPLES;
|
||||
__attribute__((aligned(16)))
|
||||
float input1[N_SAMPLES];
|
||||
__attribute__((aligned(16)))
|
||||
float input2[N_SAMPLES];
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
|
||||
// The example will calculate n!
|
||||
//Initialize an input arrays
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
input1[i] = 1;
|
||||
input2[i] = i;
|
||||
}
|
||||
float result1 = 0;
|
||||
unsigned int start_b = dsp_get_cpu_cycle_count();
|
||||
ret = dsps_dotprod_f32(input1, input2, &result1, 101);
|
||||
unsigned int end_b = dsp_get_cpu_cycle_count();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Operation error = %i", ret);
|
||||
}
|
||||
ESP_LOGI(TAG, "The sum of 101 elements from 0..100 = %f", result1);
|
||||
ESP_LOGI(TAG, "Operation for 101 samples take %i cycles", end_b - start_b);
|
||||
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(fft2r)
|
||||
@@ -0,0 +1,91 @@
|
||||
# FFT Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use FFT functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the library
|
||||
2. Initialize input signals with 1024 samples: one 0 dB, second with -20 dB
|
||||
3. Combine two signals as one complex input signal and apply window to input signals paar.
|
||||
4. Calculate FFT for 1024 complex samples
|
||||
5. Apply bit reverse operation for output complex vector
|
||||
6. Split one complex FFT output spectrum to two real signal spectrums
|
||||
7. Show results on the plots
|
||||
8. Show execution time of FFT
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (59) main: Start Example.
|
||||
W (89) main: Signal x1
|
||||
I (89) view: Data min[495] = -162.760925, Data max[164] = 23.938747
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 | |
|
||||
2 | |
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | | |
|
||||
7 | | |
|
||||
8 || || |
|
||||
9|||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (159) view: Plot: Length=512, min=-60.000000, max=40.000000
|
||||
W (169) main: Signal x2
|
||||
I (169) view: Data min[502] = -164.545135, Data max[205] = 3.857752
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 |
|
||||
2 |
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | |
|
||||
7 || |
|
||||
8 | | |
|
||||
9|||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (249) view: Plot: Length=512, min=-60.000000, max=40.000000
|
||||
W (249) main: Signals x1 and x2 on one plot
|
||||
I (259) view: Data min[505] = -159.215271, Data max[164] = 23.938747
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 | |
|
||||
2 | |
|
||||
3 | | |
|
||||
4 | | |
|
||||
5 | | |
|
||||
6 | | | |
|
||||
7 | | || |
|
||||
8 || || | | |
|
||||
9|||||||||||||||||| | ||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (339) view: Plot: Length=512, min=-60.000000, max=40.000000
|
||||
I (339) main: FFT for 1024 complex points take 140472 cycles
|
||||
I (349) main: End Example.
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_fft_main.c")
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use FFT from esp-dsp library
|
||||
|
||||
#define N_SAMPLES 1024
|
||||
int N = N_SAMPLES;
|
||||
// Input test array
|
||||
__attribute__((aligned(16)))
|
||||
float x1[N_SAMPLES];
|
||||
__attribute__((aligned(16)))
|
||||
float x2[N_SAMPLES];
|
||||
// Window coefficients
|
||||
__attribute__((aligned(16)))
|
||||
float wind[N_SAMPLES];
|
||||
// working complex array
|
||||
__attribute__((aligned(16)))
|
||||
float y_cf[N_SAMPLES * 2];
|
||||
// Pointers to result arrays
|
||||
float *y1_cf = &y_cf[0];
|
||||
float *y2_cf = &y_cf[N_SAMPLES];
|
||||
|
||||
// Sum of y1 and y2
|
||||
__attribute__((aligned(16)))
|
||||
float sum_y[N_SAMPLES / 2];
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate hann window
|
||||
dsps_wind_hann_f32(wind, N);
|
||||
// Generate input signal for x1 A=1 , F=0.1
|
||||
dsps_tone_gen_f32(x1, N, 1.0, 0.16, 0);
|
||||
// Generate input signal for x2 A=0.1,F=0.2
|
||||
dsps_tone_gen_f32(x2, N, 0.1, 0.2, 0);
|
||||
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = x1[i] * wind[i];
|
||||
y_cf[i * 2 + 1] = x2[i] * wind[i];
|
||||
}
|
||||
// FFT
|
||||
unsigned int start_b = dsp_get_cpu_cycle_count();
|
||||
dsps_fft2r_fc32(y_cf, N);
|
||||
unsigned int end_b = dsp_get_cpu_cycle_count();
|
||||
// Bit reverse
|
||||
dsps_bit_rev_fc32(y_cf, N);
|
||||
// Convert one complex vector to two complex vectors
|
||||
dsps_cplx2reC_fc32(y_cf, N);
|
||||
|
||||
for (int i = 0 ; i < N / 2 ; i++) {
|
||||
y1_cf[i] = 10 * log10f((y1_cf[i * 2 + 0] * y1_cf[i * 2 + 0] + y1_cf[i * 2 + 1] * y1_cf[i * 2 + 1]) / N);
|
||||
y2_cf[i] = 10 * log10f((y2_cf[i * 2 + 0] * y2_cf[i * 2 + 0] + y2_cf[i * 2 + 1] * y2_cf[i * 2 + 1]) / N);
|
||||
// Simple way to show two power spectrums as one plot
|
||||
sum_y[i] = fmax(y1_cf[i], y2_cf[i]);
|
||||
}
|
||||
|
||||
// Show power spectrum in 64x10 window from -100 to 0 dB from 0..N/4 samples
|
||||
ESP_LOGW(TAG, "Signal x1");
|
||||
dsps_view(y1_cf, N / 2, 64, 10, -60, 40, '|');
|
||||
ESP_LOGW(TAG, "Signal x2");
|
||||
dsps_view(y2_cf, N / 2, 64, 10, -60, 40, '|');
|
||||
ESP_LOGW(TAG, "Signals x1 and x2 on one plot");
|
||||
dsps_view(sum_y, N / 2, 64, 10, -60, 40, '|');
|
||||
ESP_LOGI(TAG, "FFT for %i complex points take %i cycles", N, end_b - start_b);
|
||||
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(fft4real)
|
||||
@@ -0,0 +1,91 @@
|
||||
# FFT 4 Real Input Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use FFT functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the library
|
||||
2. Initialize input signals with 1024 samples: one 0 dB, second with -20 dB
|
||||
3. Calculate FFT Radix-2 for 1024 complex samples
|
||||
4. Calculate FFT Radix-4 for 1024 complex samples
|
||||
5. Apply bit reverse operation for output complex vectors
|
||||
6. Show results on the plots
|
||||
7. Show execution time of FFTs
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (344) main: Start Example.
|
||||
W (424) main: Signal x1
|
||||
I (424) view: Data min[673] = -103.113297, Data max[328] = 20.490950
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 | |
|
||||
2 | |
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | |
|
||||
7 | | |
|
||||
8 | | |
|
||||
9||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (494) view: Plot: Length=1024, min=-60.000000, max=40.000000
|
||||
W (504) main: Signal x2
|
||||
I (504) view: Data min[582] = -103.113297, Data max[328] = 20.490950
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 | |
|
||||
2 | |
|
||||
3 | |
|
||||
4 | |
|
||||
5 | |
|
||||
6 | |
|
||||
7 | | |
|
||||
8 | | |
|
||||
9||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (584) view: Plot: Length=1024, min=-60.000000, max=40.000000
|
||||
W (593) main: Difference between signals x1 and x2 on one plot
|
||||
I (594) view: Data min[0] = 0.000000, Data max[392] = 0.313019
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 |
|
||||
2 |
|
||||
3 |
|
||||
4 |
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8----------------------------------------------------------------|
|
||||
9 |
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (674) view: Plot: Length=1024, min=0.000000, max=40.000000
|
||||
I (674) main: FFT Radix 2 for 1024 complex points take 168652 cycles
|
||||
I (684) main: FFT Radix 4 for 1024 complex points take 104665 cycles
|
||||
I (694) main: End Example.
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_fft4real_main.c")
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use FFT from esp-dsp library
|
||||
|
||||
#define N_SAMPLES 2048 // Amount of real input samples
|
||||
int N = N_SAMPLES;
|
||||
// Input test array
|
||||
__attribute__((aligned(16)))
|
||||
float x1[N_SAMPLES];
|
||||
__attribute__((aligned(16)))
|
||||
float x2[N_SAMPLES];
|
||||
// Window coefficients
|
||||
__attribute__((aligned(16)))
|
||||
float wind[N_SAMPLES];
|
||||
// Pointers to result arrays
|
||||
float *y1_cf = &x1[0];
|
||||
float *y2_cf = &x2[0];
|
||||
|
||||
// diff of y1 and y2
|
||||
__attribute__((aligned(16)))
|
||||
float diff_y[N_SAMPLES / 2];
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
ret = dsps_fft2r_init_fc32(NULL, N >> 1);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT2R. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = dsps_fft4r_init_fc32(NULL, N >> 1);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT4R. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate hann window
|
||||
dsps_wind_hann_f32(wind, N);
|
||||
// Generate input signal for x1 A=1 , F=0.1
|
||||
dsps_tone_gen_f32(x1, N, 1.0, 0.16, 0);
|
||||
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
x1[i] = x1[i] * wind[i];
|
||||
x2[i] = x1[i];
|
||||
}
|
||||
// FFT Radix-2
|
||||
unsigned int start_r2 = dsp_get_cpu_cycle_count();
|
||||
dsps_fft2r_fc32(x1, N >> 1);
|
||||
// Bit reverse
|
||||
dsps_bit_rev2r_fc32(x1, N >> 1);
|
||||
// Convert one complex vector with length N/2 to one real spectrum vector with length N/2
|
||||
dsps_cplx2real_fc32(x1, N >> 1);
|
||||
unsigned int end_r2 = dsp_get_cpu_cycle_count();
|
||||
|
||||
// FFT Radix-4
|
||||
unsigned int start_r4 = dsp_get_cpu_cycle_count();
|
||||
dsps_fft4r_fc32(x2, N >> 1);
|
||||
// Bit reverse
|
||||
dsps_bit_rev4r_fc32(x2, N >> 1);
|
||||
// Convert one complex vector with length N/2 to one real spectrum vector with length N/2
|
||||
dsps_cplx2real_fc32(x2, N >> 1);
|
||||
unsigned int end_r4 = dsp_get_cpu_cycle_count();
|
||||
|
||||
for (int i = 0 ; i < N / 2 ; i++) {
|
||||
x1[i] = 10 * log10f((x1[i * 2 + 0] * x1[i * 2 + 0] + x1[i * 2 + 1] * x1[i * 2 + 1] + 0.0000001) / N);
|
||||
x2[i] = 10 * log10f((x2[i * 2 + 0] * x2[i * 2 + 0] + x2[i * 2 + 1] * x2[i * 2 + 1] + 0.0000001) / N);
|
||||
// Simple way to show two power spectrums as one plot
|
||||
diff_y[i] = fabs(x1[i] - x2[i]);
|
||||
}
|
||||
|
||||
// Show power spectrum in 64x10 window from -100 to 0 dB from 0..N/4 samples
|
||||
ESP_LOGW(TAG, "Signal x1");
|
||||
dsps_view(x1, N / 2, 64, 10, -60, 40, '|');
|
||||
ESP_LOGW(TAG, "Signal x2");
|
||||
dsps_view(x2, N / 2, 64, 10, -60, 40, '|');
|
||||
ESP_LOGW(TAG, "Difference between signals x1 and x2 on one plot");
|
||||
dsps_view(diff_y, N / 2, 64, 10, 0, 40, '-');
|
||||
ESP_LOGI(TAG, "FFT Radix 2 for %i complex points take %i cycles", N / 2, end_r2 - start_r2);
|
||||
ESP_LOGI(TAG, "FFT Radix 4 for %i complex points take %i cycles", N / 2, end_r4 - start_r4);
|
||||
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1,9 @@
|
||||
[mapping:dsp]
|
||||
archive: libdsp.a
|
||||
entries:
|
||||
* (noflash)
|
||||
|
||||
[mapping:esp-dsp]
|
||||
archive: libesp-dsp.a
|
||||
entries:
|
||||
* (noflash)
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(fft_window)
|
||||
@@ -0,0 +1,134 @@
|
||||
# FFT Window Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use Window and FFT functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the library
|
||||
2. Initialize input signals with 1024 samples
|
||||
3. Apply window to input signal.
|
||||
4. Calculate FFT for 1024 complex samples
|
||||
5. Apply bit reverse operation for output complex vector
|
||||
6. Split one complex FFT output spectrum to two real signal spectrums
|
||||
7. Show results on the plots
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (128) main: Start Example.
|
||||
W (128) main: Hann Window
|
||||
I (128) view: Data min[256] = -inf, Data max[1] = 24.086628
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5 | |
|
||||
6 | |
|
||||
7 ||||| |
|
||||
8 ||||||||||||||| |
|
||||
9 ||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (138) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
W (138) main: Blackman Window
|
||||
I (148) view: Data min[355] = -165.295654, Data max[1] = 24.083012
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5| |
|
||||
6 | |
|
||||
7 ||| |
|
||||
8 ||||||||| |
|
||||
9 |||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (158) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
W (158) main: Blackman-Harris Window
|
||||
I (168) view: Data min[128] = -inf, Data max[1] = 23.874702
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5| |
|
||||
6| |
|
||||
7|| |
|
||||
8| |||| |
|
||||
9 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (178) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
W (178) main: Blackman-Nuttall Window
|
||||
I (188) view: Data min[128] = -inf, Data max[1] = 23.890663
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5| |
|
||||
6| |
|
||||
7 || |
|
||||
8 |||| | |
|
||||
9 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (198) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
W (198) main: Nuttall Window
|
||||
I (208) view: Data min[203] = -175.147400, Data max[1] = 23.858671
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5| |
|
||||
6| |
|
||||
7|| |
|
||||
8 ||| |
|
||||
9 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (218) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
W (218) main: Flat-Top Window
|
||||
I (228) view: Data min[256] = -inf, Data max[1] = 22.490753
|
||||
________________________________________________________________
|
||||
0| |
|
||||
1| |
|
||||
2| |
|
||||
3| |
|
||||
4| |
|
||||
5| |
|
||||
6| |
|
||||
7 || |
|
||||
8 ||||| |
|
||||
9 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (238) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
I (238) main: End Example.
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_window_main.c")
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use FFT from esp-dsp library
|
||||
|
||||
#define N_SAMPLES 1024
|
||||
int N = N_SAMPLES;
|
||||
// Input test array
|
||||
__attribute__((aligned(16)))
|
||||
float x1[N_SAMPLES];
|
||||
// Window coefficients
|
||||
__attribute__((aligned(16)))
|
||||
float wind[N_SAMPLES];
|
||||
// working complex array
|
||||
__attribute__((aligned(16)))
|
||||
float y_cf[N_SAMPLES * 2];
|
||||
// Pointers to result arrays
|
||||
__attribute__((aligned(16)))
|
||||
float *y1_cf = &y_cf[0];
|
||||
|
||||
void process_and_show(float *data, int length)
|
||||
{
|
||||
dsps_fft2r_fc32(data, length);
|
||||
// Bit reverse
|
||||
dsps_bit_rev_fc32(data, length);
|
||||
// Convert one complex vector to two complex vectors
|
||||
dsps_cplx2reC_fc32(data, length);
|
||||
|
||||
for (int i = 0 ; i < length / 2 ; i++) {
|
||||
data[i] = 10 * log10f((data[i * 2 + 0] * data[i * 2 + 0] + data[i * 2 + 1] * data[i * 2 + 1]) / N);
|
||||
}
|
||||
|
||||
// Show power spectrum in 64x10 window from -100 to 0 dB from 0..N/4 samples
|
||||
dsps_view(data, length / 2, 64, 10, -120, 40, '|');
|
||||
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGW(TAG, "Hann Window");
|
||||
// Generate Hann window
|
||||
dsps_wind_hann_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGW(TAG, "Blackman Window");
|
||||
// Generate Blackman window
|
||||
dsps_wind_blackman_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGW(TAG, "Blackman-Harris Window");
|
||||
// Generate Blackman-Harris window
|
||||
dsps_wind_blackman_harris_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGW(TAG, "Blackman-Nuttall Window");
|
||||
// Generate Blackman-Nuttall window
|
||||
dsps_wind_blackman_nuttall_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGW(TAG, "Nuttall Window");
|
||||
// Generate Nuttall window
|
||||
dsps_wind_nuttall_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGW(TAG, "Flat-Top Window");
|
||||
// Generate Flat-Top window
|
||||
dsps_wind_flat_top_f32(wind, N);
|
||||
// Convert two input vectors to one complex vector
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = wind[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
process_and_show(y_cf, N);
|
||||
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(fir)
|
||||
@@ -0,0 +1,87 @@
|
||||
# FIR Filter Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use FIR filter functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the FFT library
|
||||
2. Initialize input signal
|
||||
* 1st Sine wave (f = 0.2Fs)
|
||||
* 2nd Sine wave (f = 0.4Fs)
|
||||
* Combine the waves
|
||||
3. Show input signal
|
||||
* Calculate windows coefficients
|
||||
* Apply the windowing to the input signal
|
||||
* Do the FFT
|
||||
* Show the frequency response on a plot
|
||||
* Calculate execution performance
|
||||
4. Show filtered signal
|
||||
* Initialize the FIR filter library
|
||||
* Calculate Windowed-Sinc coefficients of FIR filter
|
||||
* Apply the FIR filter to the input signal
|
||||
* Do the FFT
|
||||
* Show the frequency response on a plot
|
||||
* Calculate execution performance
|
||||
|
||||
## How to use the example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is a typical example of console output.
|
||||
|
||||
```
|
||||
I (340) main: Start Example.
|
||||
I (400) view: Data min[388] = -108.419342, Data max[205] = 30.267143
|
||||
________________________________________________________________
|
||||
0 | | |
|
||||
1 | || |
|
||||
2 || || |
|
||||
3 || || |
|
||||
4 || || |
|
||||
5 || ||| |
|
||||
6 || || | | |
|
||||
7|||||||||||||||||||||||| |||||||||||||||||||||| ||||||||||||
|
||||
8 |
|
||||
9 |
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (470) view: Plot: Length=512, min=-120.000000, max=40.000000
|
||||
|
||||
|
||||
I (490) view: Data min[254] = -114.853371, Data max[205] = 27.247583
|
||||
________________________________________________________________
|
||||
0 | |
|
||||
1 | |
|
||||
2 | |
|
||||
3 | | |
|
||||
4 | | |
|
||||
5 | | |
|
||||
6 | ||| ||| |
|
||||
7||||||||||||||||||||||||||||||||||||||||||||||| | ||||| |
|
||||
8 |||||
|
||||
9 |
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (560) view: Plot: Length=256, min=-120.000000, max=40.000000
|
||||
I (560) main: FIR for 1024 samples and decimation 2 takes 763647 cycles
|
||||
I (570) main: End Example.
|
||||
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_fir_main.c")
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use FIR filters from esp-dsp library
|
||||
|
||||
#define FIR_COEFFS_LEN 64 // Number of FIR filter coefficients
|
||||
#define DECIMATION 2 // Decimation ratio of the FIR filter
|
||||
#define N_SAMPLES 1024 // Input samples
|
||||
#define FIR_DELAY (FIR_COEFFS_LEN / DECIMATION) // Amount of samples not being considered for the FFT
|
||||
#define FIR_BUFF_OUT_LEN (N_SAMPLES + FIR_DELAY) // Total length of samples
|
||||
|
||||
|
||||
// Function shows the result of the FIR filter
|
||||
void show_FFT(float *input_signal, const unsigned int fft_len)
|
||||
{
|
||||
|
||||
dsps_fft2r_fc32(input_signal, fft_len >> 1);
|
||||
dsps_bit_rev2r_fc32(input_signal, fft_len >> 1);
|
||||
dsps_cplx2real_fc32(input_signal, fft_len >> 1);
|
||||
|
||||
// Correction factor for the FFT spectrum
|
||||
const float correction_factor = fft_len * 3;
|
||||
|
||||
// Calculating power of spectrum in dB
|
||||
for (int i = 0 ; i < fft_len / 2 ; i++) {
|
||||
input_signal[i] = 10 * log10f((input_signal[i * 2 + 0] * input_signal[i * 2 + 0] + input_signal[i * 2 + 1] * input_signal[i * 2 + 1] + 0.0000001) / correction_factor);
|
||||
}
|
||||
|
||||
// Display power spectrum
|
||||
dsps_view(input_signal, fft_len / 2, 64, 10, -120, 40, '|');
|
||||
}
|
||||
|
||||
|
||||
// Generate Windowed-Sinc filter coefficients
|
||||
void generate_FIR_coefficients(float *fir_coeffs, const unsigned int fir_len, const float ft)
|
||||
{
|
||||
|
||||
// Even or odd length of the FIR filter
|
||||
const bool is_odd = (fir_len % 2) ? (true) : (false);
|
||||
const float fir_order = (float)(fir_len - 1);
|
||||
|
||||
// Window coefficients
|
||||
float *fir_window = (float *)malloc(fir_len * sizeof(float));
|
||||
dsps_wind_blackman_f32(fir_window, fir_len);
|
||||
|
||||
for (int i = 0; i < fir_len; i++) {
|
||||
if ((i == fir_order / 2) && (is_odd)) {
|
||||
fir_coeffs[i] = 2 * ft;
|
||||
} else {
|
||||
fir_coeffs[i] = sinf((2 * M_PI * ft * (i - fir_order / 2))) / (M_PI * (i - fir_order / 2));
|
||||
}
|
||||
|
||||
fir_coeffs[i] *= fir_window[i];
|
||||
}
|
||||
|
||||
free(fir_window);
|
||||
}
|
||||
|
||||
static __attribute__((aligned(16))) float tone_combined[FIR_BUFF_OUT_LEN];
|
||||
static __attribute__((aligned(16))) float fir_coeffs[FIR_COEFFS_LEN];
|
||||
static __attribute__((aligned(16))) float delay_line[FIR_COEFFS_LEN];
|
||||
|
||||
void app_main()
|
||||
{
|
||||
const int32_t fir_len = FIR_COEFFS_LEN;
|
||||
const float fir_ft = 0.5 / DECIMATION; // Transition frequency of the FIR filter
|
||||
const int32_t N = N_SAMPLES; // Number of input samples
|
||||
const int32_t fir_decim = DECIMATION; // FIR filter decimation
|
||||
const int32_t N_buff = FIR_BUFF_OUT_LEN; // Total length of samples with ignored
|
||||
|
||||
fir_f32_t fir1;
|
||||
esp_err_t ret;
|
||||
|
||||
// Ignoring the first set of samples, due to the delay line of the FIR filter
|
||||
const int fir_out_offset = ((FIR_DELAY / 2) - 1);
|
||||
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
|
||||
// If a user doesn't care about buffer allocation, the default
|
||||
// initialization could be used as shown here:
|
||||
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = dsps_fft4r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate input signal as 2 sine waves
|
||||
float *tone_1 = (float *)malloc(N_buff * sizeof(float));
|
||||
float *tone_2 = (float *)malloc(N_buff * sizeof(float));
|
||||
|
||||
dsps_tone_gen_f32(tone_1, N_buff, 5, 0.2, 0);
|
||||
dsps_tone_gen_f32(tone_2, N_buff, 5, 0.4, 0);
|
||||
|
||||
// Generate windowing coefficients
|
||||
float *window = (float *)malloc(N * sizeof(float));
|
||||
dsps_wind_blackman_harris_f32(window, N);
|
||||
|
||||
// Add the two waves together
|
||||
for (int i = 0 ; i < N_buff ; i++) {
|
||||
tone_combined[i] = tone_1[i] + tone_2[i];
|
||||
}
|
||||
|
||||
free(tone_1);
|
||||
free(tone_2);
|
||||
|
||||
// Apply the windowing
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
window[i] *= tone_combined[i];
|
||||
}
|
||||
|
||||
// Show FFT spectrum
|
||||
show_FFT(window, N);
|
||||
|
||||
// Calculate coefficients for the FIR filter
|
||||
generate_FIR_coefficients(fir_coeffs, fir_len, fir_ft);
|
||||
ESP_LOGI(TAG, "\n");
|
||||
|
||||
// Filter the input signal with FIR filter
|
||||
float *fir_out = (float *)malloc( N_buff * sizeof(float));
|
||||
dsps_fird_init_f32(&fir1, fir_coeffs, delay_line, fir_len, fir_decim);
|
||||
|
||||
uint32_t start_b = dsp_get_cpu_cycle_count();
|
||||
dsps_fird_f32(&fir1, tone_combined, fir_out, N_buff / fir_decim);
|
||||
uint32_t end_b = dsp_get_cpu_cycle_count();
|
||||
|
||||
// Generate windowing coefficients and apply the windowing
|
||||
dsps_wind_blackman_harris_f32(window, (N / fir_decim));
|
||||
for (int i = 0 ; i < N / fir_decim ; i++) {
|
||||
window[i] *= fir_out[fir_out_offset + i];
|
||||
}
|
||||
|
||||
// Show FFT spectrum, ignoring first samples from the delay line
|
||||
show_FFT(window, N / fir_decim);
|
||||
ESP_LOGI(TAG, "FIR for %"PRId32" samples and decimation %"PRId32" takes %"PRId32" cycles", N, fir_decim, (int32_t)(end_b - start_b));
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
|
||||
free(fir_out);
|
||||
free(window);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(iir)
|
||||
@@ -0,0 +1,107 @@
|
||||
# IIR Filter Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use IIR filters functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize the library
|
||||
2. Initialize input signal
|
||||
3. Show LPF filter with Q factor 1
|
||||
* Calculate iir filter coefficients
|
||||
* Filter the input test signal (delta function)
|
||||
* Shows impulse response on the plot
|
||||
* Shows frequency response on the plot
|
||||
* Calculate execution performance
|
||||
4. The same for LPF filter with Q factor 10
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (58) main: Start Example.
|
||||
I (58) main: Impulse response of IIR filter with F=0.100000, qFactor=1.000000
|
||||
I (68) view: Data min[8] = -0.060052, Data max[2] = 0.333517
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 |
|
||||
2 - |
|
||||
3- - |
|
||||
4 -------------------------------------------------------------|
|
||||
5 |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (138) view: Plot: Length=128, min=-1.000000, max=1.000000
|
||||
I (148) view: Data min[511] = -149.983795, Data max[0] = 0.000000
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 |
|
||||
2----------------- |
|
||||
3 ---------- |
|
||||
4 ------------- |
|
||||
5 ---------- |
|
||||
6 ------- |
|
||||
7 --- |
|
||||
8 -- |
|
||||
9 --|
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (228) view: Plot: Length=512, min=-100.000000, max=0.000000
|
||||
I (228) main: IIR for 1024 samples take 20276 cycles
|
||||
I (238) main: Impulse response of IIR filter with F=0.100000, qFactor=10.000000
|
||||
I (248) view: Data min[7] = -0.453739, Data max[2] = 0.526114
|
||||
________________________________________________________________
|
||||
0 |
|
||||
1 |
|
||||
2 - - |
|
||||
3- - - - --- --- - - |
|
||||
4- - - - - ---- -------------------------------------|
|
||||
5 -- -- -- -- |
|
||||
6 |
|
||||
7 |
|
||||
8 |
|
||||
9 |
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (318) view: Plot: Length=128, min=-1.000000, max=1.000000
|
||||
I (328) view: Data min[511] = -149.480377, Data max[0] = 0.000000
|
||||
________________________________________________________________
|
||||
0 -- |
|
||||
1 -- - |
|
||||
2---------- ----- |
|
||||
3 -------- |
|
||||
4 ------------ |
|
||||
5 ---------- |
|
||||
6 ------- |
|
||||
7 --- |
|
||||
8 -- |
|
||||
9 --|
|
||||
0123456789012345678901234567890123456789012345678901234567890123
|
||||
I (408) view: Plot: Length=512, min=-100.000000, max=0.000000
|
||||
I (408) main: IIR for 1024 samples take 17456 cycles
|
||||
I (418) main: End Example.
|
||||
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dsps_iir_main.c")
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use iir filters from esp-dsp library
|
||||
|
||||
#define N_SAMPLES 1024
|
||||
int N = N_SAMPLES;
|
||||
// Input test array
|
||||
__attribute__((aligned(16)))
|
||||
float d[N_SAMPLES];
|
||||
// output array
|
||||
__attribute__((aligned(16)))
|
||||
float y[N_SAMPLES];
|
||||
__attribute__((aligned(16)))
|
||||
float y_cf[N_SAMPLES * 2];
|
||||
|
||||
// Function shows result of IIR filter
|
||||
void ShowIIRfilter(float freq, float qFactor)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
float coeffs_lpf[5];
|
||||
float w_lpf[5] = {0, 0};
|
||||
// Calculate iir filter coefficients
|
||||
ret = dsps_biquad_gen_lpf_f32(coeffs_lpf, freq, qFactor);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Operation error = %i", ret);
|
||||
return;
|
||||
}
|
||||
// Process input signal
|
||||
unsigned int start_b = dsp_get_cpu_cycle_count();
|
||||
ret = dsps_biquad_f32(d, y, N, coeffs_lpf, w_lpf);
|
||||
unsigned int end_b = dsp_get_cpu_cycle_count();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Operation error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show result as a plot
|
||||
ESP_LOGI(TAG, "Impulse response of IIR filter with F=%f, qFactor=%f", freq, qFactor);
|
||||
dsps_view(y, 128, 64, 10, -1, 1, '-');
|
||||
|
||||
// Show result as frequency response on the plot
|
||||
for (int i = 0 ; i < N ; i++) {
|
||||
y_cf[i * 2 + 0] = y[i];
|
||||
y_cf[i * 2 + 1] = 0;
|
||||
}
|
||||
|
||||
// We making FFT transform
|
||||
dsps_fft2r_fc32_ansi(y_cf, N);
|
||||
// Bit reverse
|
||||
dsps_bit_rev_fc32_ansi(y_cf, N);
|
||||
// Calculating power of spectrum in dB
|
||||
for (int i = 0 ; i < N / 2 ; i++) {
|
||||
y_cf[i] = 10 * log10f((y_cf[i * 2 + 0] * y_cf[i * 2 + 0] + y_cf[i * 2 + 1] * y_cf[i * 2 + 1]) / N);
|
||||
}
|
||||
// Show power spectrum in 64x10 window from -100 to 0 dB from 0..N/2 samples
|
||||
dsps_view(y_cf, N / 2, 64, 10, -100, 0, '-');
|
||||
ESP_LOGI(TAG, "IIR for %i samples take %i cycles", N, end_b - start_b);
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
// If user don't care about buffer allocation, the default
|
||||
// initialization could be used as shown here:
|
||||
ret = dsps_fft2r_init_fc32(NULL, CONFIG_DSP_MAX_FFT_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Not possible to initialize FFT. Error = %i", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize input signal
|
||||
// Generate d function as input signal
|
||||
dsps_d_gen_f32(d, N, 0);
|
||||
|
||||
// Show filter with Q factor 1
|
||||
ShowIIRfilter(0.1, 1);
|
||||
// Show filter with Q factor 10
|
||||
ShowIIRfilter(0.1, 10);
|
||||
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ekf13states)
|
||||
@@ -0,0 +1,149 @@
|
||||
# Extended Kalman Filter
|
||||
|
||||
This example emulate system with IMU sensors and show how to use Extended Kalman Filter (EKF), with 13 values states vector,
|
||||
to estimate gyroscope errors and calculate system attitude.
|
||||
Also, this example show how to use esp-dsp library to operate with matrices and vectors.
|
||||
|
||||
In real system, the emulated sensors values should be replace by the real sensors values.
|
||||
Then, in real system, a calibration phase should be implemented and after the calibration
|
||||
phase the state vector X and covariance matrix P should be saved and restored next time, when
|
||||
filter called. It will save time for initial phase.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
I (380) spi_flash: detected chip: gd
|
||||
I (383) spi_flash: flash io: dio
|
||||
W (387) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
I (404) cpu_start: Starting scheduler on PRO CPU.
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
I (413) main: Start Example.
|
||||
Gyro error: 0.1 0.2 0.3
|
||||
|
||||
Calibration phase started:
|
||||
Loop 1000 from 48000, State data : 0.998361 0.0152476 0.0211183 0.0509682 0.00463435 0.00919946 0.01352 0.998156 0.00619182 -0.000683098 -0.00117112 0.0063196 -0.000952147
|
||||
Loop 2000 from 48000, State data : 0.941757 0.0877462 0.170681 0.276156 0.016951 0.0334337 0.0498731 0.998804 0.0162317 -0.00225174 0.00389746 0.0110905 -0.000489083
|
||||
Loop 3000 from 48000, State data : 0.372216 0.24247 0.488788 0.750832 0.0323164 0.0642265 0.0962768 0.997295 0.0269348 -0.00481966 0.00605674 0.00779719 0.00494921
|
||||
Loop 4000 from 48000, State data : 0.944725 0.0951798 0.165878 0.266308 0.0470155 0.0946294 0.141251 0.998213 0.0337875 -0.00704064 0.00422252 0.0124181 0.00485692
|
||||
Loop 5000 from 48000, State data : 0.944287 0.102183 0.168344 0.263706 0.0597481 0.12037 0.179946 0.997498 0.0378795 -0.00841348 0.0053515 0.0104612 0.00666854
|
||||
Loop 6000 from 48000, State data : 0.379137 0.258284 0.476853 0.74977 0.0697741 0.140876 0.210702 0.995523 0.0410914 -0.00911293 0.00510267 0.00764586 0.00913832
|
||||
Loop 7000 from 48000, State data : 0.947048 0.112494 0.165382 0.251187 0.0773002 0.156661 0.233985 0.996358 0.0425222 -0.00994576 0.00353348 0.00969652 0.00849919
|
||||
Loop 8000 from 48000, State data : 0.945556 0.120624 0.169212 0.250481 0.082995 0.16838 0.251493 0.995914 0.0433827 -0.0102827 0.0039165 0.00846988 0.00913964
|
||||
Loop 9000 from 48000, State data : 0.381034 0.276875 0.4647 0.749805 0.0871785 0.177046 0.264439 0.995073 0.0441243 -0.0103565 0.00391002 0.0071649 0.00997719
|
||||
Loop 10000 from 48000, State data : 0.946592 0.132375 0.168307 0.241068 0.0902326 0.183443 0.273873 0.995445 0.0443655 -0.0106197 0.00326065 0.00799655 0.00960479
|
||||
Loop 11000 from 48000, State data : 0.944297 0.140946 0.172816 0.242015 0.0924658 0.188118 0.280807 0.995187 0.0445766 -0.0106806 0.00346742 0.00749049 0.00979064
|
||||
Loop 12000 from 48000, State data : 0.378334 0.295555 0.452859 0.751285 0.0941005 0.191525 0.285886 0.994796 0.0447763 -0.0106511 0.0034986 0.00695604 0.0100697
|
||||
Loop 13000 from 48000, State data : 0.944329 0.1532 0.172826 0.234315 0.0953075 0.194011 0.289567 0.994899 0.0448155 -0.0107384 0.00323858 0.00728781 0.00989103
|
||||
Loop 14000 from 48000, State data : 0.941572 0.16194 0.177533 0.236008 0.0961574 0.195842 0.292257 0.994735 0.0448801 -0.0107422 0.00334282 0.0070798 0.00993131
|
||||
Loop 15000 from 48000, State data : 0.373427 0.314041 0.441061 0.753256 0.0967899 0.197167 0.294234 0.994523 0.0449438 -0.0107112 0.00335898 0.00685221 0.0100213
|
||||
Loop 16000 from 48000, State data : 0.941028 0.174338 0.177916 0.228952 0.0972752 0.198121 0.295664 0.994518 0.0449512 -0.0107403 0.0032445 0.00697761 0.00993463
|
||||
Loop 17000 from 48000, State data : 0.937959 0.183145 0.18262 0.230959 0.0975883 0.198844 0.296697 0.994396 0.0449757 -0.0107339 0.0032963 0.00688409 0.00992845
|
||||
Loop 18000 from 48000, State data : 0.3675 0.33233 0.429142 0.755207 0.0978324 0.199358 0.297465 0.994256 0.0450002 -0.0107104 0.00330113 0.00677742 0.00995297
|
||||
Loop 19000 from 48000, State data : 0.937014 0.195546 0.183166 0.224089 0.0980371 0.199716 0.298023 0.994211 0.0450036 -0.0107164 0.00324275 0.00681997 0.00990755
|
||||
Loop 20000 from 48000, State data : 0.933698 0.204372 0.187784 0.226223 0.0981422 0.200008 0.29842 0.994114 0.0450155 -0.0107065 0.00327025 0.00677405 0.00988484
|
||||
Loop 21000 from 48000, State data : 0.361055 0.350426 0.417036 0.756916 0.0982358 0.200208 0.29872 0.99401 0.0450272 -0.0106858 0.00326787 0.00671759 0.0098834
|
||||
Loop 22000 from 48000, State data : 0.932425 0.216717 0.188413 0.219358 0.0983318 0.200334 0.298938 0.993947 0.0450303 -0.0106798 0.00323017 0.00672916 0.00985372
|
||||
Loop 23000 from 48000, State data : 0.928888 0.225543 0.19291 0.221546 0.0983561 0.200458 0.299082 0.993866 0.0450371 -0.0106664 0.00324701 0.00670354 0.00982584
|
||||
Loop 24000 from 48000, State data : 0.354297 0.36833 0.404722 0.758292 0.0983915 0.200535 0.299203 0.993773 0.045044 -0.0106443 0.00324109 0.00666712 0.00981608
|
||||
Loop 25000 from 48000, State data : 0.927316 0.237803 0.19359 0.214612 0.0984453 0.200572 0.299291 0.993709 0.0450468 -0.0106303 0.00321085 0.00666748 0.00979369
|
||||
Loop 26000 from 48000, State data : 0.92357 0.246618 0.197954 0.216824 0.0984385 0.200632 0.299342 0.993629 0.0450514 -0.0106123 0.00322403 0.00665109 0.00976504
|
||||
Loop 27000 from 48000, State data : 0.347305 0.386034 0.392194 0.759303 0.0984521 0.200663 0.299393 0.993546 0.0450564 -0.0105864 0.00321847 0.00662376 0.00975319
|
||||
Loop 28000 from 48000, State data : 0.92171 0.258777 0.198672 0.209796 0.0984898 0.200666 0.299433 0.993475 0.045059 -0.0105663 0.00319366 0.00662077 0.00973562
|
||||
Loop 29000 from 48000, State data : 0.917761 0.267574 0.202895 0.212019 0.0984714 0.2007 0.299446 0.9934 0.0450631 -0.0105437 0.00320563 0.0066091 0.00970881
|
||||
Loop 30000 from 48000, State data : 0.340113 0.403531 0.379459 0.759933 0.0984762 0.200711 0.299466 0.993322 0.0450673 -0.0105132 0.00320031 0.00658594 0.00969804
|
||||
Loop 31000 from 48000, State data : 0.915619 0.279623 0.203648 0.204891 0.0985076 0.2007 0.299484 0.993253 0.0450696 -0.0104878 0.00317637 0.00658294 0.00968329
|
||||
Loop 32000 from 48000, State data : 0.91147 0.288396 0.207727 0.207121 0.0984838 0.200725 0.299481 0.99318 0.0450732 -0.0104599 0.00318786 0.00657435 0.00965871
|
||||
Loop 33000 from 48000, State data : 0.332734 0.420812 0.366519 0.760177 0.0984844 0.20073 0.299492 0.993105 0.045077 -0.0104242 0.00318322 0.00655352 0.00964965
|
||||
Loop 34000 from 48000, State data : 0.909049 0.300327 0.208511 0.199891 0.0985129 0.200714 0.299506 0.993034 0.0450794 -0.0103941 0.0031609 0.00655179 0.00963774
|
||||
Loop 35000 from 48000, State data : 0.904704 0.309072 0.212442 0.202124 0.0984875 0.200736 0.299498 0.992959 0.0450829 -0.0103612 0.0031732 0.00654506 0.00961709
|
||||
Loop 36000 from 48000, State data : 0.325179 0.437867 0.353384 0.760034 0.098487 0.200738 0.299504 0.992885 0.0450865 -0.0103208 0.00317079 0.00652607 0.00961171
|
||||
Loop 37000 from 48000, State data : 0.325177 0.437848 0.353377 0.760049 0.0989011 0.200534 0.299617 0.992838 0.0450912 -0.0103039 0.00319877 0.00652725 0.00959415
|
||||
Loop 38000 from 48000, State data : 0.325194 0.437821 0.353363 0.760064 0.099202 0.200388 0.299726 0.992838 0.0450926 -0.0102998 0.00320422 0.00652895 0.00959084
|
||||
Loop 39000 from 48000, State data : 0.325211 0.437798 0.353354 0.760074 0.0994169 0.200278 0.299826 0.992816 0.045093 -0.0102979 0.00320263 0.0065278 0.00959847
|
||||
Loop 40000 from 48000, State data : 0.325222 0.437784 0.353346 0.760081 0.0995754 0.200199 0.299886 0.992816 0.0450925 -0.0102967 0.00320118 0.00652683 0.00960376
|
||||
Loop 41000 from 48000, State data : 0.325231 0.437773 0.353342 0.760085 0.0996929 0.200142 0.299945 0.992816 0.0450925 -0.0102966 0.00320043 0.00652627 0.00960631
|
||||
Loop 42000 from 48000, State data : 0.325238 0.437769 0.353336 0.760087 0.0997802 0.200119 0.299978 0.992816 0.0450913 -0.0102965 0.00320007 0.0065261 0.00960773
|
||||
Loop 43000 from 48000, State data : 0.32524 0.437762 0.353331 0.760093 0.099842 0.200089 0.299979 0.992816 0.0450913 -0.0102961 0.00320001 0.00652608 0.00960857
|
||||
Loop 44000 from 48000, State data : 0.325241 0.43776 0.353327 0.760095 0.099883 0.200059 0.299979 0.992816 0.045089 -0.0102953 0.00319975 0.00652622 0.00960868
|
||||
Loop 45000 from 48000, State data : 0.325243 0.437759 0.353325 0.760096 0.0999138 0.200045 0.299979 0.992816 0.0450878 -0.0102956 0.0031996 0.00652593 0.00960985
|
||||
Loop 46000 from 48000, State data : 0.325245 0.437756 0.353324 0.760097 0.0999355 0.200042 0.299979 0.992816 0.0450878 -0.0102959 0.00319972 0.0065261 0.00960944
|
||||
Loop 47000 from 48000, State data : 0.325246 0.437757 0.353322 0.760098 0.0999504 0.200039 0.299979 0.992816 0.0450878 -0.0102959 0.00319952 0.00652634 0.00960984
|
||||
Calibration phase finished.
|
||||
|
||||
Regular calculation started:
|
||||
Loop 1000 from 48000, State data : 0.9996 6.68374e-06 -7.71055e-05 0.028269 0.0999599 0.199742 0.298758 0.992397 0.0506049 -0.00981295 0.00516875 0.00517689 0.0102406
|
||||
Loop 2000 from 48000, State data : 0.95186 0.0747648 0.154942 0.253704 0.0997667 0.199899 0.298983 0.992397 0.0504132 -0.0098162 0.00510809 0.00522702 0.0102249
|
||||
Loop 3000 from 48000, State data : 0.395338 0.237819 0.486861 0.741698 0.0994409 0.200091 0.299095 0.992397 0.0502891 -0.00981838 0.00506923 0.00525921 0.0102147
|
||||
Loop 4000 from 48000, State data : 0.952465 0.0877289 0.155254 0.247002 0.0992076 0.200299 0.299271 0.992397 0.0502054 -0.00981973 0.00504271 0.00528111 0.0102076
|
||||
Loop 5000 from 48000, State data : 0.950016 0.096521 0.160702 0.249654 0.0990023 0.200426 0.299306 0.992397 0.05013 -0.00982108 0.00501929 0.00530046 0.0102013
|
||||
Loop 6000 from 48000, State data : 0.389808 0.256786 0.476033 0.745321 0.0988748 0.200476 0.299331 0.992397 0.050078 -0.00982208 0.0050032 0.00531378 0.0101971
|
||||
Loop 7000 from 48000, State data : 0.950306 0.109383 0.161046 0.242937 0.0987883 0.200581 0.299444 0.992397 0.0500379 -0.00982289 0.0049906 0.00532416 0.0101938
|
||||
Loop 8000 from 48000, State data : 0.947646 0.118155 0.166392 0.2456 0.0986931 0.200633 0.299434 0.992397 0.0499987 -0.00982366 0.00497852 0.00533416 0.0101903
|
||||
Loop 9000 from 48000, State data : 0.383995 0.275557 0.464951 0.748623 0.0986473 0.200627 0.299425 0.992397 0.0499702 -0.00982415 0.00496994 0.00534126 0.0101879
|
||||
Loop 10000 from 48000, State data : 0.94764 0.130939 0.166769 0.238794 0.0986203 0.200694 0.299509 0.992397 0.0499475 -0.00982454 0.004963 0.00534698 0.0101861
|
||||
Loop 11000 from 48000, State data : 0.944771 0.139703 0.171999 0.241471 0.0985699 0.200714 0.299481 0.992397 0.0499252 -0.00982467 0.00495605 0.00535274 0.0101844
|
||||
Loop 12000 from 48000, State data : 0.377949 0.294161 0.453622 0.751566 0.0985571 0.200685 0.299459 0.992397 0.0499092 -0.00982467 0.00495124 0.0053567 0.0101832
|
||||
Loop 13000 from 48000, State data : 0.944475 0.152413 0.172408 0.234549 0.0985539 0.200736 0.299532 0.992397 0.0498962 -0.00982467 0.00494735 0.0053599 0.0101823
|
||||
Loop 14000 from 48000, State data : 0.941398 0.16117 0.177516 0.237239 0.0985215 0.200743 0.299498 0.992397 0.0498826 -0.00982467 0.0049434 0.00536316 0.0101813
|
||||
Loop 15000 from 48000, State data : 0.371694 0.312599 0.442052 0.754132 0.0985222 0.200704 0.299474 0.992397 0.049874 -0.00982467 0.00494084 0.0053653 0.0101808
|
||||
Loop 16000 from 48000, State data : 0.940819 0.173801 0.177954 0.230187 0.0985277 0.20075 0.299544 0.992397 0.0498671 -0.00982467 0.00493887 0.00536698 0.0101804
|
||||
Loop 17000 from 48000, State data : 0.937532 0.182552 0.182939 0.232897 0.0985023 0.200752 0.299507 0.992397 0.0498602 -0.00982467 0.0049367 0.0053688 0.0101799
|
||||
Loop 18000 from 48000, State data : 0.365235 0.33087 0.43025 0.756316 0.0985084 0.200708 0.299482 0.992397 0.0498562 -0.00982467 0.00493555 0.0053698 0.0101796
|
||||
Loop 19000 from 48000, State data : 0.936669 0.195102 0.183407 0.225717 0.0985175 0.200754 0.299549 0.992397 0.0498532 -0.00982467 0.00493474 0.00537051 0.0101794
|
||||
Loop 20000 from 48000, State data : 0.933178 0.203841 0.188264 0.22844 0.0984953 0.200754 0.299511 0.992397 0.0498502 -0.00982467 0.00493366 0.00537141 0.010179
|
||||
Loop 21000 from 48000, State data : 0.35858 0.348967 0.41822 0.758113 0.0985034 0.200709 0.299484 0.992397 0.0498495 -0.00982467 0.00493334 0.00537172 0.0101788
|
||||
Loop 22000 from 48000, State data : 0.93203 0.216304 0.188763 0.221136 0.0985129 0.200755 0.299549 0.992397 0.0498497 -0.00982467 0.00493327 0.00537182 0.0101787
|
||||
Loop 23000 from 48000, State data : 0.928336 0.225027 0.193488 0.22387 0.0984918 0.200754 0.29951 0.992397 0.0498497 -0.00982467 0.00493298 0.00537209 0.0101787
|
||||
Loop 24000 from 48000, State data : 0.351735 0.366882 0.405969 0.759519 0.0985006 0.200707 0.299482 0.992397 0.0498508 -0.00982467 0.00493324 0.00537189 0.0101787
|
||||
Loop 25000 from 48000, State data : 0.926905 0.237397 0.194017 0.216443 0.0985107 0.200755 0.299545 0.992397 0.0498526 -0.00982467 0.00493366 0.00537159 0.0101787
|
||||
Loop 26000 from 48000, State data : 0.92301 0.246099 0.198608 0.219185 0.0984902 0.200753 0.299511 0.992397 0.0498537 -0.00982467 0.00493391 0.00537146 0.0101787
|
||||
Loop 27000 from 48000, State data : 0.344708 0.384605 0.393502 0.760534 0.0984992 0.200706 0.299488 0.992397 0.0498556 -0.00982467 0.00493459 0.00537092 0.0101787
|
||||
Loop 28000 from 48000, State data : 0.921297 0.258369 0.199166 0.211636 0.0985091 0.200757 0.299555 0.992397 0.0498579 -0.00982467 0.00493535 0.00537033 0.0101787
|
||||
Loop 29000 from 48000, State data : 0.917204 0.267048 0.203621 0.214385 0.0984891 0.200754 0.29952 0.992397 0.0498601 -0.00982467 0.00493597 0.0053698 0.0101787
|
||||
Loop 30000 from 48000, State data : 0.337501 0.402129 0.380825 0.761156 0.0984981 0.200706 0.299491 0.992397 0.0498626 -0.00982467 0.00493691 0.00536903 0.0101787
|
||||
Loop 31000 from 48000, State data : 0.915208 0.279212 0.204208 0.206723 0.0985072 0.200758 0.299553 0.992397 0.0498654 -0.00982467 0.00493789 0.00536824 0.0101787
|
||||
Loop 32000 from 48000, State data : 0.910918 0.287861 0.208526 0.209479 0.0984873 0.200754 0.299515 0.992397 0.0498676 -0.00982467 0.00493879 0.00536752 0.0101787
|
||||
Loop 33000 from 48000, State data : 0.330116 0.419445 0.367945 0.761385 0.0984966 0.200704 0.299489 0.992397 0.0498701 -0.00982467 0.00493986 0.00536667 0.0101787
|
||||
Loop 34000 from 48000, State data : 0.908641 0.299912 0.209141 0.201703 0.0985056 0.200757 0.299551 0.992397 0.0498728 -0.00982467 0.00494093 0.00536582 0.0101787
|
||||
Loop 35000 from 48000, State data : 0.904158 0.308528 0.213318 0.204462 0.0984862 0.200752 0.299518 0.992397 0.0498751 -0.00982467 0.00494188 0.00536507 0.0101787
|
||||
Loop 36000 from 48000, State data : 0.322561 0.436541 0.354869 0.761219 0.0984953 0.200702 0.299495 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 37000 from 48000, State data : 0.322549 0.436508 0.354868 0.761243 0.0989076 0.200506 0.299634 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 38000 from 48000, State data : 0.322568 0.436485 0.354851 0.761257 0.099208 0.200371 0.299726 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 39000 from 48000, State data : 0.322581 0.436466 0.354841 0.761267 0.0994207 0.200267 0.299799 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 40000 from 48000, State data : 0.322592 0.436454 0.354831 0.761274 0.099581 0.200208 0.299849 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 41000 from 48000, State data : 0.322601 0.436443 0.354826 0.761278 0.099701 0.20015 0.299901 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 42000 from 48000, State data : 0.322606 0.436435 0.35482 0.761283 0.0997844 0.200101 0.299931 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 43000 from 48000, State data : 0.322611 0.436429 0.35482 0.761285 0.0998457 0.200072 0.299961 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 44000 from 48000, State data : 0.322615 0.436425 0.354818 0.761286 0.0998883 0.200057 0.29999 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 45000 from 48000, State data : 0.322617 0.436423 0.354816 0.761287 0.099912 0.200042 0.300002 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 46000 from 48000, State data : 0.322617 0.436421 0.354815 0.761289 0.0999343 0.20003 0.300002 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Loop 47000 from 48000, State data : 0.322618 0.436421 0.354814 0.761289 0.0999444 0.20003 0.300002 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Final State data : 0.322618 0.436421 0.354814 0.761289 0.0999518 0.20003 0.300002 0.992397 0.0498778 -0.00982467 0.00494296 0.00536423 0.0101787
|
||||
Estimated error : 0.0999518 0.20003 0.300002
|
||||
Difference between real and estimated errors : 4.81904e-05 -2.99811e-05 -2.17557e-06
|
||||
|
||||
Expected Euler angels (degree) : -29.8215 64.9692 150.241
|
||||
Calculated Euler angels (degree) : -35.1525 63.3067 156.167
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "ekf_imu13states_main.cpp")
|
||||
@@ -0,0 +1,196 @@
|
||||
// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dsp_platform.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "esp_dsp.h"
|
||||
#include "ekf_imu13states.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
extern "C" void app_main();
|
||||
|
||||
// This example reproduce system with gyroscope, accelerometer, and magnetometer
|
||||
// True gyroscope values will be transformed and applied to the rotation and reference measurements.
|
||||
void app_main()
|
||||
{
|
||||
ekf_imu13states *ekf13 = new ekf_imu13states();
|
||||
ekf13->Init();
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
|
||||
// Set up some initial values to emulate and calculate system values
|
||||
int total_N = 3000;
|
||||
// Pi value
|
||||
float pi = std::atan(1) * 4;
|
||||
|
||||
// gyroscope bias error
|
||||
float gyro_err_data[] = {0.1, 0.2, 0.3}; // static constant error
|
||||
dspm::Mat gyro_err(gyro_err_data, 3, 1);
|
||||
|
||||
|
||||
// Measurement noise covariance values for diagonal covariance matrix.
|
||||
// For the real system these values could be adjusted!
|
||||
// These values depends on how noisy the measurement.
|
||||
//
|
||||
float R[10];
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
R[i] = 0.01;
|
||||
}
|
||||
|
||||
// Reference vectors
|
||||
float accel0_data[] = {0, 0, 1};
|
||||
// In real system magnetometer vector will have different value and direction
|
||||
// The EKF will calculate them. This value is used as initial state.
|
||||
float magn0_data[] = {1, 0, 0};
|
||||
|
||||
dspm::Mat accel0(accel0_data, 3, 1);
|
||||
dspm::Mat magn0(magn0_data, 3, 1);
|
||||
|
||||
float dt = 0.01;
|
||||
|
||||
dspm::Mat gyro_data(3, 1);
|
||||
int count = 0;
|
||||
|
||||
// Initial rotation matrix
|
||||
dspm::Mat Rm = dspm::Mat::eye(3);
|
||||
dspm::Mat Re = dspm::Mat::eye(3);
|
||||
|
||||
gyro_err *= 1;
|
||||
|
||||
std::cout << "Gyro error: " << gyro_err.t() << std::endl;
|
||||
std::cout << "Calibration phase started: " << std::endl;
|
||||
for (size_t n = 1; n < total_N * 16; n++) {
|
||||
if ((n % 1000) == 0) {
|
||||
std::cout << "Loop " << n << " from " << total_N * 16;
|
||||
std::cout << ", State data : " << ekf13->X.t();
|
||||
}
|
||||
//
|
||||
// This part of the loop related to the system emulation
|
||||
//
|
||||
|
||||
// Generate gyro values for system emulation
|
||||
gyro_data *= 0; // reset gyro value
|
||||
if ((n >= (total_N / 2)) && (n < total_N * 12)) {
|
||||
gyro_data(0, 0) = 1 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
gyro_data(1, 0) = 2 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
gyro_data(2, 0) = 3 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
count++;
|
||||
}
|
||||
dspm::Mat gyro_sample = gyro_data + gyro_err;
|
||||
|
||||
gyro_data *= dt;
|
||||
// Calculate rotation for the last time interval
|
||||
Re = ekf::eul2rotm(gyro_data.data);
|
||||
// Ally rotation to the system rotation matrix
|
||||
Rm = Rm * Re;
|
||||
// Convert rotation matrix to the system attitude quaternion
|
||||
dspm::Mat attitude = ekf::rotm2quat(Rm);
|
||||
// We have to rotate accel and magn to the opposite direction
|
||||
dspm::Mat accel_data = Rm.t() * accel0;
|
||||
dspm::Mat magn_data = Rm.t() * magn0;
|
||||
|
||||
dspm::Mat accel_norm = accel_data / accel_data.norm();
|
||||
dspm::Mat magn_norm = magn_data / magn_data.norm();
|
||||
|
||||
//
|
||||
// This part of the loop related to the real system
|
||||
// Here gyro_sample values must be replaced by measured gyroscope values
|
||||
// and accel_norm and magn_norm should be real measured accel and magn values
|
||||
// The dt in this case should be real time difference in seconds between samples
|
||||
// Fill the input control values with measured gyro values
|
||||
float input_u[] = {gyro_sample(0, 0), gyro_sample(1, 0), gyro_sample(2, 0)};
|
||||
// Process input values to new state
|
||||
ekf13->Process(input_u, dt);
|
||||
dspm::Mat q_norm(ekf13->X.data, 4, 1);
|
||||
q_norm /= q_norm.norm();
|
||||
// Correct state and calculate gyro and magnetometer values.
|
||||
// Here accel_norm and magn_norm should be real measured accel and magn values
|
||||
ekf13->UpdateRefMeasurementMagn(accel_norm.data, magn_norm.data, R);
|
||||
}
|
||||
std::cout << "Calibration phase finished." << std::endl << std::endl;
|
||||
|
||||
std::cout << "Regular calculation started:" << std::endl;
|
||||
|
||||
// Reset rotation nmatrix
|
||||
Rm = dspm::Mat::eye(3);
|
||||
Re = dspm::Mat::eye(3);
|
||||
|
||||
count = 0;
|
||||
// Set initial state
|
||||
ekf13->X(0, 0) = 1;
|
||||
ekf13->X(0, 1) = 0;
|
||||
ekf13->X(0, 2) = 0;
|
||||
ekf13->X(0, 3) = 0;
|
||||
|
||||
for (size_t n = 1; n < total_N * 16; n++) {
|
||||
if ((n % 1000) == 0) {
|
||||
std::cout << "Loop " << n << " from " << total_N * 16;
|
||||
std::cout << ", State data : " << ekf13->X.t();
|
||||
}
|
||||
//
|
||||
// This part of the loop related to the system emulation
|
||||
//
|
||||
|
||||
// Generate gyro values for system emulation
|
||||
gyro_data *= 0; // reset gyro value
|
||||
if ((n >= (total_N / 2)) && (n < total_N * 12)) {
|
||||
gyro_data(0, 0) = 1 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
gyro_data(1, 0) = 2 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
gyro_data(2, 0) = 3 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
|
||||
count++;
|
||||
}
|
||||
dspm::Mat gyro_sample = gyro_data + gyro_err;
|
||||
|
||||
gyro_data *= dt;
|
||||
// Calculate rotation for the last time interval
|
||||
Re = ekf::eul2rotm(gyro_data.data);
|
||||
// Ally rotation to the system rotation matrix
|
||||
Rm = Rm * Re;
|
||||
// Convert rotation matrix to the system attitude quaternion
|
||||
dspm::Mat attitude = ekf::rotm2quat(Rm);
|
||||
// We have to rotate accel and magn to the opposite direction
|
||||
dspm::Mat accel_data = Rm.t() * accel0;
|
||||
dspm::Mat magn_data = Rm.t() * magn0;
|
||||
|
||||
dspm::Mat accel_norm = accel_data / accel_data.norm();
|
||||
dspm::Mat magn_norm = magn_data / magn_data.norm();
|
||||
|
||||
//
|
||||
// This part of the loop related to the real system
|
||||
// Here gyro_sample values must be replaced by measured gyroscope values
|
||||
// and accel_norm and magn_norm should be real measured accel and magn values
|
||||
// The dt in this case should be real time difference in seconds between samples
|
||||
// Fill the input control values with measured gyro values
|
||||
float input_u[] = {gyro_sample(0, 0), gyro_sample(1, 0), gyro_sample(2, 0)};
|
||||
// Process input values to new state
|
||||
ekf13->Process(input_u, dt);
|
||||
dspm::Mat q_norm(ekf13->X.data, 4, 1);
|
||||
q_norm /= q_norm.norm();
|
||||
// Correct state and calculate gyro and magnetometer values.
|
||||
// Here accel_norm and magn_norm should be real measured accel and magn values
|
||||
ekf13->UpdateRefMeasurement(accel_norm.data, magn_norm.data, R);
|
||||
}
|
||||
|
||||
std::cout << "Final State data : " << ekf13->X.t();
|
||||
dspm::Mat estimated_error(&ekf13->X.data[4], 3, 1);
|
||||
std::cout << "Estimated error : " << estimated_error.t();
|
||||
std::cout << "Difference between real and estimated errors : " << (gyro_err - estimated_error).t() << std::endl;
|
||||
|
||||
std::cout << "Expected Euler angels (degree) : " << (180 / pi * ekf::quat2eul(ekf::rotm2quat(Rm).data)).t();
|
||||
std::cout << "Calculated Euler angels (degree) : " << (180 / pi * ekf::quat2eul(ekf13->X.data)).t() << std::endl;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# DSP Library
|
||||
#
|
||||
# CONFIG_DSP_ANSI is not set
|
||||
CONFIG_DSP_OPTIMIZED=y
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_512 is not set
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set
|
||||
CONFIG_DSP_MAX_FFT_SIZE_4096=y
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set
|
||||
# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set
|
||||
CONFIG_DSP_MAX_FFT_SIZE=4096
|
||||
# end of DSP Library
|
||||
|
||||
#
|
||||
# ESP System Settings
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
CONFIG_ESP_INT_WDT=n
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
# end of ESP System Settings
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(matrix)
|
||||
@@ -0,0 +1,54 @@
|
||||
# Matrix Operations Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to use Mat class functionality from esp-dsp library. Example does the following steps:
|
||||
|
||||
1. Initialize a matrix A and matrix x
|
||||
2. Calculate matrix b: b = A*x
|
||||
3. Find roots x1_: A*x1_ = b, with different methods
|
||||
4. Print result
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example does not require any special hardware, and can be run on any common development board.
|
||||
|
||||
### Configure the project
|
||||
|
||||
Under Component Config ---> DSP Library ---> DSP Optimization, it's possible to choose either the optimized or ANSI implementation, to compare them.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output (replace PORT with serial port name):
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example output
|
||||
|
||||
Here is an typical example console output.
|
||||
|
||||
```
|
||||
I (215) main: Start Example.
|
||||
I (215) main: Original vector x:
|
||||
0
|
||||
1
|
||||
2
|
||||
I (215) main: Solve result:
|
||||
0
|
||||
1
|
||||
2
|
||||
I (215) main: Roots result:
|
||||
0
|
||||
1
|
||||
2
|
||||
I (215) main: End Example.
|
||||
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
idf_component_register(SRCS "dspm_matrix_main.cpp")
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dsp_platform.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "esp_dsp.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// This example shows how to use Mat class from esp-dsp library.
|
||||
//
|
||||
// First we create matrix A and x, and then calculating matrix b as result
|
||||
// A*x = b
|
||||
// Then we can find x as roots of matrices X and b
|
||||
//
|
||||
extern "C" void app_main();
|
||||
|
||||
void app_main()
|
||||
{
|
||||
ESP_LOGI(TAG, "Start Example.");
|
||||
int M = 3;
|
||||
int N = 3;
|
||||
dspm::Mat A(M, N);
|
||||
dspm::Mat x(N, 1);
|
||||
for (int m = 0 ; m < M ; m++) {
|
||||
for (int n = 0 ; n < N ; n++) {
|
||||
A(m, n) = N * m + n;
|
||||
}
|
||||
x(m, 0) = m;
|
||||
}
|
||||
A(0, 0) = 10;
|
||||
A(0, 1) = 11;
|
||||
|
||||
dspm::Mat b = A * x;
|
||||
// Gaussian method
|
||||
dspm::Mat x1_ = dspm::Mat::solve(A, b);
|
||||
// Non Gaussian method
|
||||
dspm::Mat x2_ = dspm::Mat::roots(A, b);
|
||||
|
||||
ESP_LOGI(TAG, "Original vector x:");
|
||||
std::cout << x;
|
||||
ESP_LOGI(TAG, "Solve result:");
|
||||
std::cout << x1_;
|
||||
ESP_LOGI(TAG, "Roots result:");
|
||||
std::cout << x2_;
|
||||
ESP_LOGI(TAG, "End Example.");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-dsp:
|
||||
version: '*'
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
||||
Reference in New Issue
Block a user